aee0f09db8
- Datafabrik: Dockerfile fix, agentorkestrering fungerar - Vision: Identify-modell, FAISS, OCR alla testade - API: Alla 7 integrationstester passerade - Upplösare: Entitetsupplösning verifierad
649 lines
28 KiB
Python
649 lines
28 KiB
Python
"""
|
|
LIFE — Reality Intelligence Validation Program (RIVP)
|
|
|
|
Målet: Bevisa att LIFE fungerar i riktiga miljöer.
|
|
|
|
Faser:
|
|
- Fas 1: Infrastruktur (vägar, broar, arbeten)
|
|
- Fas 2: Kommun (parker, belysning, skyltning)
|
|
- Fas 3: Fastigheter (byggnader, skador, underhåll)
|
|
- Fas 4: Bistånd (projekt, observationer, verifiering)
|
|
|
|
Nyckeltal (KPI:er):
|
|
- Datatäckning
|
|
- Aktualitet
|
|
- Evidenskvalitet
|
|
- Analyskvalitet
|
|
- Adoption
|
|
- Interoperabilitet
|
|
"""
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Optional, Dict, Any
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
|
|
from app.database import get_db
|
|
from app.core.security import get_current_user
|
|
from app.models import User
|
|
|
|
router = APIRouter(prefix="/life-validation", tags=["life_validation"])
|
|
|
|
|
|
# ─── REALITY INTELLIGENCE VALIDATION PROGRAM ──────────────────────────────────
|
|
|
|
@router.get("/public/validation-program")
|
|
async def get_validation_program():
|
|
"""
|
|
Reality Intelligence Validation Program (RIVP)
|
|
Bevisa att LIFE fungerar i riktiga miljöer.
|
|
"""
|
|
return {
|
|
"program_name": "Reality Intelligence Validation Program (RIVP)",
|
|
"version": "1.0.0",
|
|
"purpose": "Bevisa att LIFE fungerar i riktiga miljöer innan vidare arkitekturutveckling",
|
|
"philosophy": "Många tekniska projekt fortsätter bygga lager utan att validera dem. RIVP säkerställer att varje fas bevisar verkligt värde.",
|
|
"phases": {
|
|
"phase_1_infrastructure": {
|
|
"phase": 1,
|
|
"name": "Infrastruktur",
|
|
"duration": "6 månader",
|
|
"goal": "Visa att LIFE kan övervaka infrastruktur i realtid",
|
|
"objectives": [
|
|
{
|
|
"objective": "Hitta vägskador",
|
|
"description": "Identifiera skador på vägar genom satellitbilder och fältobservationer",
|
|
"success_criteria": ">80% precision i skadedetektion",
|
|
"measurement": "Jämförelse med manuell inspektion",
|
|
},
|
|
{
|
|
"objective": "Följa vägarbeten",
|
|
"description": "Spåra framsteg i vägarbeten över tid",
|
|
"success_criteria": "Progress estimation ±10% jämfört med rapporter",
|
|
"measurement": "Veckovis jämförelse med entreprenörsrapporter",
|
|
},
|
|
{
|
|
"objective": "Upptäcka förändringar",
|
|
"description": "Automatisk detektion av förändringar i infrastruktur",
|
|
"success_criteria": "<48h från förändring till detektion",
|
|
"measurement": "Tidsstämplad jämförelse",
|
|
},
|
|
{
|
|
"objective": "Verifiera reparationer",
|
|
"description": "Bekräfta att rapporterade reparationer verkligen utförts",
|
|
"success_criteria": ">90% korrekt verifiering",
|
|
"measurement": "Fältbesök + satellitbilder",
|
|
},
|
|
],
|
|
"pilot_locations": [
|
|
{"location": "E4, Uppsala län", "type": "Highway", "length_km": 45},
|
|
{"location": "Länsväg 272, Stockholm", "type": "County road", "length_km": 23},
|
|
],
|
|
"data_sources": ["Sentinel-2", "QUIXZOOM", "Trafikverket API"],
|
|
"expected_outcomes": {
|
|
"objects_tracked": 500,
|
|
"observations_collected": 10000,
|
|
"issues_detected": 150,
|
|
"verification_rate": 90,
|
|
},
|
|
},
|
|
"phase_2_municipality": {
|
|
"phase": 2,
|
|
"name": "Kommun",
|
|
"duration": "6 månader",
|
|
"goal": "Visa att LIFE kan hantera kommunala tillgångar",
|
|
"objectives": [
|
|
{
|
|
"objective": "Följa parker",
|
|
"description": "Övervaka skick och användning av kommunala parker",
|
|
"success_criteria": "Veckovis uppdatering av parkstatus",
|
|
"measurement": "Bildjämförelse + besöksdata",
|
|
},
|
|
{
|
|
"objective": "Gatubelysning",
|
|
"description": "Kartlägga och övervaka gatubelysning",
|
|
"success_criteria": ">95% täckning av belysningspunkter",
|
|
"measurement": "Fältverifiering",
|
|
},
|
|
{
|
|
"objective": "Skyltning",
|
|
"description": "Inventera och övervaka vägskyltar",
|
|
"success_criteria": "Komplett inventering ±5%",
|
|
"measurement": "Jämförelse med kommunalt register",
|
|
},
|
|
{
|
|
"objective": "Avfall",
|
|
"description": "Övervaka avfallshantering och återvinning",
|
|
"success_criteria": "Identifiera 90% av illegala dumpningsplatser",
|
|
"measurement": "Satellit + fältobservationer",
|
|
},
|
|
{
|
|
"objective": "Vinterunderhåll",
|
|
"description": "Spåra snöröjning och halkbekämpning",
|
|
"success_criteria": "<4h från snöfall till uppdaterad status",
|
|
"measurement": "Realtidsjämförelse",
|
|
},
|
|
],
|
|
"pilot_locations": [
|
|
{"location": "Uppsala kommun", "population": 230000},
|
|
{"location": "Enköpings kommun", "population": 48000},
|
|
],
|
|
"data_sources": ["Satellit", "QUIXZOOM", "Kommunala API:er"],
|
|
"expected_outcomes": {
|
|
"objects_tracked": 5000,
|
|
"observations_collected": 50000,
|
|
"issues_detected": 300,
|
|
"response_time_hours": 4,
|
|
},
|
|
},
|
|
"phase_3_properties": {
|
|
"phase": 3,
|
|
"name": "Fastigheter",
|
|
"duration": "6 månader",
|
|
"goal": "Visa att LIFE kan övervaka byggnader och fastigheter",
|
|
"objectives": [
|
|
{
|
|
"objective": "Följa byggnader",
|
|
"description": "Spåra byggnaders skick och förändringar",
|
|
"success_criteria": "Månatlig uppdatering av byggnadsstatus",
|
|
"measurement": "Satellit + drönare + fält",
|
|
},
|
|
{
|
|
"objective": "Upptäcka skador",
|
|
"description": "Identifiera skador på tak, fasader, grunder",
|
|
"success_criteria": ">75% precision i skadedetektion",
|
|
"measurement": "Jämförelse med besiktning",
|
|
},
|
|
{
|
|
"objective": "Följa underhåll",
|
|
"description": "Spåra planerat och utfört underhåll",
|
|
"success_criteria": "100% spårbarhet av underhållsåtgärder",
|
|
"measurement": "Integration med underhållssystem",
|
|
},
|
|
{
|
|
"objective": "Analysera risk",
|
|
"description": "Bedöma risker för byggnader",
|
|
"success_criteria": "Riskbedömning ±1 nivå jämfört med expert",
|
|
"measurement": "Oberoende expertgranskning",
|
|
},
|
|
],
|
|
"pilot_locations": [
|
|
{"location": "Bostadsrättsföreningar, Uppsala", "properties": 50},
|
|
{"location": "Kommunala fastigheter", "properties": 100},
|
|
],
|
|
"data_sources": ["Satellit", "Drönare", "Fältinspektion", "Fastighetsregister"],
|
|
"expected_outcomes": {
|
|
"objects_tracked": 150,
|
|
"observations_collected": 3000,
|
|
"issues_detected": 200,
|
|
"risk_assessments": 150,
|
|
},
|
|
},
|
|
"phase_4_aid": {
|
|
"phase": 4,
|
|
"name": "Bistånd",
|
|
"duration": "12 månader",
|
|
"goal": "Visa att LIFE kan övervaka biståndsprojekt i utvecklingsländer",
|
|
"objectives": [
|
|
{
|
|
"objective": "Följa projekt över tid",
|
|
"description": "Spåra framsteg i biståndsprojekt",
|
|
"success_criteria": "Månatlig uppdatering ±15% jämfört med rapporter",
|
|
"measurement": "Jämförelse med implementerarrapporter",
|
|
},
|
|
{
|
|
"objective": "Samla oberoende observationer",
|
|
"description": "Använda QUIXZOOM för oberoende verifiering",
|
|
"success_criteria": ">50% av projekt med oberoende observationer",
|
|
"measurement": "Antal verifierade projekt",
|
|
},
|
|
{
|
|
"objective": "Kombinera flera datakällor",
|
|
"description": "Fusionera satellit, fält, rapporter och nyheter",
|
|
"success_criteria": ">3 oberoende källor per projekt",
|
|
"measurement": "Källtäckning per projekt",
|
|
},
|
|
{
|
|
"objective": "Identifiera verifieringsbehov",
|
|
"description": "Automatisk flaggning av projekt som behöver extra granskning",
|
|
"success_criteria": ">80% precision i flaggning",
|
|
"measurement": "Jämförelse med manuell granskning",
|
|
},
|
|
],
|
|
"pilot_locations": [
|
|
{"location": "Somalia", "projects": 50, "focus": "Infrastructure"},
|
|
{"location": "Kenya", "projects": 30, "focus": "Education"},
|
|
{"location": "Malawi", "projects": 20, "focus": "Health"},
|
|
],
|
|
"data_sources": ["Sentinel-2", "QUIXZOOM", "Implementerarrapporter", "Nyheter", "Sociala medier"],
|
|
"expected_outcomes": {
|
|
"objects_tracked": 100,
|
|
"observations_collected": 10000,
|
|
"projects_monitored": 100,
|
|
"verification_flags": 25,
|
|
},
|
|
},
|
|
},
|
|
"success_criteria": {
|
|
"program_level": [
|
|
"Alla 4 faser genomförda",
|
|
"Minst 2 piloter per fas",
|
|
"Dokumenterade resultat",
|
|
"Publicerade case studies",
|
|
],
|
|
"technical": [
|
|
">80% precision i detektion",
|
|
"<48h aktualitet",
|
|
">90% datatäckning",
|
|
">3 oberoende källor per objekt",
|
|
],
|
|
"business": [
|
|
"Minst 3 externa partners",
|
|
"Minst 1 kommersiell pilot",
|
|
"Positiv ROI i minst 1 fas",
|
|
"Publicerad referensarkitektur",
|
|
],
|
|
},
|
|
}
|
|
|
|
|
|
# ─── SUCCESS MEASUREMENT FRAMEWORK ────────────────────────────────────────────
|
|
|
|
@router.get("/public/success-metrics")
|
|
async def get_success_metrics():
|
|
"""
|
|
Ramverk för att mäta om LIFE lyckas som ekosystem.
|
|
"""
|
|
return {
|
|
"framework_name": "LIFE Success Measurement Framework",
|
|
"version": "1.0.0",
|
|
"purpose": "Definiera hur vi mäter om plattformen lyckas — fokus på faktisk användning, inte antal moduler",
|
|
"dimensions": {
|
|
"data_coverage": {
|
|
"dimension": "Datatäckning",
|
|
"description": "Andel relevanta objekt eller områden med aktuell observationsdata",
|
|
"metrics": [
|
|
{
|
|
"metric": "Object Coverage",
|
|
"definition": "Andel registrerade objekt med minst 1 observation",
|
|
"target": ">95%",
|
|
"measurement": "Registrerade objekt / Objekt med observation",
|
|
"frequency": "Veckovis",
|
|
},
|
|
{
|
|
"metric": "Geographic Coverage",
|
|
"definition": "Andel av target-området med data",
|
|
"target": ">90%",
|
|
"measurement": "Km² med data / Total target km²",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Domain Coverage",
|
|
"definition": "Andel domäner med aktiv datainsamling",
|
|
"target": "100% av aktiva domäner",
|
|
"measurement": "Domäner med data / Aktiva domäner",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
],
|
|
},
|
|
"freshness": {
|
|
"dimension": "Aktualitet",
|
|
"description": "Tid från förändring i verkligheten till registrerad observation",
|
|
"metrics": [
|
|
{
|
|
"metric": "Detection Time",
|
|
"definition": "Tid från förändring till detektion",
|
|
"target": "<48h",
|
|
"measurement": "Mediantid för kända förändringar",
|
|
"frequency": "Veckovis",
|
|
},
|
|
{
|
|
"metric": "Update Frequency",
|
|
"definition": "Hur ofta objekt uppdateras",
|
|
"target": "Veckovis för aktiva objekt",
|
|
"measurement": "Dagar sedan senaste observation",
|
|
"frequency": "Dagligen",
|
|
},
|
|
{
|
|
"metric": "Alert Latency",
|
|
"definition": "Tid från detektion till användaralert",
|
|
"target": "<1h",
|
|
"measurement": "Mediantid alert-utskick",
|
|
"frequency": "Dagligen",
|
|
},
|
|
],
|
|
},
|
|
"evidence_quality": {
|
|
"dimension": "Evidenskvalitet",
|
|
"description": "Genomsnittlig konfidens och andel observationer med oberoende verifiering",
|
|
"metrics": [
|
|
{
|
|
"metric": "Average Confidence",
|
|
"definition": "Genomsnittlig konfidens över alla observationer",
|
|
"target": ">75",
|
|
"measurement": "Medel av RIS-003 composite scores",
|
|
"frequency": "Veckovis",
|
|
},
|
|
{
|
|
"metric": "Verification Rate",
|
|
"definition": "Andel observationer med oberoende verifiering",
|
|
"target": ">30%",
|
|
"measurement": "Verifierade / Totala observationer",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Source Diversity",
|
|
"definition": "Genomsnittligt antal källor per objekt",
|
|
"target": ">2.5",
|
|
"measurement": "Antal unika källor / Antal objekt",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Contradiction Rate",
|
|
"definition": "Andel objekt med motstridig evidens",
|
|
"target": "<5%",
|
|
"measurement": "Objekt med flaggade motsägelser / Totala objekt",
|
|
"frequency": "Veckovis",
|
|
},
|
|
],
|
|
},
|
|
"analysis_quality": {
|
|
"dimension": "Analyskvalitet",
|
|
"description": "Hur ofta användare bedömer analyser som användbara eller korrekta",
|
|
"metrics": [
|
|
{
|
|
"metric": "User Satisfaction",
|
|
"definition": "Andel användare som bedömer analyser som användbara",
|
|
"target": ">80%",
|
|
"measurement": "Enkäter + feedback",
|
|
"frequency": "Kvartalsvis",
|
|
},
|
|
{
|
|
"metric": "Decision Adoption",
|
|
"definition": "Andel rekommendationer som leder till åtgärd",
|
|
"target": ">60%",
|
|
"measurement": "Genomförda åtgärder / Rekommendationer",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Prediction Accuracy",
|
|
"definition": "Hur ofta prognoser stämmer",
|
|
"target": ">70%",
|
|
"measurement": "Korrekta prognoser / Totala prognoser",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Expert Agreement",
|
|
"definition": "Hur ofta experter håller med om analyser",
|
|
"target": ">75%",
|
|
"measurement": "Oberoende expertgranskning",
|
|
"frequency": "Kvartalsvis",
|
|
},
|
|
],
|
|
},
|
|
"adoption": {
|
|
"dimension": "Adoption",
|
|
"description": "Antal externa implementationer, partnerintegrationer och aktiva SDK-användare",
|
|
"metrics": [
|
|
{
|
|
"metric": "External Implementations",
|
|
"definition": "Antal oberoende RIS-implementationer",
|
|
"target": ">10",
|
|
"measurement": "Registrerade implementationer",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Partner Integrations",
|
|
"definition": "Antal system integrerade med LIFE",
|
|
"target": ">20",
|
|
"measurement": "Aktiva integrationer",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "SDK Users",
|
|
"definition": "Antal aktiva SDK-användare",
|
|
"target": ">100",
|
|
"measurement": "Unika utvecklare med SDK-downloads",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Certified Products",
|
|
"definition": "Antal RIS-certifierade produkter",
|
|
"target": ">5",
|
|
"measurement": "Certifierade produkter",
|
|
"frequency": "Kvartalsvis",
|
|
},
|
|
],
|
|
},
|
|
"interoperability": {
|
|
"dimension": "Interoperabilitet",
|
|
"description": "Antal system som kan utbyta data via RIS utan specialanpassning",
|
|
"metrics": [
|
|
{
|
|
"metric": "RIS Compatible Systems",
|
|
"definition": "Antal system med RIS Compatible-certifiering",
|
|
"target": ">15",
|
|
"measurement": "Certifierade system",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Federated Queries",
|
|
"definition": "Antal frågor över flera system",
|
|
"target": ">1000/månad",
|
|
"measurement": "Loggade federerade frågor",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Data Exchange Volume",
|
|
"definition": "Volym data utbytt via RIS",
|
|
"target": ">1TB/månad",
|
|
"measurement": "Bytes överförda",
|
|
"frequency": "Månadsvis",
|
|
},
|
|
{
|
|
"metric": "Cross-domain Usage",
|
|
"definition": "Andel användare som använder flera domäner",
|
|
"target": ">40%",
|
|
"measurement": "Användare med >1 domän / Totala användare",
|
|
"frequency": "Kvartalsvis",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
"reporting": {
|
|
"dashboard": "https://landvex.com/admin/validation-metrics",
|
|
"frequency": "Månadsvis rapport till ledning",
|
|
"public_transparency": "Kvartalsvis publicerad rapport",
|
|
"benchmarking": "Jämförelse med branschstandarder",
|
|
},
|
|
}
|
|
|
|
|
|
# ─── TECHNICAL SPECIFICATION RFC ──────────────────────────────────────────────
|
|
|
|
@router.get("/public/technical-specification")
|
|
async def get_technical_specification():
|
|
"""
|
|
Teknisk specifikation — nästa viktiga leverans efter arkitekturen.
|
|
"""
|
|
return {
|
|
"document_title": "Reality Intelligence Standard (RIS) Technical Specification",
|
|
"version": "1.0.0-draft",
|
|
"status": "Draft",
|
|
"purpose": "Nästa viktiga leverans efter arkitekturen. En RFC/ISO-liknande standard som blir referens för utvecklare, partners och kunder.",
|
|
"table_of_contents": {
|
|
"1_executive_summary": {
|
|
"section": 1,
|
|
"title": "Executive Summary",
|
|
"content": "Översikt över RIS och LIFE",
|
|
},
|
|
"2_vision_principles": {
|
|
"section": 2,
|
|
"title": "Vision and Principles",
|
|
"content": [
|
|
"Reality Intelligence definition",
|
|
"Evidence Before Opinion",
|
|
"Multi-source Fusion",
|
|
"Traceability",
|
|
"Explainability",
|
|
"Openness",
|
|
],
|
|
},
|
|
"3_architecture": {
|
|
"section": 3,
|
|
"title": "Architecture",
|
|
"content": [
|
|
"4-nivåers plattformsarkitektur",
|
|
"9 Core Blocks",
|
|
"5 Enterprise Pillars",
|
|
"6 RIS Standards",
|
|
],
|
|
},
|
|
"4_ontology": {
|
|
"section": 4,
|
|
"title": "Ontology",
|
|
"content": [
|
|
"Core Ontology (12 universella begrepp)",
|
|
"Domain Ontologies (Infrastructure, Aid, Insurance, Environment)",
|
|
"Customer Extensions",
|
|
"Versioning and Governance",
|
|
],
|
|
},
|
|
"5_ris_specifications": {
|
|
"section": 5,
|
|
"title": "RIS Specifications",
|
|
"content": [
|
|
"RIS-001: Reality Object Standard",
|
|
"RIS-002: Evidence Standard",
|
|
"RIS-003: Confidence Standard",
|
|
"RIS-004: Reality Exchange Protocol",
|
|
"RIS-005: Decision Standard",
|
|
"RIS-006: Learning Standard",
|
|
],
|
|
},
|
|
"6_object_model": {
|
|
"section": 6,
|
|
"title": "Object Model",
|
|
"content": [
|
|
"Identity",
|
|
"Geometry",
|
|
"Time",
|
|
"State",
|
|
"Evidence",
|
|
"Confidence",
|
|
"Relationships",
|
|
"History",
|
|
"Predictions",
|
|
"Actions",
|
|
],
|
|
},
|
|
"7_evidence_model": {
|
|
"section": 7,
|
|
"title": "Evidence Model",
|
|
"content": [
|
|
"Source",
|
|
"Timestamp",
|
|
"Geographic Position",
|
|
"Method",
|
|
"Quality",
|
|
"Uncertainty",
|
|
"Validation Status",
|
|
"Revision History",
|
|
],
|
|
},
|
|
"8_api_contracts": {
|
|
"section": 8,
|
|
"title": "API Contracts",
|
|
"content": [
|
|
"/objects",
|
|
"/observations",
|
|
"/evidence",
|
|
"/relationships",
|
|
"/events",
|
|
"/hypotheses",
|
|
"/predictions",
|
|
"/actions",
|
|
"/missions",
|
|
],
|
|
},
|
|
"9_security_model": {
|
|
"section": 9,
|
|
"title": "Security Model",
|
|
"content": [
|
|
"Authentication (OAuth 2.0)",
|
|
"Authorization (RBAC)",
|
|
"Data Encryption",
|
|
"Audit Logging",
|
|
"Compliance (GDPR, ISO 27001)",
|
|
],
|
|
},
|
|
"10_versioning": {
|
|
"section": 10,
|
|
"title": "Versioning Strategy",
|
|
"content": [
|
|
"Semantic Versioning",
|
|
"Backward Compatibility",
|
|
"Deprecation Policy",
|
|
"Migration Guides",
|
|
],
|
|
},
|
|
"11_governance": {
|
|
"section": 11,
|
|
"title": "Governance",
|
|
"content": [
|
|
"RIS Board (RISB)",
|
|
"RFC Process",
|
|
"Decision Making",
|
|
"Community Participation",
|
|
],
|
|
},
|
|
"12_reference_implementation": {
|
|
"section": 12,
|
|
"title": "Reference Implementation",
|
|
"content": [
|
|
"LIFE Server",
|
|
"LIFE Client",
|
|
"LIFE SDK",
|
|
"Example Data",
|
|
"Example APIs",
|
|
],
|
|
},
|
|
"13_conformance": {
|
|
"section": 13,
|
|
"title": "Conformance Requirements",
|
|
"content": [
|
|
"RIS Compatible",
|
|
"RIS Certified",
|
|
"RIS Enterprise Certified",
|
|
"Testing Procedures",
|
|
],
|
|
},
|
|
"14_examples": {
|
|
"section": 14,
|
|
"title": "Examples and Test Cases",
|
|
"content": [
|
|
"Creating a Reality Object",
|
|
"Submitting Evidence",
|
|
"Querying with Confidence",
|
|
"Building a Decision",
|
|
"Interoperability Tests",
|
|
],
|
|
},
|
|
},
|
|
"target_audience": [
|
|
"Software Developers",
|
|
"System Architects",
|
|
"Product Managers",
|
|
"Technical Partners",
|
|
"Customers",
|
|
"Auditors",
|
|
"Regulators",
|
|
],
|
|
"publication": {
|
|
"formats": ["PDF", "HTML", "Markdown"],
|
|
"url": "https://standard.life.ai/spec/v1.0.0",
|
|
"license": "CC BY 4.0",
|
|
"update_frequency": "Kvartalsvis",
|
|
},
|
|
}
|