{
 "$schema": "https://json-schema.org/draft/2020-12/schema",
 "$id": "https://efix.kz/static/schema/efix-protocol-v1.json",
 "title": "Машиночитаемый протокол eFix, версия 1",
 "description": "protocol.json рядом с protocol.pdf в архиве протокола: реквизиты протокола фиксации (п. 5 ст. 78 ГПК РК), объект, время, хеши, пределы и реестр файлов. Подписан той же ЭЦП НУЦ РК, что и PDF: protocol.json.cms — отсоединённая подпись CMS над байтами этого файла.",
 "type": "object",
 "required": ["format", "schema", "generated_at", "system", "protocol", "object", "time", "pdf", "files", "verification"],
 "additionalProperties": false,
 "properties": {
  "format": {"const": "efix-protocol-v1"},
  "schema": {"type": "string", "format": "uri"},
  "generated_at": {"type": "string", "description": "UTC, ISO 8601"},
  "system": {
   "type": "object", "required": ["name", "version"],
   "properties": {"name": {"const": "eFix"}, "version": {"type": "string"}}
  },
  "protocol": {
   "type": "object", "required": ["id", "source_type", "capture_timestamp"],
   "properties": {
    "id": {"type": "string", "pattern": "^[A-Za-z]{2}-"},
    "source_type": {"type": "string", "enum": ["web", "social", "email", "messenger", "video", "mobile", "stamp", "document", "ad"]},
    "language": {"type": "string", "enum": ["ru", "kk"]},
    "created_at": {"type": ["string", "null"]},
    "capture_timestamp": {"type": ["string", "null"]},
    "completed_at": {"type": ["string", "null"]},
    "revoked": {"type": "boolean"},
    "supersedes": {"type": ["string", "null"]},
    "superseded_by": {"type": ["string", "null"]}
   }
  },
  "applicant": {
   "type": "object",
   "properties": {"name": {"type": ["string", "null"]}, "id_number": {"type": ["string", "null"]}}
  },
  "object": {
   "type": "object", "required": ["url"],
   "properties": {
    "url": {"type": "string"}, "final_url": {"type": ["string", "null"]}, "domain": {"type": ["string", "null"]},
    "title": {"type": ["string", "null"]}, "device_type": {"type": ["string", "null"]},
    "resolved_ip": {"type": ["string", "null"]}, "http_status": {"type": ["integer", "string", "null"]}
   }
  },
  "time": {
   "type": "object", "required": ["capture_timestamp", "source"],
   "properties": {
    "capture_timestamp": {"type": ["string", "null"]},
    "source": {"type": "string", "enum": ["ntp", "system_clock"]},
    "ntp_server": {"type": ["string", "null"]},
    "ntp_offset_ms": {"type": ["number", "string", "null"]}
   }
  },
  "pdf": {
   "type": "object", "required": ["file", "sha256", "signed"],
   "properties": {
    "file": {"const": "protocol.pdf"},
    "sha256": {"type": ["string", "null"], "pattern": "^[0-9a-f]{64}$"},
    "sha512": {"type": ["string", "null"]},
    "signed": {"type": "boolean"},
    "signature": {"type": "object", "description": "Сведения о сертификате подписанта PDF, как они напечатаны в разделе 5"}
   }
  },
  "limits": {
   "type": "object",
   "description": "Что захват не смог или о чём предупреждает; пустой объект — предупреждений нет. Ключи те же, что в capture_data протокола."
  },
  "ledger": {
   "type": ["object", "null"],
   "description": "Запись в реестре прозрачности eFix на момент выпуска файла; позиция и корень появляются после запечатывания дня, актуальное состояние — evidence_record_url.",
   "properties": {
    "position": {"type": ["integer", "null"]}, "entry_hash": {"type": ["string", "null"]},
    "status": {"type": ["string", "null"]}, "root": {"type": ["object", "null"]}
   }
  },
  "files": {
   "type": "array",
   "description": "Все файлы архива протокола, кроме самого protocol.json, его подписи и ZIP.",
   "items": {
    "type": "object", "required": ["name", "size", "sha256"],
    "properties": {"name": {"type": "string"}, "size": {"type": "integer", "minimum": 0}, "sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"}}
   }
  },
  "verification": {
   "type": "object", "required": ["verify_url"],
   "properties": {
    "verify_url": {"type": "string", "format": "uri"}, "api_url": {"type": "string", "format": "uri"},
    "evidence_record_url": {"type": "string", "format": "uri"}, "how_to_verify": {"type": "string", "format": "uri"}
   }
  },
  "not_established": {"type": "array", "items": {"type": "string"}}
 }
}
