{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://qaz.bio/schemas/public-entity.schema.json",
  "title": "QAZ.BIO public entity",
  "type": "object",
  "required": ["id", "slug", "kind", "names", "source_refs", "publication", "evidence", "profile_url", "profile_json_url"],
  "properties": {
    "id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._:-]{2,127}$"},
    "slug": {"type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"},
    "kind": {"enum": ["person", "organisation"]},
    "profile_url": {"type": "string", "format": "uri"},
    "profile_json_url": {"type": "string", "format": "uri"},
    "names": {
      "type": "object",
      "required": ["ru"],
      "properties": {
        "kk": {"type": "string", "minLength": 1},
        "ru": {"type": "string", "minLength": 1},
        "en": {"type": "string", "minLength": 1}
      },
      "additionalProperties": false
    },
    "summary": {
      "type": "object",
      "properties": {
        "kk": {"type": "string", "maxLength": 500},
        "ru": {"type": "string", "maxLength": 500},
        "en": {"type": "string", "maxLength": 500}
      },
      "additionalProperties": {"type": ["string", "number", "boolean", "null"]}
    },
    "identifiers": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["system", "type", "value", "source_url", "evidence"],
        "properties": {
          "system": {"const": "egov"},
          "type": {"const": "BIN"},
          "value": {"type": "string", "pattern": "^\\d{12}$"},
          "source_url": {"type": "string", "format": "uri"},
          "evidence": {"$ref": "#/$defs/evidence"}
        },
        "additionalProperties": false
      }
    },
    "federated_links": {
      "type": "array",
      "items": {"$ref": "#/$defs/federatedLink"}
    },
    "roles": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["title", "organisation", "start_date", "evidence"],
        "properties": {
          "title": {"type": "string"},
          "position_id": {"type": "string", "pattern": "^qbio:position:[a-f0-9]{24}$"},
          "organisation": {"type": "string"},
          "organisation_slug": {"type": ["string", "null"]},
          "start_date": {"$ref": "#/$defs/partialDate"},
          "end_date": {"$ref": "#/$defs/partialDateOrNull"},
          "role_period_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._:-]{2,127}$"},
          "current_membership": {"type": ["boolean", "null"]},
          "composition_checked_at": {"type": ["string", "null"], "format": "date-time"},
          "end_date_status": {"enum": ["known", "unknown", "not_applicable"]},
          "evidence_history": {"type": "array", "items": {"$ref": "#/$defs/evidence"}},
          "evidence": {"$ref": "#/$defs/evidence"}
        },
        "additionalProperties": false
      }
    },
    "places": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["type", "name", "lat", "lon", "evidence"],
        "properties": {
          "type": {"enum": ["birthplace", "work_location", "institution_location", "event_location"]},
          "name": {"type": "string", "minLength": 1},
          "region_code": {"type": ["string", "null"]},
          "lat": {"type": ["number", "null"], "minimum": -90, "maximum": 90},
          "lon": {"type": ["number", "null"], "minimum": -180, "maximum": 180},
          "confidence": {"type": ["number", "null"], "minimum": 0, "maximum": 1},
          "evidence": {"$ref": "#/$defs/evidence"}
        },
        "additionalProperties": false
      }
    },
    "aliases": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["value", "type", "evidence"],
        "properties": {
          "value": {"type": "string", "minLength": 1},
          "type": {"enum": ["alternate_name", "former_name", "transliteration"]},
          "language": {"type": ["string", "null"]},
          "evidence": {"$ref": "#/$defs/evidence"}
        },
        "additionalProperties": false
      }
    },
    "relationships": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["target_id", "target_slug", "target_names", "type", "evidence"],
        "properties": {
          "target_id": {"type": "string", "minLength": 1},
          "target_slug": {"type": "string", "minLength": 1},
          "target_kind": {"enum": ["person", "organisation"]},
          "target_names": {"type": "object", "minProperties": 1, "additionalProperties": {"type": "string"}},
          "type": {"enum": ["affiliated_with", "appointed_by", "reports_to", "succeeds", "precedes"]},
          "start_date": {"$ref": "#/$defs/partialDateOrNull"},
          "end_date": {"$ref": "#/$defs/partialDateOrNull"},
          "evidence": {"$ref": "#/$defs/evidence"}
        },
        "additionalProperties": false
      }
    },
    "legal_status_history": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["status", "start_date", "evidence"],
        "properties": {
          "status": {"type": "string", "minLength": 1},
          "start_date": {"$ref": "#/$defs/partialDate"},
          "end_date": {"$ref": "#/$defs/partialDateOrNull"},
          "registry_url": {"type": ["string", "null"], "format": "uri"},
          "evidence": {"$ref": "#/$defs/evidence"}
        },
        "additionalProperties": false
      }
    },
    "officers": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["target_id", "target_slug", "target_names", "title", "evidence"],
        "properties": {
          "target_id": {"type": "string", "minLength": 1},
          "target_slug": {"type": "string", "minLength": 1},
          "target_names": {"type": "object", "minProperties": 1, "additionalProperties": {"type": "string"}},
          "title": {"type": "string", "minLength": 1},
          "start_date": {"$ref": "#/$defs/partialDateOrNull"},
          "end_date": {"$ref": "#/$defs/partialDateOrNull"},
          "evidence": {"$ref": "#/$defs/evidence"}
        },
        "additionalProperties": false
      }
    },
    "parent_links": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["target_id", "target_slug", "target_names", "type", "evidence"],
        "properties": {
          "target_id": {"type": "string", "minLength": 1},
          "target_slug": {"type": "string", "minLength": 1},
          "target_names": {"type": "object", "minProperties": 1, "additionalProperties": {"type": "string"}},
          "type": {"enum": ["parent", "subsidiary", "controlled_by", "controls"]},
          "start_date": {"$ref": "#/$defs/partialDateOrNull"},
          "end_date": {"$ref": "#/$defs/partialDateOrNull"},
          "evidence": {"$ref": "#/$defs/evidence"}
        },
        "additionalProperties": false
      }
    },
    "source_refs": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["system", "record_id", "url"],
        "properties": {
          "system": {"type": "string", "minLength": 1},
          "record_id": {"type": "string", "minLength": 1},
          "url": {"type": "string", "format": "uri"}
        },
        "additionalProperties": false
      }
    },
    "publication": {
      "type": "object",
      "required": ["status", "reviewed_at"],
      "properties": {
        "status": {"const": "published"},
        "reviewed_at": {"type": "string", "format": "date-time"},
        "reviewer": {"type": "string", "minLength": 1}
      },
      "additionalProperties": false
    },
    "evidence": {"$ref": "#/$defs/evidence"}
  },
  "$defs": {
    "federatedLink": {
      "type": "object",
      "required": ["qbio_id", "system", "local_id", "canonical_url", "entity_kind", "status", "match_basis", "reviewed_at", "source_refs", "revision", "content_hash"],
      "properties": {
        "qbio_id": {"type": "string", "pattern": "^qbio:[a-z_]+:[^\\s]+$"},
        "system": {"enum": ["qpolity", "qazvision"]},
        "local_id": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{1,191}$"},
        "canonical_url": {"type": "string", "format": "uri"},
        "entity_kind": {"enum": ["person", "organisation"]},
        "status": {"const": "active"},
        "match_basis": {"type": "string", "minLength": 1},
        "reviewed_at": {"type": "string", "format": "date-time"},
        "source_refs": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {"type": "string", "format": "uri"}
        },
        "revision": {"type": "integer", "minimum": 1},
        "content_hash": {"type": "string", "pattern": "^[a-f0-9]{64}$"}
      },
      "additionalProperties": false
    },
    "partialDate": {
      "type": "string",
      "anyOf": [
        {"format": "date"},
        {"pattern": "^[0-9]{4}(?:-[0-9]{2})?$"}
      ]
    },
    "partialDateOrNull": {
      "anyOf": [
        {"type": "null"},
        {"$ref": "#/$defs/partialDate"}
      ]
    },
    "evidence": {
      "type": "object",
      "required": ["state", "source_url", "captured_at"],
      "properties": {
        "state": {"enum": ["verified", "sourced", "archival"]},
        "evidence_id": {"type": "string", "minLength": 1},
        "entity_id": {"type": "string", "minLength": 1},
        "source_id": {"type": "string", "minLength": 1},
        "title": {"type": ["string", "null"]},
        "source_url": {"type": "string", "format": "uri"},
        "archive_url": {"type": ["string", "null"], "format": "uri"},
        "captured_at": {"type": "string", "format": "date-time"},
        "content_hash": {"type": ["string", "null"], "pattern": "^[a-f0-9]{64}$"}
      },
      "allOf": [
        {
          "if": {
            "properties": {"state": {"const": "archival"}},
            "required": ["state"]
          },
          "then": {
            "required": ["content_hash", "archive_url"],
            "properties": {
              "content_hash": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
              "archive_url": {"type": "string", "format": "uri", "minLength": 1}
            }
          }
        }
      ],
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
