# Fragments

Reusable form fragments organized FLAT in this directory (not nested subdirectories).

## Purpose

Fragments provide:
- **Reusable sections** - Used by multiple forms
- **Modularity** - Change once, applies to all forms using it
- **Organization** - Named by purpose (workspace, server, queue, etc.)
- **DRY principle** - Don't repeat configuration sections

## Fragment Organization

**CRITICAL**: All fragments are stored at the SAME LEVEL (flat directory).

```toml
fragments/
├── workspace-section.toml              # Workspace configuration
├── server-section.toml                 # HTTP server settings
├── database-rocksdb-section.toml       # RocksDB database
├── database-surrealdb-section.toml     # SurrealDB database
├── database-postgres-section.toml      # PostgreSQL database
├── security-section.toml               # Auth, RBAC, encryption
├── monitoring-section.toml             # Metrics, health checks
├── logging-section.toml                # Log configuration
├── orchestrator-queue-section.toml     # Orchestrator queue config
├── orchestrator-workflow-section.toml  # Orchestrator batch workflow
├── orchestrator-storage-section.toml   # Orchestrator storage backend
├── control-center-jwt-section.toml     # Control Center JWT
├── control-center-rbac-section.toml    # Control Center RBAC
├── control-center-compliance-section.toml
├── mcp-capabilities-section.toml       # MCP capabilities
├── mcp-tools-section.toml              # MCP tools configuration
├── mcp-resources-section.toml          # MCP resource limits
├── deployment-mode-section.toml        # Deployment mode selection
├── resources-section.toml              # Resource allocation (CPU, RAM, disk)
└── README.md                           # This file
```

Referenced in forms as:
```toml
[[items]]
name = "workspace_group"
type = "group"
includes = ["fragments/workspace-section.toml"]  # Flat reference

[[items]]
name = "queue_group"
type = "group"
includes = ["fragments/orchestrator-queue-section.toml"]  # Same level
```

## Fragment Categories

### Common Fragments (Used by Multiple Services)

- **workspace-section.toml** - Workspace name, path, enable/disable
- **server-section.toml** - HTTP server host, port, workers, keep-alive
- **database-rocksdb-section.toml** - RocksDB path (filesystem-backed)
- **database-surrealdb-section.toml** - SurrealDB embedded (no external service)
- **database-postgres-section.toml** - PostgreSQL server connection
- **security-section.toml** - JWT issuer, RBAC, encryption keys
- **monitoring-section.toml** - Metrics interval, health checks
- **logging-section.toml** - Log level, format, rotation
- **resources-section.toml** - CPU cores, memory, disk allocation
- **deployment-mode-section.toml** - Solo/MultiUser/CI/CD/Enterprise selection

### Service-Specific Fragments

**Orchestrator** (workflow engine):
- **orchestrator-queue-section.toml** - Max concurrent tasks, retries, timeout
- **orchestrator-workflow-section.toml** - Batch workflow settings, parallelism
- **orchestrator-storage-section.toml** - Storage backend selection

**Control Center** (policy/RBAC):
- **control-center-jwt-section.toml** - JWT issuer, audience, token expiration
- **control-center-rbac-section.toml** - Roles, permissions, policies
- **control-center-compliance-section.toml** - SOC2, HIPAA, audit logging

**MCP Server** (protocol):
- **mcp-capabilities-section.toml** - Tools, prompts, resources, sampling
- **mcp-tools-section.toml** - Tool timeout, max concurrent, categories
- **mcp-resources-section.toml** - Max size, caching, TTL

## Fragment Structure

Each fragment is a TOML file containing `[[elements]]` definitions:

```toml
# fragments/workspace-section.toml

[[elements]]
border_top = true
border_bottom = true
name = "workspace_header"
title = "🗂️ Workspace Configuration"
type = "section_header"

[[elements]]
name = "workspace_name"
type = "text"
prompt = "Workspace Name"
default = "default"
required = true
help = "Name of the workspace this service will serve"
nickel_path = ["orchestrator", "workspace", "name"]

[[elements]]
name = "workspace_path"
type = "text"
prompt = "Workspace Path"
default = "/var/lib/provisioning/orchestrator"
required = true
help = "Absolute path to the workspace directory"
nickel_path = ["orchestrator", "workspace", "path"]

[[elements]]
name = "workspace_enabled"
type = "confirm"
prompt = "Enable Workspace?"
default = true
help = "Enable or disable this workspace"
nickel_path = ["orchestrator", "workspace", "enabled"]
```

## Fragment Composition

Fragments are included in main forms:

```toml
# forms/orchestrator-form.toml

name = "orchestrator_configuration"
description = "Interactive configuration for Orchestrator"

# Include fragments in order

[[items]]
name = "deployment_group"
type = "group"
includes = ["fragments/deployment-mode-section.toml"]

[[items]]
name = "workspace_group"
type = "group"
includes = ["fragments/workspace-section.toml"]

[[items]]
name = "server_group"
type = "group"
includes = ["fragments/server-section.toml"]

[[items]]
name = "storage_group"
type = "group"
includes = ["fragments/orchestrator-storage-section.toml"]

[[items]]
name = "queue_group"
type = "group"
includes = ["fragments/orchestrator-queue-section.toml"]

# Optional sections
[[items]]
name = "monitoring_group"
type = "group"
when = "enable_monitoring == true"
includes = ["fragments/monitoring-section.toml"]
```

