{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tools.press.zone/schemas/deployment-manifest-v1.json",
  "title": "PDF2HTML production deployment manifest",
  "type": "object",
  "additionalProperties": false,
  "required": ["$schema", "schemaVersion", "environment", "deploymentStatus", "domains", "components", "secretNames", "rollout", "rollback", "unresolvedAuthenticatedValues"],
  "properties": {
    "$schema": {"const": "./deployment.schema.json"},
    "schemaVersion": {"const": 1},
    "environment": {"const": "production"},
    "deploymentStatus": {"enum": ["blocked", "ready", "deployed"]},
    "domains": {"$ref": "#/$defs/domains"},
    "components": {"$ref": "#/$defs/components"},
    "secretNames": {"$ref": "#/$defs/secretNames"},
    "rollout": {"$ref": "#/$defs/rollout"},
    "rollback": {"$ref": "#/$defs/rollback"},
    "unresolvedAuthenticatedValues": {"type": "array", "uniqueItems": true, "items": {"$ref": "#/$defs/unresolved"}}
  },
  "allOf": [{
    "if": {"properties": {"deploymentStatus": {"enum": ["ready", "deployed"]}}, "required": ["deploymentStatus"]},
    "then": {
      "properties": {
        "unresolvedAuthenticatedValues": {"maxItems": 0},
        "components": {
          "properties": {
            "cloudflareFrontend": {"properties": {"accountId": {"type": "string", "minLength": 1}, "projectName": {"type": "string", "minLength": 1}, "deploymentTarget": {"type": "string", "minLength": 1}, "healthCheck": {"$ref": "#/$defs/verifiedHttpCheck"}}},
            "cloudpanelApi": {"properties": {"runtime": {"type": "string", "minLength": 1}, "serviceName": {"type": "string", "minLength": 1}, "originMapping": {"type": "string", "minLength": 1}, "healthCheck": {"$ref": "#/$defs/verifiedHttpCheck"}, "readinessCheck": {"$ref": "#/$defs/verifiedHttpCheck"}}},
            "cloudpanelWorker": {"properties": {"serviceName": {"type": "string", "minLength": 1}, "imageDigest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"}, "runtime": {"type": "string", "minLength": 1}, "resourceLimits": {"$ref": "#/$defs/resolvedResourceLimits"}, "healthCheck": {"$ref": "#/$defs/verifiedWorkerCheck"}}},
            "postgresMigrations": {"properties": {"artifact": {"type": "string", "minLength": 1}, "runner": {"type": "string", "minLength": 1}, "databaseTarget": {"type": "string", "minLength": 1}, "migrationCommand": {"type": "string", "minLength": 1}, "backupVerified": {"const": true}, "restoreVerified": {"const": true}, "transactional": {"type": "boolean"}}},
            "privateObjectStorage": {"properties": {"adapter": {"type": "string", "minLength": 1}, "endpoint": {"type": "string", "format": "uri"}, "region": {"type": "string", "minLength": 1}, "bucket": {"type": "string", "minLength": 1}, "encryption": {"type": "string", "minLength": 1}, "signedDownloadTtlSeconds": {"type": "integer", "minimum": 1}, "lifecycle": {"properties": {"sourcePrefix": {"type": "string", "minLength": 1}, "zipPrefix": {"type": "string", "minLength": 1}, "providerRuleIds": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}}, "deadlineSemanticsVerified": {"const": true}}}}}
          }
        },
        "rollback": {"properties": {"previousFrontendDeployment": {"type": "string", "minLength": 1}, "previousApiArtifact": {"type": "string", "minLength": 1}, "previousWorkerImageDigest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"}, "databaseRollbackProcedure": {"type": "string", "minLength": 1}}}
      }
    }
  }],
  "$defs": {
    "nullableString": {"type": ["string", "null"], "minLength": 1},
    "nullableInteger": {"type": ["integer", "null"], "minimum": 1},
    "domains": {"type": "object", "additionalProperties": false, "required": ["frontend", "api"], "properties": {"frontend": {"const": "https://tools.press.zone"}, "api": {"const": "https://api.press.zone"}}},
    "components": {"type": "object", "additionalProperties": false, "required": ["cloudflareFrontend", "cloudpanelApi", "cloudpanelWorker", "postgresMigrations", "privateObjectStorage"], "properties": {"cloudflareFrontend": {"$ref": "#/$defs/cloudflareFrontend"}, "cloudpanelApi": {"$ref": "#/$defs/cloudpanelApi"}, "cloudpanelWorker": {"$ref": "#/$defs/cloudpanelWorker"}, "postgresMigrations": {"$ref": "#/$defs/postgresMigrations"}, "privateObjectStorage": {"$ref": "#/$defs/privateObjectStorage"}}},
    "httpCheck": {"type": "object", "additionalProperties": false, "required": ["url", "method", "expectedStatuses", "requiresAuthentication", "contentAssertion", "verified"], "properties": {"url": {"type": "string", "format": "uri"}, "method": {"const": "GET"}, "expectedStatuses": {"type": "array", "minItems": 1, "maxItems": 1, "items": {"const": 200}}, "requiresAuthentication": {"type": "boolean"}, "contentAssertion": {"$ref": "#/$defs/contentAssertion"}, "verified": {"type": "boolean"}}},
    "verifiedHttpCheck": {"allOf": [{"$ref": "#/$defs/httpCheck"}, {"properties": {"verified": {"const": true}, "contentAssertion": {"properties": {"verified": {"const": true}}}}}]},
    "contentAssertion": {"type": "object", "additionalProperties": false, "required": ["kind", "value", "verified"], "properties": {"kind": {"enum": ["body-contains", "json-field-equals"]}, "value": {"type": "string", "minLength": 1}, "verified": {"type": "boolean"}}},
    "cloudflareFrontend": {"type": "object", "additionalProperties": false, "required": ["kind", "artifact", "accountId", "projectName", "deploymentTarget", "observedStatus", "healthCheck"], "properties": {"kind": {"const": "cloudflare-astro"}, "artifact": {"type": "string", "minLength": 1}, "accountId": {"$ref": "#/$defs/nullableString"}, "projectName": {"$ref": "#/$defs/nullableString"}, "deploymentTarget": {"$ref": "#/$defs/nullableString"}, "observedStatus": {"enum": ["unverified", "healthy", "deployed"]}, "healthCheck": {"$ref": "#/$defs/httpCheck"}}},
    "cloudpanelApi": {"type": "object", "additionalProperties": false, "required": ["kind", "artifact", "host", "runtime", "serviceName", "originMapping", "observedStatus", "healthCheck", "readinessCheck"], "properties": {"kind": {"const": "cloudpanel-process"}, "artifact": {"type": "string", "minLength": 1}, "host": {"const": "cloudpanel01"}, "runtime": {"$ref": "#/$defs/nullableString"}, "serviceName": {"$ref": "#/$defs/nullableString"}, "originMapping": {"$ref": "#/$defs/nullableString"}, "observedStatus": {"enum": ["unverified", "dns-tls-only", "healthy", "deployed"]}, "healthCheck": {"$ref": "#/$defs/httpCheck"}, "readinessCheck": {"$ref": "#/$defs/httpCheck"}}},
    "resourceLimits": {"type": "object", "additionalProperties": false, "required": ["cpu", "memoryBytes", "pids", "temporaryStorageBytes", "outputBytes", "fileCount", "wallTimeSeconds"], "properties": {"cpu": {"type": ["number", "null"], "exclusiveMinimum": 0}, "memoryBytes": {"$ref": "#/$defs/nullableInteger"}, "pids": {"$ref": "#/$defs/nullableInteger"}, "temporaryStorageBytes": {"$ref": "#/$defs/nullableInteger"}, "outputBytes": {"$ref": "#/$defs/nullableInteger"}, "fileCount": {"$ref": "#/$defs/nullableInteger"}, "wallTimeSeconds": {"$ref": "#/$defs/nullableInteger"}}},
    "resolvedResourceLimits": {"type": "object", "additionalProperties": false, "required": ["cpu", "memoryBytes", "pids", "temporaryStorageBytes", "outputBytes", "fileCount", "wallTimeSeconds"], "properties": {"cpu": {"type": "number", "exclusiveMinimum": 0}, "memoryBytes": {"type": "integer", "minimum": 1}, "pids": {"type": "integer", "minimum": 1}, "temporaryStorageBytes": {"type": "integer", "minimum": 1}, "outputBytes": {"type": "integer", "minimum": 1}, "fileCount": {"type": "integer", "minimum": 1}, "wallTimeSeconds": {"type": "integer", "minimum": 1}}},
    "workerCheck": {"type": "object", "additionalProperties": false, "required": ["mechanism", "expected", "verified"], "properties": {"mechanism": {"$ref": "#/$defs/nullableString"}, "expected": {"$ref": "#/$defs/nullableString"}, "verified": {"type": "boolean"}}},
    "verifiedWorkerCheck": {"allOf": [{"$ref": "#/$defs/workerCheck"}, {"properties": {"mechanism": {"type": "string", "minLength": 1}, "expected": {"type": "string", "minLength": 1}, "verified": {"const": true}}}]},
    "cloudpanelWorker": {"type": "object", "additionalProperties": false, "required": ["kind", "artifact", "host", "serviceName", "imageDigest", "runtime", "separateFromApi", "network", "runAsNonRoot", "readOnlyRootFilesystem", "dropAllCapabilities", "noNewPrivileges", "resourceLimits", "healthCheck"], "properties": {"kind": {"const": "cloudpanel-worker-container"}, "artifact": {"type": "string", "minLength": 1}, "host": {"const": "cloudpanel01"}, "serviceName": {"$ref": "#/$defs/nullableString"}, "imageDigest": {"$ref": "#/$defs/nullableString"}, "runtime": {"$ref": "#/$defs/nullableString"}, "separateFromApi": {"const": true}, "network": {"const": "disabled-for-conversion-job"}, "runAsNonRoot": {"const": true}, "readOnlyRootFilesystem": {"const": true}, "dropAllCapabilities": {"const": true}, "noNewPrivileges": {"const": true}, "resourceLimits": {"$ref": "#/$defs/resourceLimits"}, "healthCheck": {"$ref": "#/$defs/workerCheck"}}},
    "postgresMigrations": {"type": "object", "additionalProperties": false, "required": ["kind", "artifact", "runner", "databaseTarget", "migrationCommand", "backupVerified", "restoreVerified", "transactional"], "properties": {"kind": {"const": "postgres-migrations"}, "artifact": {"$ref": "#/$defs/nullableString"}, "runner": {"$ref": "#/$defs/nullableString"}, "databaseTarget": {"$ref": "#/$defs/nullableString"}, "migrationCommand": {"$ref": "#/$defs/nullableString"}, "backupVerified": {"type": "boolean"}, "restoreVerified": {"type": "boolean"}, "transactional": {"type": ["boolean", "null"]}}},
    "lifecycle": {"type": "object", "additionalProperties": false, "required": ["sourcePrefix", "zipPrefix", "sourceDeadlineHours", "zipDeadlineHours", "providerRuleIds", "deadlineSemanticsVerified", "applicationReconciliation"], "properties": {"sourcePrefix": {"$ref": "#/$defs/nullableString"}, "zipPrefix": {"$ref": "#/$defs/nullableString"}, "sourceDeadlineHours": {"const": 48}, "zipDeadlineHours": {"const": 48}, "providerRuleIds": {"type": ["array", "null"], "uniqueItems": true, "items": {"type": "string", "minLength": 1}}, "deadlineSemanticsVerified": {"type": "boolean"}, "applicationReconciliation": {"const": true}}},
    "privateObjectStorage": {"type": "object", "additionalProperties": false, "required": ["kind", "adapter", "endpoint", "region", "bucket", "publicAccess", "encryption", "signedDownloadTtlSeconds", "lifecycle"], "properties": {"kind": {"const": "s3-compatible-private"}, "adapter": {"$ref": "#/$defs/nullableString"}, "endpoint": {"$ref": "#/$defs/nullableString"}, "region": {"$ref": "#/$defs/nullableString"}, "bucket": {"$ref": "#/$defs/nullableString"}, "publicAccess": {"const": false}, "encryption": {"$ref": "#/$defs/nullableString"}, "signedDownloadTtlSeconds": {"$ref": "#/$defs/nullableInteger"}, "lifecycle": {"$ref": "#/$defs/lifecycle"}}},
    "secretNames": {"type": "object", "additionalProperties": false, "required": ["api", "worker", "frontend"], "properties": {"api": {"$ref": "#/$defs/secretList"}, "worker": {"$ref": "#/$defs/secretList"}, "frontend": {"$ref": "#/$defs/secretList"}}},
    "secretList": {"type": "array", "uniqueItems": true, "items": {"type": "string", "pattern": "^[A-Z][A-Z0-9_]*$"}},
    "rollout": {"type": "object", "additionalProperties": false, "required": ["strategy", "automaticPromotion", "steps", "requiredGates"], "properties": {"strategy": {"const": "gated-sequential"}, "automaticPromotion": {"const": false}, "steps": {"$ref": "#/$defs/nonEmptyStrings"}, "requiredGates": {"$ref": "#/$defs/nonEmptyStrings"}}},
    "rollbackTrigger": {"type": "object", "additionalProperties": false, "required": ["failure", "action"], "properties": {"failure": {"enum": ["migration-failure", "post-migration-api-readiness-failure", "api-health-failure", "worker-health-failure", "frontend-health-failure", "storage-lifecycle-failure", "production-smoke-failure"]}, "action": {"enum": ["halt-only", "application-rollback", "database-restore"]}}},
    "rollback": {"type": "object", "additionalProperties": false, "required": ["automatic", "triggers", "steps", "previousFrontendDeployment", "previousApiArtifact", "previousWorkerImageDigest", "databaseRollbackProcedure"], "properties": {"automatic": {"const": false}, "triggers": {"type": "array", "minItems": 7, "uniqueItems": true, "items": {"$ref": "#/$defs/rollbackTrigger"}}, "steps": {"$ref": "#/$defs/nonEmptyStrings"}, "previousFrontendDeployment": {"$ref": "#/$defs/nullableString"}, "previousApiArtifact": {"$ref": "#/$defs/nullableString"}, "previousWorkerImageDigest": {"$ref": "#/$defs/nullableString"}, "databaseRollbackProcedure": {"$ref": "#/$defs/nullableString"}}},
    "nonEmptyStrings": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
    "unresolved": {"type": "object", "additionalProperties": false, "required": ["path", "owner", "reason"], "properties": {"path": {"type": "string", "pattern": "^/"}, "owner": {"type": "string", "minLength": 1}, "reason": {"type": "string", "minLength": 1}}}
  }
}
