# Schemas

Nickel type contracts defining configuration structure and validation for all services.

## Purpose

Schemas define:
- **Type safety** - Required/optional fields, valid types (string, number, bool, record)
- **Value constraints** - Enum values, numeric bounds (via contracts)
- **Documentation** - Field descriptions and usage patterns
- **Composition** - Inheritance and merging of schema types

## File Organization

```bash
schemas/
├── README.md                           # This file
├── common/                             # Shared schemas (server, database, security, etc.)
│   ├── server.ncl                      # HTTP server configuration schema
│   ├── database.ncl                    # Database backend schema
│   ├── security.ncl                    # Authentication and security schema
│   ├── monitoring.ncl                  # Metrics and health checks schema
│   ├── logging.ncl                     # Log level and format schema
│   ├── network.ncl                     # Network binding and TLS schema
│   ├── storage.ncl                     # Storage backend schema
│   └── workspace.ncl                   # Workspace configuration schema
├── deployment/                         # Mode-specific schemas
│   ├── solo.ncl                        # Solo mode resource constraints
│   ├── multiuser.ncl                   # Multi-user mode schema
│   ├── cicd.ncl                        # CI/CD mode schema
│   └── enterprise.ncl                  # Enterprise HA schema
├── orchestrator.ncl                    # Orchestrator service schema
├── control-center.ncl                  # Control Center service schema
├── mcp-server.ncl                      # MCP Server service schema
└── installer.ncl                       # Installer service schema
```

## Schema Patterns

### 1. Basic Schema Definition

```bash
# schemas/common/server.ncl
{
  Server = {
    host | String,                     # Required string field
    port | Number,                     # Required number field
    workers | Number | default = 4,    # Optional with default
    keep_alive | Number | optional,    # Optional field
    max_connections | Number | optional,
  },
}
```

### 2. Type with Contract Validation

```bash
# With constraint checking (via validators)
{
  WorkerCount =
    let valid_range = fun n =>
      if n < 1 then
        std.contract.blame "Workers must be >= 1" n
      else if n > 32 then
        std.contract.blame "Workers must be <= 32" n
      else
        n
    in
    Number | valid_range,
}
```

### 3. Record Merging (Composition)

```bash
# schemas/orchestrator.ncl
let server_schema = import "./common/server.ncl" in
let database_schema = import "./common/database.ncl" in

{
  OrchestratorConfig = {
    workspace | {
      name | String,
      path | String,
      enabled | Bool | default = true,
    },
    server | server_schema.Server,  # Reuse Server schema
    storage | database_schema.Database,  # Reuse Database schema
    queue | {
      max_concurrent_tasks | Number,
      retry_attempts | Number | default = 3,
    },
  },
}
```

## Common Schemas

### server.ncl
HTTP server configuration:
- `host` - Bind address (string)
- `port` - Listen port (number)
- `workers` - Thread count (number, optional)
- `keep_alive` - Keep-alive timeout (number, optional)
- `max_connections` - Connection limit (number, optional)

### database.ncl
Database backend selection:
- `backend` - 'filesystem | 'rocksdb | 'surrealdb_embedded | 'surrealdb_server | 'postgres (enum)
- `path` - Storage path (string, optional)
- `connection_string` - DB URL (string, optional)
- `credentials` - Auth object (optional)

### security.ncl
Authentication and encryption:
- `jwt_issuer` - JWT issuer (string, optional)
- `jwt_audience` - JWT audience (string, optional)
- `jwt_expiration` - Token expiration (number, optional)
- `encryption_key` - Encryption key (string, optional)
- `kms_backend` - KMS provider (string, optional)
- `mfa_required` - Require MFA (bool, optional)

### monitoring.ncl
Metrics and health:
- `enabled` - Enable monitoring (bool, optional)
- `metrics_interval` - Metrics collection interval (number, optional)
- `health_check_interval` - Health check frequency (number, optional)
- `retention_days` - Metrics retention (number, optional)