## Element Requirements

Every element in a fragment MUST include:

1. **name** - Unique identifier (used in form data)
2. **type** - Element type (text, number, confirm, select, etc.)
3. **prompt** - User-facing label
4. **nickel_path** - Mapping to Nickel structure (**CRITICAL**)

Example:
```toml
[[elements]]
name = "max_concurrent_tasks"          # Unique identifier
type = "number"                        # Type
prompt = "Maximum Concurrent Tasks"    # User label
nickel_path = ["orchestrator", "queue", "max_concurrent_tasks"]  # Nickel mapping
```

## Constraint Interpolation

Fragments reference constraints dynamically:

```toml
[[elements]]
name = "max_concurrent_tasks"
type = "number"
prompt = "Maximum Concurrent Tasks"
min = "${constraint.orchestrator.queue.concurrent_tasks.min}"  # Dynamic
max = "${constraint.orchestrator.queue.concurrent_tasks.max}"  # Dynamic
nickel_path = ["orchestrator", "queue", "max_concurrent_tasks"]
```

The `${constraint.path.to.value}` syntax references `constraints/constraints.toml`.

## Common Fragment Patterns

### Workspace Fragment Pattern
```toml
[[elements]]
name = "workspace_name"
type = "text"
prompt = "Workspace Name"
nickel_path = ["orchestrator", "workspace", "name"]

[[elements]]
name = "workspace_path"
type = "text"
prompt = "Workspace Path"
nickel_path = ["orchestrator", "workspace", "path"]

[[elements]]
name = "workspace_enabled"
type = "confirm"
prompt = "Enable Workspace?"
nickel_path = ["orchestrator", "workspace", "enabled"]
```

### Server Fragment Pattern
```toml
[[elements]]
name = "server_host"
type = "text"
prompt = "Server Host"
default = "127.0.0.1"
nickel_path = ["orchestrator", "server", "host"]

[[elements]]
name = "server_port"
type = "number"
prompt = "Server Port"
min = "${constraint.common.server.port.min}"
max = "${constraint.common.server.port.max}"
nickel_path = ["orchestrator", "server", "port"]

[[elements]]
name = "server_workers"
type = "number"
prompt = "Worker Threads"
min = 1
max = 32
nickel_path = ["orchestrator", "server", "workers"]
```

### Database Selection Pattern
```toml
[[elements]]
name = "storage_backend"
type = "select"
prompt = "Storage Backend"
options = [
  { value = "filesystem", label = "📁 Filesystem" },
  { value = "rocksdb", label = "🗄️ RocksDB (Embedded)" },
  { value = "surrealdb", label = "📊 SurrealDB" },
  { value = "postgres", label = "🐘 PostgreSQL" },
]
nickel_path = ["orchestrator", "storage", "backend"]

[[elements]]
name = "rocksdb_group"
type = "group"
when = "storage_backend == 'rocksdb'"
includes = ["fragments/database-rocksdb-section.toml"]

[[elements]]
name = "postgres_group"
type = "group"
when = "storage_backend == 'postgres'"
includes = ["fragments/database-postgres-section.toml"]

[[elements]]
name = "surrealdb_group"
type = "group"
when = "storage_backend == 'surrealdb'"
includes = ["fragments/database-surrealdb-section.toml"]
```

## Best Practices

1. **Clear naming** - Fragment name describes its purpose (queue-section, not qs)
2. **Meaningful headers** - Each fragment starts with a section header (name, title, emoji)
3. **Constraint interpolation** - Use `${constraint.*}` for dynamic validation
4. **Consistent nickel_path** - Paths match actual Nickel structure
5. **Provide defaults** - Sensible defaults improve UX
6. **Help text** - Explain each field clearly
7. **Group logically** - Related fields in same fragment
8. **Test with form** - Verify fragment loads correctly in form

## Adding a New Fragment

1. **Create fragment file** in `forms/fragments/{name}-section.toml`
2. **Add section header** (name, title, emoji)
3. **Add form elements**:
   - Include `name`, `type`, `prompt`
   - Add `nickel_path` (CRITICAL)
   - Add constraints if applicable
   - Add `help` and `default` if appropriate
4. **Include in form** - Add to main form via `includes` field
5. **Test** - Run configuration wizard to verify fragment loads

## Fragment Naming Convention

- **Section fragments**: `{topic}-section.toml` (workspace-section.toml)
- **Service-specific**: `{service}-{topic}-section.toml` (orchestrator-queue-section.toml)
- **Database-specific**: `database-{backend}-section.toml` (database-postgres-section.toml)
- **Deployment-specific**: `{mode}-{topic}-section.toml` (enterprise-options-section.toml)

## Testing Fragments

```toml
# Validate form that uses fragment
nu provisioning/.typedialog/provisioning/platform/scripts/configure.nu orchestrator solo --backend web

# Verify constraint interpolation works
grep "constraint\." forms/fragments/*.toml

# Check nickel_path consistency
grep "nickel_path" forms/fragments/*.toml | sort
```

---

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