2026-01-11 22:35:49 +00:00
..
2026-01-11 22:35:49 +00:00

Mode B: Config File Specification

This example shows provisioning generation from a declarative TOML configuration file.

Use Cases

Mode B is ideal when:

  • You don't have a Cargo.toml to analyze (e.g., Python, Go services)
  • You want complete control over feature definitions
  • You're designing configuration before implementation
  • You need custom fields not automatically detected
  • You're configuring existing services with different tech stacks

Configuration Structure

The project-spec.toml file has three main sections:

1. Project Metadata

[project]
name = "service-name"
description = "What this service does"
type = "Microservice"  # WebService, CliTool, Microservice, Library
```text

### 2. Infrastructure Requirements
```toml
[infrastructure]
ssh = true
monitoring = ["prometheus", "grafana"]
cloud_providers = ["aws", "gcp"]

[[infrastructure.databases]]
type = "postgres"
required = true
```text

### 3. Domain Features
Each feature represents a functional capability:

```toml
[features.my_feature]
description = "What this feature does"
enabled = true

[[features.my_feature.fields]]
name = "field_name"
type = "Text"              # Text, Number, Password, Confirm, Select, etc.
prompt = "User prompt"
default = "default_value"
help = "Helpful text"
required = true
sensitive = false          # Set to true for passwords/secrets
encryption_backend = "age" # For sensitive fields
min = 1                    # For numbers/arrays
max = 100
options = ["a", "b"]       # For Select/MultiSelect
```text

### 4. Constraints (Single Source of Truth)
```toml
[constraints.feature_name.field_name]
min = 1
max = 100
min_length = 5
max_length = 255
```text

## Running the Example

### Generate Provisioning Structure
```bash
typedialog-provisioning-gen config \
  --input examples/11-provisioning-generation/mode-b-config/project-spec.toml \
  --output /tmp/microservice-platform
```text

### Inspect Generated Files
```bash
# View master configuration
cat /tmp/microservice-platform/config.ncl

# View API gateway schema
cat /tmp/microservice-platform/schemas/api_gateway.ncl

# View authentication fragment
cat /tmp/microservice-platform/fragments/authentication-section.toml

# Validate constraints
cat /tmp/microservice-platform/constraints.toml
```text

### Test Forms Interactively
```bash
# Test API gateway configuration form
typedialog /tmp/microservice-platform/fragments/api_gateway-section.toml --backend cli

# Test authentication configuration form
typedialog /tmp/microservice-platform/fragments/authentication-section.toml --backend cli
```text

### Use Generated Scripts
```bash
cd /tmp/microservice-platform

# Validate Nickel syntax
./scripts/validate-nickel.sh

# Create Nickel from JSON input
echo '{"api_gateway": {"bind_address": "0.0.0.0:8080"}}' | \
  ./scripts/json-to-nickel.sh

