{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://dirac-uxi.local/schemas/crud-intent.schema.json",
  "title": "CRUD Site Intent",
  "description": "Machine-readable intent contract for CRUD-family and Metric-family operational application sites",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "siteKey",
    "siteFamily",
    "siteName",
    "siteTagline",
    "appUrl",
    "devPort",
    "packageName",
    "auth",
    "dataSources",
    "navigation",
    "pages"
  ],
  "properties": {
    "siteKey": { "type": "string", "minLength": 1 },
    "siteFamily": { "type": "string", "enum": ["crud", "metric"] },
    "siteName": { "type": "string", "minLength": 1 },
    "siteTagline": { "type": "string", "minLength": 1 },
    "appUrl": { "type": "string", "minLength": 1 },
    "devPort": { "type": "integer", "minimum": 1 },
    "packageName": { "type": "string", "minLength": 1 },
    "auth": {
      "type": "object",
      "additionalProperties": false,
      "required": ["provider", "storage", "tokenKey", "loginEndpoint", "roles"],
      "properties": {
        "provider": { "type": "string", "enum": ["jwt"] },
        "storage": { "type": "string", "enum": ["localStorage", "sessionStorage", "cookie"] },
        "tokenKey": { "type": "string", "minLength": 1 },
        "loginEndpoint": { "type": "string", "minLength": 1 },
        "roles": {
          "type": "array",
          "minItems": 1,
          "items": { "type": "string", "minLength": 1 },
          "description": "Authoritative list of role names exactly as they appear in the JWT roleName claim. Used as the vocabulary for allowedRoles in navigation and pages."
        }
      }
    },
    "dataSources": {
      "type": "object",
      "additionalProperties": false,
      "required": ["graphqlUrl"],
      "properties": {
        "graphqlUrl": { "type": "string", "minLength": 1 },
        "restApiUrl": { "type": "string", "minLength": 1 },
        "dashApiUrl": { "type": "string", "minLength": 1 }
      }
    },
    "navigation": {
      "type": "object",
      "additionalProperties": false,
      "required": ["sidebar"],
      "properties": {
        "sidebar": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/navItem" }
        }
      }
    },
    "pages": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/$defs/page"
      }
    }
  },
  "$defs": {
    "navItem": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name"],
      "properties": {
        "name": { "type": "string", "minLength": 1 },
        "href": { "type": "string", "minLength": 1 },
        "icon": { "type": "string" },
        "menuId": {
          "type": "string",
          "description": "Permission identifier checked at runtime against the role's permission map (e.g. canViewMenu(menuId))."
        },
        "allowedRoles": {
          "type": "array",
          "items": { "type": "string", "minLength": 1 },
          "description": "Whitelist of role names from auth.roles that may see this nav item. Omit for visible to all authenticated roles."
        },
        "children": {
          "type": "array",
          "items": { "$ref": "#/$defs/navItem" }
        }
      }
    },
    "page": {
      "type": "object",
      "additionalProperties": false,
      "required": ["theme", "pageFamily"],
      "properties": {
        "theme": { "type": "string", "minLength": 1 },
        "pageFamily": {
          "type": "string",
          "enum": ["crud", "metric", "auth", "onboarding"]
        },
        "route": {
          "type": "string",
          "minLength": 1,
          "description": "Canonical URL path for this page, including dynamic segments like [id] or [...token]."
        },
        "allowedRoles": {
          "type": "array",
          "items": { "type": "string", "minLength": 1 },
          "description": "Whitelist of role names allowed to access the page. Omit for all authenticated roles. Auth-family pages omit this (public)."
        },
        "props": { "type": "object" }
      }
    }
  }
}
