{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "UXlab deployment manifest v1",
  "type": "object",
  "additionalProperties": false,
  "required": ["schema_version", "slug", "title", "description", "repository", "maintainer_email", "supervisor_email", "kind", "entrypoint", "runbook", "internal_port", "base_path", "env_example", "secret_names", "persistent_data", "external_services", "access", "resources", "verification", "data_lifecycle", "available_until"],
  "properties": {
    "schema_version": {"const": 1},
    "slug": {"type": "string", "pattern": "^[a-z][a-z0-9-]{0,47}$"},
    "title": {"type": "string", "minLength": 1},
    "description": {"type": "string", "minLength": 1},
    "repository": {"type": "string", "pattern": "^https://gitlab\\.fit\\.cvut\\.cz/[A-Za-z0-9_./-]+$"},
    "maintainer_email": {"type": "string", "format": "email"},
    "supervisor_email": {"type": "string", "format": "email"},
    "kind": {"enum": ["compose", "container", "static"]},
    "entrypoint": {"$ref": "#/$defs/file"},
    "runbook": {"$ref": "#/$defs/file"},
    "internal_port": {"type": "integer", "minimum": 1, "maximum": 65535},
    "base_path": {"type": "string", "pattern": "^/demo/[a-z][a-z0-9-]{0,47}/$"},
    "env_example": {"$ref": "#/$defs/file"},
    "secret_names": {"type": "array", "items": {"type": "string", "pattern": "^[A-Z][A-Z0-9_]*$"}, "uniqueItems": true},
    "persistent_data": {"type": "array", "items": {"type": "string"}},
    "external_services": {"type": "array", "items": {"type": "string"}},
    "access": {"enum": ["public", "testers", "vpn"]},
    "resources": {"type": "object", "additionalProperties": false, "required": ["ram_mb", "disk_mb"], "properties": {"ram_mb": {"type": "integer", "minimum": 1}, "disk_mb": {"type": "integer", "minimum": 1}}},
    "verification": {"type": "object", "additionalProperties": false, "required": ["path", "expected_status", "scenario"], "properties": {"path": {"type": "string", "pattern": "^/"}, "expected_status": {"type": "integer", "minimum": 200, "maximum": 599}, "scenario": {"type": "string", "minLength": 1}}},
    "data_lifecycle": {"type": "string", "minLength": 1},
    "available_until": {"type": "string", "format": "date"}
  },
  "$defs": {"file": {"type": "string", "minLength": 1, "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))[A-Za-z0-9_./-]+$"}}
}
