# Platform Common

Shared utilities for configuration composition and transformation.

## Helper Functions (`helpers.ncl`)

Utility functions for working with configurations:

### `apply_merge(defaults, overrides)`

Merge two configuration records with override support:

```nickel
let helpers = import "common/helpers.ncl" in

let base = {port = 8080, workers = 4}
let overrides = {port = 9001}
let merged = helpers.apply_merge base overrides
# Result: {port = 9001, workers = 4}
```

### `compose_config(schema, mode_defaults, user_customizations)`

Compose final configuration from three layers:

```nickel
let schema = import "../../vapora/main.ncl" in
let defaults = import "../defaults/deployment/solo.ncl" in
let user = {backend.port = 9001}

let final = helpers.compose_config schema defaults user
```

**Composition flow:**
1. Schema (base structure)
2. Mode defaults (mode-specific overrides)
3. User customizations (final overrides)

### `validate_non_empty(field_name, value)`

Validate required field is not empty:

```nickel
let result = helpers.validate_non_empty "jwt_secret" config.security.jwt_secret

if result.valid then
  "OK"
else
  "Error: %{result.error}"
```

### `to_json(config)`

Serialize configuration to JSON:

```nickel
let json_output = helpers.to_json config
```

### `to_toml(config)`

Serialize configuration to TOML-compatible JSON:

```nickel
let toml_compat = helpers.to_toml config
```

## Usage Pattern

```nickel
let helpers = import "schemas/platform/common/helpers.ncl" in
let schema = import "schemas/vapora/main.ncl" in
let defaults = import "schemas/platform/defaults/deployment/multiuser.ncl" in

let config = helpers.compose_config schema defaults {
  backend.port = 9001,
  llm_router.providers.ollama_enabled = true,
}

# Export to JSON
helpers.to_json config
```

## References

- Parent: `../README.md`
- Values: `../values/README.md`
- Defaults: `../defaults/README.md`