### logging.ncl
Log configuration:
- `level` - Log level (debug | info | warn | error)
- `format` - Log format (json | text)
- `rotation` - Log rotation policy (optional)
- `output` - Log destination (stdout | file | syslog)

## Service Schemas

### orchestrator.ncl
Workflow orchestration:

```nickel
OrchestratorConfig = {
  workspace | WorkspaceConfig,
  server | Server,
  storage | Database,
  queue | QueueConfig,
  batch | BatchConfig,
  monitoring | MonitoringConfig | optional,
  rollback | RollbackConfig | optional,
  extensions | ExtensionsConfig | optional,
}
```

### control-center.ncl
Policy and RBAC:

```nickel
ControlCenterConfig = {
  workspace | WorkspaceConfig,
  server | Server,
  database | Database,
  security | SecurityConfig,
  rbac | RBACConfig | optional,
  compliance | ComplianceConfig | optional,
}
```

### mcp-server.ncl
MCP protocol server:

```nickel
MCPServerConfig = {
  workspace | WorkspaceConfig,
  server | Server,
  capabilities | CapabilitiesConfig,
  tools | ToolsConfig | optional,
  resources | ResourcesConfig | optional,
}
```

## Deployment Mode Schemas

Deployment schemas define resource constraints for each mode:

- **solo.ncl** - 2 CPU, 4GB RAM, embedded DB
- **multiuser.ncl** - 4 CPU, 8GB RAM, PostgreSQL
- **cicd.ncl** - 8 CPU, 16GB RAM, ephemeral
- **enterprise.ncl** - 16+ CPU, 32+ GB RAM, HA

Example:

```bash
# schemas/deployment/solo.ncl
{
  SoloMode = {
    resources = {
      cpu_cores | 2,
      memory_mb | 4096,
      disk_gb | 50,
    },
    database_backend | 'filesystem,
    security_level | 'basic,
  },
}
```

## Validation with Schemas

Schemas are composed with validators in config files:

```toml
# configs/orchestrator.solo.ncl
let schemas = import "../schemas/orchestrator.ncl" in
let validators = import "../validators/orchestrator-validator.ncl" in
let defaults = import "../defaults/orchestrator-defaults.ncl" in

# Compose: defaults + validation + schema checking
{
  orchestrator = defaults.orchestrator & {
    queue = {
      max_concurrent_tasks = validators.ValidConcurrentTasks 5,
    },
  },
} | schemas.OrchestratorConfig
```

The final `| schemas.OrchestratorConfig` applies type checking.

## Type System

### Nickel Type Syntax

```nickel
# Required field
field | Type,

# Optional field
field | Type | optional,

# Field with default
field | Type | default = value,

# Union type
field | [| 'option1, 'option2],

# Nested record
field | {
  subfield | Type,
},
```

## Best Practices

1. **Reuse common schemas** - Import and compose rather than duplicate
2. **Use enums for choices** - `'filesystem | 'rocksdb` instead of string validation
3. **Document fields** - Add comments explaining purpose
4. **Keep schemas focused** - Each file covers one logical component
5. **Test composition** - Use `nickel typecheck` to verify schema merging

## Modifying Schemas

When changing a schema:

1. Update schema file (schemas/*.ncl)
2. Update corresponding defaults (defaults/*.ncl) to match schema
3. Update validators if constraints changed
4. Run typecheck: `nickel typecheck configs/orchestrator.*.ncl`
5. Verify all configs still type-check

## Schema Testing

```bash
# Typecheck a schema
nickel typecheck provisioning/.typedialog/provisioning/platform/schemas/orchestrator.ncl

# Typecheck a config (which applies schema)
nickel typecheck provisioning/.typedialog/provisioning/platform/configs/orchestrator.solo.ncl

# Evaluate a schema
nickel eval provisioning/.typedialog/provisioning/platform/schemas/orchestrator.ncl
```

---

**Version**: 1.0.0
**Last Updated**: 2025-01-05
