Configuration
Overview
Section titled “Overview”Every intu project is configured through YAML files at the project root and inside channel directories. The root intu.yaml defines runtime behaviour, destinations, storage, logging, and metrics. Each channel has its own channel.yaml that describes a single integration pipeline.
my-project/├── intu.yaml # root config (base profile)├── intu.dev.yaml # dev overrides├── intu.prod.yaml # production overrides└── channels/ └── adt-to-fhir/ └── channel.yaml # channel configProfile Layering
Section titled “Profile Layering”intu supports profile-based configuration layering. At startup the engine loads files in order and deep-merges them:
intu.yaml— base configuration (always loaded)intu.<profile>.yaml— profile overlay (e.g.intu.dev.yaml,intu.prod.yaml)
The active profile is set with the --profile flag or the INTU_PROFILE environment variable:
intu run --profile prod# orINTU_PROFILE=prod intu runKeys in the profile file override the same keys in the base file. Nested maps are merged recursively; arrays are replaced entirely.
Environment Variable Expansion
Section titled “Environment Variable Expansion”Any value in YAML can reference an environment variable with ${VAR} syntax. An optional default is supported with ${VAR:-default}:
destinations: epic: type: http url: ${EPIC_BASE_URL:-https://sandbox.epic.com/api} auth: client_secret: ${EPIC_CLIENT_SECRET}Variables are resolved at startup. A missing variable with no default causes a fatal error.
Root Configuration — intu.yaml
Section titled “Root Configuration — intu.yaml”Runtime Settings
Section titled “Runtime Settings”runtime: mode: standalone # standalone | cluster workers: 4 # concurrent pipeline workers hot_reload: true # watch for config/code changes| Key | Type | Default | Description |
|---|---|---|---|
mode | standalone | cluster | standalone | Single-process or distributed mode |
workers | integer | CPU count | Number of concurrent workers per channel |
hot_reload | boolean | true | Restart affected channels on file change |
Destinations
Section titled “Destinations”Destinations are declared at the root level and referenced by name in channel configs:
destinations: epic_fhir: type: http url: https://fhir.epic.com/R4 auth: type: oauth2_client_credentials token_url: https://fhir.epic.com/oauth2/token client_id: ${EPIC_CLIENT_ID} client_secret: ${EPIC_CLIENT_SECRET} scopes: - system/*.read - system/*.write
warehouse: type: postgres host: ${PG_HOST:-localhost} port: 5432 database: integration_db username: ${PG_USER} password: ${PG_PASSWORD} ssl_mode: require
archive: type: s3 bucket: ${S3_BUCKET} region: us-east-1 prefix: hl7/archive/Each destination has a type and type-specific settings. Supported types include http, tcp, kafka, postgres, s3, file, smtp, sftp, dicom, and database.
Message Storage
Section titled “Message Storage”storage: driver: postgres # memory | postgres | s3 mode: full # none | status | full connection: host: ${PG_HOST:-localhost} port: 5432 database: intu_messages username: ${PG_USER} password: ${PG_PASSWORD}| Mode | Stored Data |
|---|---|
none | Nothing — fire-and-forget |
status | Message ID, status, timestamps, error info |
full | Everything in status plus the complete message body |
Logging
Section titled “Logging”logging: level: info # debug | info | warn | error format: json # json | text transports: - type: console - type: file path: ./logs/intu.log max_size_mb: 100 max_backups: 5 - type: cloudwatch log_group: /intu/prod region: us-east-1 - type: datadog api_key: ${DD_API_KEY} site: datadoghq.com - type: sumologic endpoint: ${SUMO_ENDPOINT} - type: elasticsearch url: ${ES_URL} index: intu-logsMultiple transports can run simultaneously. Each transport inherits the root level unless overridden.
Metrics
Section titled “Metrics”metrics: prometheus: enabled: true port: 9090 path: /metrics opentelemetry: enabled: true endpoint: ${OTEL_ENDPOINT} protocol: grpc # grpc | http service_name: intuChannel Configuration — channel.yaml
Section titled “Channel Configuration — channel.yaml”Each channel directory contains a channel.yaml that defines a single pipeline:
id: adt-to-fhirenabled: truegroup: admissions
listener: type: tcp port: 6661 content_type: hl7v2
transformer: transform.ts
validator: validate.ts
destinations: - epic_fhir - warehouse
retry: max_attempts: 5 backoff: exponential initial_delay_ms: 500 max_delay_ms: 30000 jitter: true
tags: department: admissions priority: high| Key | Required | Description |
|---|---|---|
id | yes | Unique channel identifier |
enabled | no | true (default) or false to disable without deleting |
listener | yes | Inbound connector (type, port, content_type, etc.) |
transformer | no | Path to a TypeScript transformer |
validator | no | Path to a TypeScript validator |
destinations | yes | List of destination names declared in intu.yaml |
retry | no | Retry policy for failed deliveries |
tags | no | Arbitrary key-value metadata for filtering and grouping |
group | no | Logical channel group for batch operations |
Full Example — intu.yaml
Section titled “Full Example — intu.yaml”runtime: mode: standalone workers: 4 hot_reload: true
storage: driver: memory mode: status
logging: level: info format: json transports: - type: console
metrics: prometheus: enabled: true port: 9090 path: /metrics
destinations: epic_fhir: type: http url: ${EPIC_FHIR_URL:-https://sandbox.epic.com/R4} auth: type: oauth2_client_credentials token_url: ${EPIC_TOKEN_URL} client_id: ${EPIC_CLIENT_ID} client_secret: ${EPIC_CLIENT_SECRET}
local_file: type: file path: ./output/ naming: "{{.ChannelID}}_{{.Timestamp}}.json"Full Example — intu.prod.yaml
Section titled “Full Example — intu.prod.yaml”runtime: mode: cluster workers: 8 hot_reload: false
storage: driver: postgres mode: full connection: host: ${PG_HOST} port: 5432 database: intu_prod username: ${PG_USER} password: ${PG_PASSWORD} ssl_mode: require
logging: level: warn format: json transports: - type: console - type: datadog api_key: ${DD_API_KEY} site: datadoghq.com
metrics: prometheus: enabled: true port: 9090 path: /metrics opentelemetry: enabled: true endpoint: ${OTEL_ENDPOINT} protocol: grpc service_name: intu-prod
destinations: epic_fhir: type: http url: ${EPIC_FHIR_URL} auth: type: oauth2_client_credentials token_url: ${EPIC_TOKEN_URL} client_id: ${EPIC_CLIENT_ID} client_secret: ${EPIC_CLIENT_SECRET} scopes: - system/*.read - system/*.writeProfile Layering in Practice
Section titled “Profile Layering in Practice”Given the two files above and --profile prod, the merged result at startup is:
| Key | Base (intu.yaml) | Prod Override | Effective Value |
|---|---|---|---|
runtime.mode | standalone | cluster | cluster |
runtime.workers | 4 | 8 | 8 |
runtime.hot_reload | true | false | false |
storage.driver | memory | postgres | postgres |
storage.mode | status | full | full |
logging.level | info | warn | warn |
metrics.prometheus | enabled | enabled | enabled (merged) |
metrics.opentelemetry | — | enabled | enabled (added) |