{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "opjd/schema/dictionary/1.0.0",
  "title": "oPJD Dictionary — Format",
  "description": "Metaschema des semantischen Dictionaries: die normative, maschinenlesbare Bedeutungsschicht des oPJD. Je Spezifikationsversion existiert eine dictionary.json mit einem Eintrag pro Objekt, Feld und Enum-Wert. Term-IDs folgen dem Schema opjd://<version>/<pfad>[/<wert>] und sind versionsübergreifend stabil; Terme werden nie gelöscht, sondern über deprecated_in/superseded_by geführt. Eigene SemVer, unabhängig von den Spezifikationsversionen.",
  "type": "object",
  "required": ["dictionary_format", "spec_version", "schema_id", "license", "entries"],
  "additionalProperties": false,
  "properties": {
    "dictionary_format": { "const": "opjd-dictionary/1.0.0" },
    "spec_version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$" },
    "schema_id": { "type": "string", "minLength": 1 },
    "license": { "const": "CC-BY-4.0" },
    "entries": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/entry" }
    }
  },
  "$defs": {
    "text_de_en": {
      "type": "object",
      "required": ["de"],
      "additionalProperties": false,
      "properties": {
        "de": { "type": "string", "minLength": 1 },
        "en": { "type": "string" }
      }
    },
    "text_de_en_required": {
      "type": "object",
      "required": ["de", "en"],
      "additionalProperties": false,
      "properties": {
        "de": { "type": "string", "minLength": 1 },
        "en": { "type": "string", "minLength": 1 }
      }
    },
    "entry": {
      "type": "object",
      "required": [
        "id", "kind", "path", "schema_pointer", "instance_paths",
        "label", "definition", "since_version", "deprecated_in", "superseded_by"
      ],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string", "pattern": "^opjd://\\d+\\.\\d+\\.\\d+/[a-z0-9_.]+(/[A-Za-z_][A-Za-z0-9_]*)?$" },
        "kind": {
          "type": "string",
          "enum": ["object", "field", "type", "value_set", "enum_value", "event_type", "episode_type", "relation_type"],
          "description": "event_type/episode_type/relation_type sind spezialisierte Enum-Werte (für Gruppierung und Filter)."
        },
        "path": { "type": "string", "pattern": "^[a-z0-9_.]+$" },
        "value": { "type": "string", "description": "Nur bei Enum-Wert-Einträgen (kind enum_value/event_type/episode_type/relation_type)." },
        "schema_pointer": { "type": "string", "pattern": "^#(/.*)?$" },
        "instance_paths": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "label": { "$ref": "#/$defs/text_de_en_required" },
        "definition": { "$ref": "#/$defs/text_de_en_required" },
        "rationale": { "$ref": "#/$defs/text_de_en" },
        "datatype": { "type": "string", "description": "Menschenlesbar, z. B. \"array<use_purpose> (minItems 1)\"." },
        "requirement": { "type": ["string", "null"], "enum": ["required", "optional", "conditional", null] },
        "constraints_note": { "$ref": "#/$defs/text_de_en" },
        "clinical_notes": { "$ref": "#/$defs/text_de_en" },
        "obds_mapping": {
          "type": ["object", "null"],
          "required": ["element", "note"],
          "additionalProperties": false,
          "properties": {
            "element": { "type": ["string", "null"], "description": "oBDS-Element/-Pfad; null = dokumentierte oBDS-Lücke (note erklärt)." },
            "note": { "type": "string", "minLength": 1 }
          }
        },
        "examples": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["description"],
            "additionalProperties": false,
            "properties": {
              "description": { "$ref": "#/$defs/text_de_en" },
              "json": {},
              "ref": { "type": "string", "description": "Name eines Referenzbeispiels, z. B. opjd-example-nsclc." }
            }
          }
        },
        "since_version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$" },
        "deprecated_in": { "type": ["string", "null"], "pattern": "^\\d+\\.\\d+\\.\\d+$" },
        "superseded_by": { "type": ["string", "null"], "pattern": "^opjd://" },
        "related": { "type": "array", "items": { "type": "string", "pattern": "^opjd://" } }
      },
      "allOf": [
        {
          "if": { "properties": { "kind": { "enum": ["enum_value", "event_type", "episode_type", "relation_type"] } }, "required": ["kind"] },
          "then": { "required": ["value"] }
        }
      ]
    }
  }
}
