Skip to content

Runtime settings — the key catalogue

Purpose: the authoritative catalogue of every runtime setting key — its scope, default, who may edit it, and whether it is a money rule. This is the domain page; the mechanism, resolution order and audit live in the runbook ../runbooks/runtime-settings.md. Audience: AI agents. Status: as of 2026-09-26 — catalogue re-diffed against the api registry on origin/main 171898a4 (PO 2026-09-26: the code is the decision); agreed split: PO 2026-09-19 — ../../backlog/ideation/multi-runtime-settings-flags-inventory.md).

Every key is declared in the typed registry terminales-api/src/core/runtime-settings/settings-registry.ts (built by api #797 + its RuntimeSettings siblings). This catalogue is generated from that file — regenerate it whenever a key is added, removed, or its shape changes. The registry is the source of truth for the exact leaf-key spelling and validating schema; unknown keys are rejected everywhere.

  • Scope — realm = one value per realm; realm + merchant = a realm default that a per-merchant row may override (resolution: merchant override → realm value → code default).
  • Default — the code default, which equals today’s deployed behaviour, so an empty runtime_settings table changes nothing.
  • editableBy — admin (platform operator/admin screens) or owner (merchant owner settings; the owner write admits only editableBy: 'owner' keys, any other → 403).
  • moneyRule — yes if the value is a monetary amount stored and served in integer minor units (×10000). Rates/ratios are exempt even when they govern money.
  • clientVisible — yes if the resolved value may be handed to ordinary store staff (cashiers/supervisors) through the POS effective-settings read; the registry defaults to no.

Diffed key-by-key against terminales-api/src/core/runtime-settings/settings-registry.ts on origin/main 171898a4 (2026-09-26; PO ruling: the code is the decision where this page and the registry disagreed). 27 keys. clientVisible = the resolved value may reach ordinary store staff through the POS effective-settings read (default false).

Key Scope Default editableBy moneyRule clientVisible Notes
reconciliation.allowManualLineFix realm false admin no no Manual fix of an unreadable bank-statement line; consumer ships with the bank-statement import (sub-project 4). The seed key that proves the mechanism.
reconciliation.concentratorClabe realm '' (not configured) admin no yes The single house (concentrador) CLABE every merchant wires deposits to (#852, deposit model “Option A”); merchants are told apart by merchants.depositReference in the concepto. A non-empty value must be an 18-digit CLABE with a valid control digit, else the write is rejected. Client-visible so the deposit-instructions screen can show it.

POS behaviour (← migrated from FEATURE_FLAG_POS_* / refunds)

Section titled “POS behaviour (← migrated from FEATURE_FLAG_POS_* / refunds)”
Key Scope Default editableBy moneyRule clientVisible Notes
pos.shiftRequiredToSell realm + merchant true admin no yes ← FEATURE_FLAG_POS_STAFF_SHIFTS. Admin-only in code since terminales-api #964 (R9 A2, 2026-09-26: a POS sale always requires an open shift; the owner cannot turn it off). Kept only because web + Android still read it; remove it (unconditional guard) under feature-flag minimalism.
pos.shiftTerminalStrict realm + merchant true owner no yes ← FEATURE_FLAG_POS_SHIFT_TERMINAL_STRICT. ON → a sale on another terminal’s shift is a 400 sale_shift_terminal_mismatch; OFF → warn-only.
pos.drawerLockdown realm + merchant true owner no yes ← FEATURE_FLAG_POS_SHIFT_DRAWER_LOCKDOWN.
pos.refundsBeyondSameDay realm + merchant true owner no yes ← FEATURE_FLAG_REFUNDS_BEYOND_SAME_DAY. Also fixes the old plane mismatch (api ON, web profile omitted it).
pos.shiftCloseVarianceTolerance realm + merchant toMinor(50) = 500000 ($50.00) owner yes yes Integer minor units (×10000). ← the hardcoded $50.00 in shift-variance.ts. A store-preference dial, so owner-editable.
onboarding.selfSignupOpen realm true admin no yes ← FEATURE_FLAG_MERCHANT_ONBOARDING. A realm that only provisions merchants centrally turns it off. Realm-only (a signing-up merchant has no row to override).
Key Scope Default editableBy moneyRule clientVisible Notes
vas.billPayDebtLookup realm + merchant true owner no yes ← FEATURE_FLAG_VAS_ADEUDO_LOOKUP. Gates GET /vas/adeudo; OFF → the legacy flag-off response, no upstream call.
vas.fraud.maxAmountPerTransaction realm + merchant 50_000_000 ($5,000.00) admin yes no ← VAS_FRAUD_* (mirrors DEFAULT_VAS_FRAUD_LIMITS). 0 disables the dimension.
vas.fraud.windowMinutes realm + merchant 60 admin no no Window for the store/cashier count + amount limits.
vas.fraud.maxCountPerStore realm + merchant 100 admin no no 0 disables.
vas.fraud.maxAmountPerStore realm + merchant 1_000_000_000 ($100,000.00) admin yes no 0 disables.
vas.fraud.maxCountPerCashier realm + merchant 50 admin no no 0 disables.
vas.fraud.maxAmountPerCashier realm + merchant 500_000_000 ($50,000.00) admin yes no 0 disables.
vas.vendorFloatLowThreshold realm 0 (alert off) admin no no Low vendor-float alert threshold, in the vendor’s native MXN float unit (pesos as the provider reports it), not ledger minor units — hence not a money rule. The key and any UI label must not name the vendor. Realm-only.
Key Scope Default editableBy moneyRule clientVisible Notes
settlement.commissionRate realm + merchant 0.02 admin no no Fractional rate in 0–1 (0.02 = 2 %). ← SETTLEMENT_COMMISSION_RATE. Not a money rule in the registry: it is a ratio, not a minor-units amount (rates are exempt), even though it governs money. Not effective-dated: a report keeps the rate it was computed with; a change affects only the next computation. Negotiated per merchant.
settlement.source realm angelpay_import admin no no Enum angelpay_import | computed_rollup (#828): which pipeline is authoritative for card settlements. Registered inert — nothing reads it yet; the nightly rollup keeps running until the import can replace it. es-MX admin label «Fuente de liquidaciones».
Key Scope Default editableBy moneyRule clientVisible Notes
verification.amlEnabled realm false admin no no ← VERIFICATION_AML_ENABLED. Whether the aml check counts toward the required set.
verification.currentTermsVersion realm '2026-08' admin no no ← CURRENT_TERMS_VERSION (mirrors DEFAULT_TERMS_VERSION). Bumping it makes merchants re-accept (terms → lapsed on the next recompute).
verification.validityMonths realm 24 admin no no Identity-mirror validity window, in calendar months.
verification.expiringWindowDays realm 30 admin no no Days ahead the daily sweep flags an identity as expiring soon.
merchant.unverifiedCanOperate realm only false admin no no The unverified-merchant policy switch. false = policy B (set up, 1 store / 1 terminal, no selling/shifts/cash movements/invites); true = policy A (operate from day one; money-out still gated). A merchant-scoped write is rejected (422) and ignored at read; an unreadable value fails closed to false. Clients read GET /pos/merchants/:id/capabilities instead. See merchant-verification-policy.md.

Module enablement (← per-merchant commercial package / staged onboarding)

Section titled “Module enablement (← per-merchant commercial package / staged onboarding)”
Key Scope Default editableBy moneyRule clientVisible Notes
modules.wallet realm + merchant true admin no no Wallet + deposits + transfers. Disabled ⇒ new ops refused 403 module_disabled (ModuleEnablementService); history reads stay allowed; in-flight work is not cancelled.
modules.vas realm + merchant true admin no no VAS sales.
modules.cardPayments realm + merchant true admin no no Card tender / payment intents.
modules.settlements realm + merchant true admin no no Liquidaciones.
  • Deploy-time env (integration wiring, build/dev toggles, security constants) — see the runbook §“What stays deploy-time env”. These are not editable at runtime.
  • Removed flags — always-ON flags hard-wired ON (e.g. MERCHANT_WALLET, SETTLEMENT_UNIFIED, web WRITE_GATEWAY) and dead/zero-reader flags deleted outright. FEATURE_FLAG_MERCHANT_WALLET_DEPOSITS is the one survivor (switchable until money-in reconciliation ships) and is not a runtime setting.