# Schemas\n\nNickel type contracts defining configuration structure and validation for all services.\n\n## Purpose\n\nSchemas define:\n- **Type safety** - Required/optional fields, valid types (string, number, bool, record)\n- **Value constraints** - Enum values, numeric bounds (via contracts)\n- **Documentation** - Field descriptions and usage patterns\n- **Composition** - Inheritance and merging of schema types\n\n## File Organization\n\n```\nschemas/\n├── README.md                           # This file\n├── common/                             # Shared schemas (server, database, security, etc.)\n│   ├── server.ncl                      # HTTP server configuration schema\n│   ├── database.ncl                    # Database backend schema\n│   ├── security.ncl                    # Authentication and security schema\n│   ├── monitoring.ncl                  # Metrics and health checks schema\n│   ├── logging.ncl                     # Log level and format schema\n│   ├── network.ncl                     # Network binding and TLS schema\n│   ├── storage.ncl                     # Storage backend schema\n│   └── workspace.ncl                   # Workspace configuration schema\n├── deployment/                         # Mode-specific schemas\n│   ├── solo.ncl                        # Solo mode resource constraints\n│   ├── multiuser.ncl                   # Multi-user mode schema\n│   ├── cicd.ncl                        # CI/CD mode schema\n│   └── enterprise.ncl                  # Enterprise HA schema\n├── orchestrator.ncl                    # Orchestrator service schema\n├── control-center.ncl                  # Control Center service schema\n├── mcp-server.ncl                      # MCP Server service schema\n└── installer.ncl                       # Installer service schema\n```\n\n## Schema Patterns\n\n### 1. Basic Schema Definition\n\n```\n# schemas/common/server.ncl\n{\n  Server = {\n    host | String,                     # Required string field\n    port | Number,                     # Required number field\n    workers | Number | default = 4,    # Optional with default\n    keep_alive | Number | optional,    # Optional field\n    max_connections | Number | optional,\n  },\n}\n```\n\n### 2. Type with Contract Validation\n\n```\n# With constraint checking (via validators)\n{\n  WorkerCount =\n    let valid_range = fun n =>\n      if n < 1 then\n        std.contract.blame "Workers must be >= 1" n\n      else if n > 32 then\n        std.contract.blame "Workers must be <= 32" n\n      else\n        n\n    in\n    Number | valid_range,\n}\n```\n\n### 3. Record Merging (Composition)\n\n```\n# schemas/orchestrator.ncl\nlet server_schema = import "./common/server.ncl" in\nlet database_schema = import "./common/database.ncl" in\n\n{\n  OrchestratorConfig = {\n    workspace | {\n      name | String,\n      path | String,\n      enabled | Bool | default = true,\n    },\n    server | server_schema.Server,  # Reuse Server schema\n    storage | database_schema.Database,  # Reuse Database schema\n    queue | {\n      max_concurrent_tasks | Number,\n      retry_attempts | Number | default = 3,\n    },\n  },\n}\n```\n\n## Common Schemas\n\n### server.ncl\nHTTP server configuration:\n- `host` - Bind address (string)\n- `port` - Listen port (number)\n- `workers` - Thread count (number, optional)\n- `keep_alive` - Keep-alive timeout (number, optional)\n- `max_connections` - Connection limit (number, optional)\n\n### database.ncl\nDatabase backend selection:\n- `backend` - 'filesystem | 'rocksdb | 'surrealdb_embedded | 'surrealdb_server | 'postgres (enum)\n- `path` - Storage path (string, optional)\n- `connection_string` - DB URL (string, optional)\n- `credentials` - Auth object (optional)\n\n### security.ncl\nAuthentication and encryption:\n- `jwt_issuer` - JWT issuer (string, optional)\n- `jwt_audience` - JWT audience (string, optional)\n- `jwt_expiration` - Token expiration (number, optional)\n- `encryption_key` - Encryption key (string, optional)\n- `kms_backend` - KMS provider (string, optional)\n- `mfa_required` - Require MFA (bool, optional)\n\n### monitoring.ncl\nMetrics and health:\n- `enabled` - Enable monitoring (bool, optional)\n- `metrics_interval` - Metrics collection interval (number, optional)\n- `health_check_interval` - Health check frequency (number, optional)\n- `retention_days` - Metrics retention (number, optional)\n\n### logging.ncl\nLog configuration:\n- `level` - Log level (debug | info | warn | error)\n- `format` - Log format (json | text)\n- `rotation` - Log rotation policy (optional)\n- `output` - Log destination (stdout | file | syslog)\n\n## Service Schemas\n\n### orchestrator.ncl\nWorkflow orchestration:\n\n```\nOrchestratorConfig = {\n  workspace | WorkspaceConfig,\n  server | Server,\n  storage | Database,\n  queue | QueueConfig,\n  batch | BatchConfig,\n  monitoring | MonitoringConfig | optional,\n  rollback | RollbackConfig | optional,\n  extensions | ExtensionsConfig | optional,\n}\n```\n\n### control-center.ncl\nPolicy and RBAC:\n\n```\nControlCenterConfig = {\n  workspace | WorkspaceConfig,\n  server | Server,\n  database | Database,\n  security | SecurityConfig,\n  rbac | RBACConfig | optional,\n  compliance | ComplianceConfig | optional,\n}\n```\n\n### mcp-server.ncl\nMCP protocol server:\n\n```\nMCPServerConfig = {\n  workspace | WorkspaceConfig,\n  server | Server,\n  capabilities | CapabilitiesConfig,\n  tools | ToolsConfig | optional,\n  resources | ResourcesConfig | optional,\n}\n```\n\n## Deployment Mode Schemas\n\nDeployment schemas define resource constraints for each mode:\n\n- **solo.ncl** - 2 CPU, 4GB RAM, embedded DB\n- **multiuser.ncl** - 4 CPU, 8GB RAM, PostgreSQL\n- **cicd.ncl** - 8 CPU, 16GB RAM, ephemeral\n- **enterprise.ncl** - 16+ CPU, 32+ GB RAM, HA\n\nExample:\n\n```\n# schemas/deployment/solo.ncl\n{\n  SoloMode = {\n    resources = {\n      cpu_cores | 2,\n      memory_mb | 4096,\n      disk_gb | 50,\n    },\n    database_backend | 'filesystem,\n    security_level | 'basic,\n  },\n}\n```\n\n## Validation with Schemas\n\nSchemas are composed with validators in config files:\n\n```\n# configs/orchestrator.solo.ncl\nlet schemas = import "../schemas/orchestrator.ncl" in\nlet validators = import "../validators/orchestrator-validator.ncl" in\nlet defaults = import "../defaults/orchestrator-defaults.ncl" in\n\n# Compose: defaults + validation + schema checking\n{\n  orchestrator = defaults.orchestrator & {\n    queue = {\n      max_concurrent_tasks = validators.ValidConcurrentTasks 5,\n    },\n  },\n} | schemas.OrchestratorConfig\n```\n\nThe final `| schemas.OrchestratorConfig` applies type checking.\n\n## Type System\n\n### Nickel Type Syntax\n\n```\n# Required field\nfield | Type,\n\n# Optional field\nfield | Type | optional,\n\n# Field with default\nfield | Type | default = value,\n\n# Union type\nfield | [| 'option1, 'option2],\n\n# Nested record\nfield | {\n  subfield | Type,\n},\n```\n\n## Best Practices\n\n1. **Reuse common schemas** - Import and compose rather than duplicate\n2. **Use enums for choices** - `'filesystem | 'rocksdb` instead of string validation\n3. **Document fields** - Add comments explaining purpose\n4. **Keep schemas focused** - Each file covers one logical component\n5. **Test composition** - Use `nickel typecheck` to verify schema merging\n\n## Modifying Schemas\n\nWhen changing a schema:\n\n1. Update schema file (schemas/*.ncl)\n2. Update corresponding defaults (defaults/*.ncl) to match schema\n3. Update validators if constraints changed\n4. Run typecheck: `nickel typecheck configs/orchestrator.*.ncl`\n5. Verify all configs still type-check\n\n## Schema Testing\n\n```\n# Typecheck a schema\nnickel typecheck provisioning/.typedialog/provisioning/platform/schemas/orchestrator.ncl\n\n# Typecheck a config (which applies schema)\nnickel typecheck provisioning/.typedialog/provisioning/platform/configs/orchestrator.solo.ncl\n\n# Evaluate a schema\nnickel eval provisioning/.typedialog/provisioning/platform/schemas/orchestrator.ncl\n```\n\n---\n\n**Version**: 1.0.0\n**Last Updated**: 2025-01-05
