{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "opjd/schema/opjd-package/0.2.0",
  "title": "oPJD Package — oncological Patient Journey Dataset",
  "description": "Formaler Kontrakt für ein oPJD-Datenpaket: die konsolidierte onkologische Patient Journey eines Patienten inklusive Austauschhülle (delivery), Ereignissen mit unveränderter oBDS-Nutzlast, Episoden (Klammern), typisierten Relationen (Bezügen) und Metadaten-Layer. SemVer: Breaking Changes erhöhen major, additive Felder minor. Status: 0.x = Entwurf im Rahmen von BZKF OncoFlow. Referenzielle Integrität (z. B. dass event-Referenzen existieren) ist bewusst nicht per JSON Schema erzwingbar und wird auf Validator-Ebene geprüft.",
  "type": "object",
  "required": ["schema_version", "delivery", "patient", "tumors", "events", "episodes", "relations"],
  "additionalProperties": false,
  "properties": {
    "schema_version": {
      "type": "string",
      "pattern": "^0\\.\\d+\\.\\d+$",
      "description": "Version dieses Schemas (SemVer, major = 0 während der Entwurfsphase)"
    },
    "delivery": { "$ref": "#/$defs/delivery" },
    "patient": { "$ref": "#/$defs/patient" },
    "tumors": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/tumor" },
      "description": "Alle Tumorentitäten des Patienten, auf die sich Ereignisse und Episoden beziehen"
    },
    "events": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/event" },
      "description": "Die atomaren, dokumentierten Tatsachen. Die oBDS-Nutzlast bleibt unverändert (Prinzip: Schicht, nicht Ersatz)."
    },
    "episodes": {
      "type": "array",
      "items": { "$ref": "#/$defs/episode" },
      "description": "Die klinischen Klammern. Ein leeres Array ist zulässig (reines Ereignis-Paket, würdevoll zu oBDS degradiert), mindert aber den Nutzwert des Pakets."
    },
    "relations": {
      "type": "array",
      "items": { "$ref": "#/$defs/relation" },
      "description": "Typisierte, gerichtete Bezüge zwischen Ereignissen bzw. von Ereignissen zu Episoden"
    },
    "journey_status": {
      "type": "array",
      "items": { "$ref": "#/$defs/journeyStatus" },
      "description": "Optional: konsolidierter aktueller Zustand je Tumor"
    }
  },
  "$defs": {
    "id": {
      "type": "string",
      "minLength": 1,
      "description": "Stabile, innerhalb des Pakets eindeutige Kennung. Präfix-Konventionen (EVT-, EP-, REL-, TU-) sind empfohlen, nicht erzwungen."
    },
    "datePrecision": {
      "type": "string",
      "enum": ["E", "T", "M", "J"],
      "description": "Datumsgenauigkeit nach oBDS-Konvention: E = exakt, T = Tag geschätzt, M = Monat geschätzt, J = Jahr geschätzt"
    },
    "usePurpose": {
      "type": "string",
      "enum": [
        "treatment",
        "quality_assurance",
        "follow_up",
        "registry_completion",
        "research",
        "certification",
        "tumor_board_preparation",
        "data_reconciliation",
        "internal_reconciliation_only"
      ],
      "description": "Verwendungszweck-Vokabular (siehe Website: Data Delivery, Usage & Legal Context)"
    },
    "delivery": {
      "type": "object",
      "description": "Die Austauschhülle: Wer liefert an wen, auf welcher Grundlage, zu welchem Zweck, mit welcher Gültigkeit. Pflichtset entspricht dem Minimal-Set V1 der Spezifikation.",
      "required": [
        "package_id",
        "package_version",
        "package_created_at",
        "sending_organization",
        "sending_system",
        "receiving_organization",
        "delivery_context",
        "jurisdiction",
        "legal_basis_category",
        "permitted_use"
      ],
      "additionalProperties": false,
      "properties": {
        "package_id": { "$ref": "#/$defs/id" },
        "package_version": {
          "type": "integer",
          "minimum": 1,
          "description": "Version dieser Lieferung (Updates, Nachlieferungen, Korrekturen)"
        },
        "package_created_at": { "type": "string", "format": "date-time" },
        "sending_organization": { "type": "string", "minLength": 1 },
        "sending_unit": { "type": "string" },
        "sending_system": {
          "type": "string",
          "minLength": 1,
          "description": "Quellsystem, z. B. ONKOSTAR, Registersystem"
        },
        "receiving_organization": { "type": "string", "minLength": 1 },
        "delivery_context": {
          "$ref": "#/$defs/usePurpose",
          "description": "Anlass der Übermittlung"
        },
        "jurisdiction": {
          "type": "string",
          "minLength": 1,
          "description": "Rechtsraum, z. B. DE-BY"
        },
        "responsible_contact": { "type": "string" },
        "legal_basis_category": {
          "type": "string",
          "enum": [
            "clinical_care",
            "cancer_registry_law",
            "quality_assurance_regulation",
            "research_consent",
            "other_research_basis",
            "contractual_data_transfer",
            "jurisdiction_specific_exception"
          ]
        },
        "legal_basis_detail": { "type": "string" },
        "jurisdiction_specific_rule": { "type": "string" },
        "permitted_use": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/usePurpose" },
          "description": "Erlaubte Verwendungszwecke"
        },
        "prohibited_use": {
          "type": "array",
          "items": { "$ref": "#/$defs/usePurpose" }
        },
        "redisclosure_allowed": { "type": "boolean" },
        "valid_from": { "type": "string", "format": "date" },
        "valid_until": { "type": "string", "format": "date" },
        "last_verified_at": { "type": "string", "format": "date" },
        "refresh_required_after": { "type": "string", "format": "date" },
        "supersedes_package_id": { "$ref": "#/$defs/id" },
        "consent": { "$ref": "#/$defs/consent" },
        "restriction_flag": { "type": "boolean" },
        "restriction_note": { "type": "string" },
        "local_reconciliation_allowed": {
          "type": "boolean",
          "description": "Darf der Empfänger die Daten in den lokalen Bestand übernehmen/abgleichen?"
        }
      }
    },
    "consent": {
      "type": "object",
      "description": "Einwilligungs-/Freigabeinformation auf Patientenebene (kann von der Paket-Rechtsgrundlage abweichen)",
      "required": ["status"],
      "additionalProperties": false,
      "properties": {
        "status": {
          "type": "string",
          "enum": ["present", "not_present", "revoked", "unknown", "not_required"]
        },
        "scope": { "type": "string" },
        "valid_from": { "type": "string", "format": "date" },
        "valid_until": { "type": "string", "format": "date" },
        "revocation_date": { "type": "string", "format": "date" }
      }
    },
    "patient": {
      "type": "object",
      "required": ["patient_id", "id_kind"],
      "additionalProperties": false,
      "properties": {
        "patient_id": { "$ref": "#/$defs/id" },
        "id_kind": {
          "type": "string",
          "enum": ["pseudonym", "identified"],
          "description": "Pseudonymisiert oder identifiziert, je nach Einsatzkontext und Rechtsgrundlage"
        },
        "birth_date": { "type": "string", "format": "date" },
        "sex": {
          "type": "string",
          "enum": ["M", "W", "D", "U"],
          "description": "Geschlecht nach oBDS-Vokabular"
        },
        "obds": {
          "type": "object",
          "description": "Optionale unveränderte oBDS-Stammdaten-Nutzlast"
        }
      }
    },
    "tumor": {
      "type": "object",
      "required": ["tumor_id", "icd10", "diagnosis_date"],
      "additionalProperties": false,
      "properties": {
        "tumor_id": { "$ref": "#/$defs/id" },
        "icd10": {
          "type": "object",
          "required": ["code"],
          "additionalProperties": false,
          "properties": {
            "code": { "type": "string", "minLength": 1, "description": "ICD-10-GM, z. B. C34.1" },
            "version": { "type": "string" }
          }
        },
        "icd_o_morphology": {
          "type": "string",
          "description": "ICD-O-3-Morphologie, z. B. 8140/3"
        },
        "diagnosis_date": { "type": "string", "format": "date" },
        "diagnosis_date_precision": { "$ref": "#/$defs/datePrecision" },
        "laterality": { "type": "string", "description": "Seitenlokalisation nach oBDS-Vokabular" },
        "obds": { "type": "object", "description": "Optionale unveränderte oBDS-Nutzlast der Tumorzuordnung/Diagnose" }
      }
    },
    "eventMeta": {
      "type": "object",
      "description": "Metadaten-Layer eines Ereignisses: Herkunft, Aktualität, Qualität",
      "required": ["provenance", "currency", "quality"],
      "additionalProperties": false,
      "properties": {
        "provenance": {
          "type": "string",
          "enum": ["primary_clinical", "tumor_documentation", "registry", "study", "certification", "external"],
          "description": "Woher stammt die Information?"
        },
        "currency": {
          "type": "string",
          "enum": ["current", "delayed", "historical"],
          "description": "Wie synchron ist die Information mit dem klinischen Geschehen?"
        },
        "quality": {
          "type": "string",
          "enum": ["curated", "derived", "limited", "unconfirmed"],
          "description": "Praktikable Qualitätsstufe, aus Quelle und Prozess ableitbar"
        },
        "source_system": { "type": "string" },
        "source_category": { "type": "string", "enum": ["primary", "secondary"] },
        "recorded_at": { "type": "string", "format": "date" },
        "last_confirmed_at": { "type": "string", "format": "date" }
      }
    },
    "interpretationMeta": {
      "type": "object",
      "description": "Metadaten der Interpretationsschicht (Episoden, Relationen): Die Klammer selbst hat eine Herkunft. derived = algorithmisch aus oBDS-Indizien vorgeschlagen, curated = fachlich bestätigt.",
      "required": ["quality"],
      "additionalProperties": false,
      "properties": {
        "quality": { "type": "string", "enum": ["curated", "derived"] },
        "derived_from": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Indizien, aus denen die Interpretation abgeleitet wurde, z. B. \"Stellung_OP=N\", \"ycTNM\", \"Datumsfenster\""
        },
        "annotated_at": { "type": "string", "format": "date" },
        "annotated_by_role": {
          "type": "string",
          "enum": ["algorithm", "tumor_documentation", "physician"],
          "description": "Rolle, nicht Person — die Bewertung soll aus dem Prozess ableitbar sein"
        }
      }
    },
    "event": {
      "type": "object",
      "required": ["event_id", "type", "date", "tumor_ref", "meta"],
      "additionalProperties": false,
      "properties": {
        "event_id": { "$ref": "#/$defs/id" },
        "type": {
          "type": "string",
          "enum": [
            "diagnosis",
            "pathology_report",
            "surgery",
            "radiation_therapy",
            "systemic_therapy",
            "progress_report",
            "tumor_board",
            "death",
            "study_enrollment",
            "other"
          ],
          "description": "Ereignistyp. Die ersten acht sind auf die oBDS-Dokumentzweige gemappt (Diagnose, Pathologie, OP, ST, SYST, Verlauf, Tumorkonferenz, Tod). study_enrollment ist ein oPJD-Zusatztyp: Der Studieneinschluss (Einwilligung/Registrierung/Randomisierung) ist im oBDS nicht abbildbar, aber ein Schlüsselereignis der Journey — Herkunft typischerweise Studiendokumentation (meta.provenance = study)."
        },
        "date": { "type": "string", "format": "date" },
        "date_precision": { "$ref": "#/$defs/datePrecision" },
        "tumor_ref": { "$ref": "#/$defs/id" },
        "key_event": {
          "type": "boolean",
          "description": "Schlüsselereignis mit strukturierender Funktion (Erstdiagnose, Tumorboard-Beschluss, Progressionsnachweis)"
        },
        "obds": {
          "type": "object",
          "description": "Unveränderte oBDS-Nutzlast des zugrunde liegenden Dokuments. Semantische Basis bleibt oBDS (ICD-10-GM, ICD-O-3, OPS, TNM) — der oPJD fügt keine neuen Codes ein."
        },
        "note": { "type": "string" },
        "meta": { "$ref": "#/$defs/eventMeta" }
      }
    },
    "episode": {
      "type": "object",
      "description": "Die Klammer: ein klinisch definierter Sinnabschnitt. Die Zuordnung von Ereignissen wohnt in der Episode (events[]), nicht im Ereignis — Ereignisse bleiben unangetastet. Zwei Kategorien: VERLAUFSPHASEN (first_diagnosis, neoadjuvant, surgical, adjuvant, follow_up, progression, palliative_line, active_surveillance, watchful_waiting) strukturieren den Behandlungsverlauf und sollen sich je Tumor nicht überlappen (Validator-Regel). KONTEXTKLAMMERN (study_participation, primary_case, center_case) laufen parallel zu den Verlaufsphasen und dürfen sich mit ihnen und untereinander überlappen — dasselbe Ereignis darf in mehreren Episoden referenziert sein (z. B. Protokoll-Chemotherapie in neoadjuvanter Phase UND Studienphase).",
      "required": ["episode_id", "type", "tumor_ref", "events", "meta"],
      "additionalProperties": false,
      "properties": {
        "episode_id": { "$ref": "#/$defs/id" },
        "type": {
          "type": "string",
          "enum": [
            "first_diagnosis",
            "neoadjuvant",
            "surgical",
            "adjuvant",
            "follow_up",
            "progression",
            "palliative_line",
            "active_surveillance",
            "watchful_waiting",
            "study_participation",
            "primary_case",
            "center_case",
            "other"
          ],
          "description": "active_surveillance: strukturierte Überwachung mit aufgeschobenem kurativem Therapieanspruch (intent: curative); erwartet regelmäßige Kontrollereignisse — eine Überwachungsepisode ohne Kontrollen ist eine sichtbare Lücke (Lost-to-follow-up). watchful_waiting: symptomorientiertes Abwarten ohne kurativen Anspruch (intent: palliative). oBDS-Bezug: Die Tumorkonferenz-Empfehlungstypen WW/AS/WS liefern Indizien (derived_from). study_participation: vom Studieneinschluss (study_enrollment) bis zum Ende der Studienteilnahme (EOT/EOS); erfordert study. primary_case / center_case: deklarative Fallklassifikation der benannten Einrichtung nach der jeweils gültigen Zertifizierungsdefinition (z. B. DKG/OnkoZert-Kennzahlenbogen) — der oPJD transportiert die Deklaration samt Herkunft, er berechnet sie nicht; erfordert organization, meta.provenance des zugrunde liegenden Prozesses ist typischerweise certification."
        },
        "tumor_ref": { "$ref": "#/$defs/id" },
        "intent": {
          "type": "string",
          "enum": ["curative", "palliative", "mixed", "unknown"],
          "description": "Intention/Therapieziel auf Episodenebene — die Klammer trägt die Strategie, nicht nur die Einzeltherapie. Konvention: active_surveillance → curative (aufgeschoben), watchful_waiting → palliative."
        },
        "study": {
          "type": "object",
          "description": "Studienbezug — Pflicht bei type = study_participation",
          "required": ["registry", "code"],
          "additionalProperties": false,
          "properties": {
            "registry": {
              "type": "string",
              "enum": ["NCT", "DRKS", "EudraCT", "ISRCTN", "other"],
              "description": "Studienregister, in dem die Studie geführt wird"
            },
            "code": { "type": "string", "minLength": 1, "description": "Registernummer, z. B. NCT-Nummer" },
            "name": { "type": "string", "description": "Studienname/Akronym" },
            "arm": { "type": "string", "description": "Studienarm, sofern bekannt und übermittelbar" }
          }
        },
        "organization": {
          "type": "string",
          "description": "Deklarierende bzw. behandelnde Einrichtung — Pflicht bei type = primary_case oder center_case (wessen Fallzählung gilt hier?)"
        },
        "line_number": {
          "type": "integer",
          "minimum": 1,
          "description": "Therapielinie (v. a. für palliative_line), ESMO-Zählung anschlussfähig"
        },
        "start_event": { "$ref": "#/$defs/id" },
        "end_event": { "$ref": "#/$defs/id" },
        "events": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/id" },
          "description": "Alle Ereignisse dieser Episode (event_ids)"
        },
        "status": { "type": "string", "enum": ["active", "completed", "unknown"] },
        "meta": { "$ref": "#/$defs/interpretationMeta" }
      },
      "allOf": [
        {
          "if": {
            "properties": { "type": { "const": "study_participation" } },
            "required": ["type"]
          },
          "then": { "required": ["study"] }
        },
        {
          "if": {
            "properties": { "type": { "enum": ["primary_case", "center_case"] } },
            "required": ["type"]
          },
          "then": { "required": ["organization"] }
        }
      ]
    },
    "relation": {
      "type": "object",
      "description": "Gerichteter, typisierter Bezug. Leserichtung folgt der Grammatik, nicht der Zeit: from [Subjekt] --type [Verb]--> to [Objekt]. from ist immer das Element, das den Bezug ausspricht. Erwartete Ziele je Typ: result_of → Ereignis (Befund → Maßnahme), implements → Ereignis (Maßnahme → Beschluss/Empfehlung), assesses → Episode oder Ereignis (Bewertung → Beurteiltes), triggers → Episode (Auslöser → neue Klammer).",
      "required": ["relation_id", "type", "from", "to", "meta"],
      "additionalProperties": false,
      "properties": {
        "relation_id": { "$ref": "#/$defs/id" },
        "type": {
          "type": "string",
          "enum": ["result_of", "implements", "assesses", "triggers"],
          "description": "result_of = \"ist Ergebnis von\", implements = \"setzt um\", assesses = \"beurteilt\", triggers = \"löst aus\""
        },
        "from": {
          "$ref": "#/$defs/id",
          "description": "event_id des aussprechenden Ereignisses"
        },
        "to": {
          "$ref": "#/$defs/id",
          "description": "event_id oder episode_id des Bezugsziels (typabhängig, siehe Objektbeschreibung)"
        },
        "note": { "type": "string" },
        "meta": { "$ref": "#/$defs/interpretationMeta" }
      }
    },
    "journeyStatus": {
      "type": "object",
      "required": ["tumor_ref"],
      "additionalProperties": false,
      "properties": {
        "tumor_ref": { "$ref": "#/$defs/id" },
        "active_episode": { "$ref": "#/$defs/id" },
        "current_line": { "type": "integer", "minimum": 1 },
        "last_assessment": {
          "type": "object",
          "required": ["event_ref"],
          "additionalProperties": false,
          "properties": {
            "event_ref": { "$ref": "#/$defs/id" },
            "overall_assessment": {
              "type": "string",
              "description": "Gesamtbeurteilung nach oBDS-Vokabular (z. B. V, T, K, P, U)"
            }
          }
        }
      }
    }
  }
}
