rototo
Examples

Example: Manage Tenant Exceptions Without App Branches

This example models a tenant exception as reviewed runtime configuration instead of a special case in application code.

Use this pattern when a small number of tenants or account classes need different runtime configuration, and those exceptions should be reviewed, tested, and observable.

Production problem

Most tenants use the standard search backend. A named enterprise tenant uses a dedicated backend with a higher timeout.

The application resolves:

search-config

and passes tenant facts as context.

Workspace shape

config/
  rototo-workspace.toml
  schemas/
    context.schema.json
    search-config.schema.json
  qualifiers/
    acme-enterprise-tenant.toml
  variables/
    search-config.toml

Runtime context

{
  "tenant": {
    "id": "acme",
    "plan": "enterprise"
  }
}

Use opaque tenant ids or stable account ids. Do not put sensitive tenant metadata in context unless the application already treats it as safe telemetry.

Qualifier

Create qualifiers/acme-enterprise-tenant.toml:

schema_version = 1

[qualifier]
description = "Acme enterprise tenant"

[[qualifier.predicate]]
attribute = "tenant.id"
op = "eq"
value = "acme"

[[qualifier.predicate]]
attribute = "tenant.plan"
op = "eq"
value = "enterprise"

This keeps the tenant exception visible in the workspace instead of buried in application conditionals.

Variable

Create variables/search-config.toml:

schema_version = 1

[variable]
description = "Search backend settings"
schema = "../schemas/search-config.schema.json"

[variable.values.standard]
backend = "shared-search"
timeout_ms = 1500

[variable.values.acme]
backend = "acme-dedicated-search"
timeout_ms = 3000

[variable.env._]
value = "standard"

[variable.env.prod]
value = "standard"

[[variable.env.prod.rule]]
description = "Acme uses a dedicated production search backend"
qualifier = "acme-enterprise-tenant"
value = "acme"

Verify the behavior

rototo variable resolve search-config \
  --workspace config/ \
  --env prod \
  --context '{"tenant":{"id":"acme","plan":"enterprise"}}' \
  --json

Expected selected key:

acme

Tests to keep

Test the named tenant and at least one ordinary tenant. If the tenant exception is production-only, also test that non-production environments do not select the dedicated backend unless intended.

Fit

Use this for explicit, reviewed tenant exceptions or account-class behavior.

Do not use this to encode a large tenant database in configuration. rototo should select runtime behavior, not replace application data storage.

Related docs