# Convert back to JSON
./scripts/nickel-to-json.sh < config.ncl
```text

## Features Defined in This Example

### 1. API Gateway
- **Purpose**: REST API entry point with rate limiting
- **Fields**:
  - `bind_address` - Interface and port
  - `rate_limit` - Requests per second
  - `timeout_seconds` - Request timeout

**Generated Output**:
- Schema: `schemas/api_gateway.ncl` - Type contract
- Validator: `validators/api_gateway.ncl` - Validation rules
- Defaults: `defaults/api_gateway.ncl` - Default values
- Fragment: `fragments/api_gateway-section.toml` - UI form

### 2. Event Streaming
- **Purpose**: Message queue for event-driven architecture
- **Fields**:
  - `broker_url` - Message broker connection
  - `consumer_group` - Kafka consumer group ID
  - `max_concurrent_consumers` - Parallelism

### 3. Authentication
- **Purpose**: JWT-based access control
- **Fields**:
  - `jwt_secret` - Sensitive signing key (encrypted)
  - `jwt_expiry_hours` - Token lifetime
  - `allow_refresh_tokens` - Refresh mechanism

### 4. Observability
- **Purpose**: Logging and distributed tracing
- **Fields**:
  - `log_level` - Trace/Debug/Info/Warn/Error
  - `enable_distributed_tracing` - Toggle tracing
  - `trace_sample_rate` - Sampling percentage

### 5. Database Migrations
- **Purpose**: Schema versioning and evolution
- **Fields**:
  - `migration_directory` - Path to SQL files
  - `auto_migrate_on_startup` - Automatic migrations

## Field Types Reference

| Type | Use Case | Example |
|---|---|---|
| **Text** | Free-form string | domain.example.com |
| **Number** | Integer or float | 8080, 0.5 |
| **Password** | Sensitive text | secret key (encrypted) |
| **Confirm** | Yes/No toggle | Enable feature? |
| **Select** | Single choice | Log level: debug, info, warn |
| **MultiSelect** | Multiple choices | Monitoring: prometheus, grafana |
| **Editor** | Multi-line code | SQL migration script |
| **Date** | Calendar picker | Deployment date |
| **RepeatingGroup** | Array of items | Multiple database servers |

## Sensitive Fields

Mark fields as sensitive for encryption:

```toml
[[features.authentication.fields]]
name = "jwt_secret"
type = "Password"
sensitive = true
encryption_backend = "age"  # Default: age
```text

**Supported backends**:
- `age` - Modern encryption (recommended)
- `sops` - Mozilla SOPS
- `secretumvault` - SecretumVault integration
- `aws-kms` - AWS Key Management Service
- `gcp-kms` - Google Cloud KMS
- `azure-kms` - Azure Key Vault

## Constraints System

Constraints provide a single source of truth for validation bounds:

```toml
[constraints.api_gateway.bind_address]
min_length = 3
max_length = 50

[constraints.api_gateway.rate_limit]
min = 1
max = 10000
```text

These constraints are:
- Used in TypeDialog forms (enforced client-side)
- Referenced in validators (Nickel validation)
- Available in fragments (UI constraints)
- Documented in generated schema

## Extending This Example

### Add a New Feature
1. Add to `project-spec.toml`:
   ```toml
   [features.caching]
   description = "Redis caching layer"

   [[features.caching.fields]]
   name = "redis_url"
   type = "Text"
   prompt = "Redis connection string"
  1. Regenerate:

    typedialog-provisioning-gen config --input project-spec.toml --output ./output
    
  2. Generated files appear:

    • schemas/caching.ncl
    • validators/caching.ncl
    • defaults/caching.ncl
    • fragments/caching-section.toml

Customize a Field

  1. Modify the field definition
  2. Update constraints if needed
  3. Regenerate

The regeneration merges with existing configuration, making it safe to iterate.

What This Demonstrates

Complete feature definition without code Type safety through Nickel contracts Constraint interpolation (single source of truth) Multi-language field options (Select, MultiSelect) Sensitive data encryption configuration Infrastructure requirements specification Full 7-layer validation stack generation

Next Steps

  1. Copy and Customize: Use this as a template for your service
  2. Add Your Features: Define the capabilities your service provides
  3. Generate: Run provisioning-gen to create artifacts
  4. Test: Use TypeDialog forms to validate configuration
  5. Deploy: Use generated scripts for orchestration
  6. Iterate: Modify spec and regenerate as needed

Integration with Application

Once generated, import Nickel schemas in your app:

# config.ncl
let infrastructure = import "schemas/database.ncl"
let auth = import "schemas/authentication.ncl"

{
  database = {
    %host% = "localhost",
    port = 5432,
  } | infrastructure.Database,

  authentication = auth.Authentication,
}
```text

Or deserialize from JSON:

```bash
# Load configuration from TypeDialog form output
./scripts/json-to-nickel.sh < form-output.json > config.ncl

# Validate against schema
nickel eval config.ncl

# Export to application
./scripts/nickel-to-json.sh < config.ncl > config.json
```text