Product configuration panel¶
| ID | MOD-127 |
| System | SD08 |
| Repo | bank-app |
| Build status | Deployed |
| Deployed | Yes |
| Last commit | bc8ae27c9ecc660c7eb59e321a9936d2a0c54463 |
Purpose¶
Provides back-office and product management staff with a governed interface for configuring product terms — interest rates, fee schedules, eligibility thresholds, and product-level feature flags. All changes require a four-eyes (maker/checker) approval before taking effect and are subject to a disclosure gate that prevents unfavourable changes reaching customers before required notification has been dispatched.
Compliance rationale¶
Under the Fair Dealing provisions of the Financial Markets Conduct Act (NZ) and the Australian Securities and Investments Commission Act, banks must provide customers with prior notice of changes to key terms and conditions — typically 14 days minimum for retail customers. This module makes compliance with that obligation a technical constraint, not a process obligation: an unfavourable rate or fee change simply cannot take effect until MOD-063 confirms that all affected customers have received the required notification.
Two-person authorisation is a standard operational risk control required under bank prudential standards (RBNZ/APRA). The maker/checker constraint prevents a single operator — whether acting negligently or maliciously — from making unauthorised changes to product configuration that could affect customer charges, eligibility criteria, or rate terms.
Commercial rationale¶
Product managers need agility to respond to competitive rate movements and regulatory changes. A governed self-service panel — rather than ticketed engineering changes — lets product, compliance, and pricing teams manage configuration within a controlled environment without requiring developer involvement for routine adjustments.
Configuration scope¶
This module controls the following configurable parameters per product (identified by product_id and jurisdiction):
| Parameter type | Examples |
|---|---|
| Interest rates | Variable base rate, fixed rate tiers, introductory rate, overdraft rate |
| Fee schedules | Monthly fee, transaction fee, overdraft facility fee, late payment fee |
| Product thresholds | Minimum balance, maximum balance, LVR cap, income threshold |
| Notification periods | Advance notice days before unfavourable change takes effect |
| Feature flags | Joint accounts enabled, overdraft enabled, cheque account enabled |
Parameters not in this scope: credit policy rules (managed in MOD-029), fraud scoring thresholds (managed in MOD-023), AML rules (managed in MOD-034). Those modules have separate governed configuration interfaces.
Data model¶
-- app.product_config_proposals
CREATE TABLE app.product_config_proposals (
proposal_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
product_id TEXT NOT NULL,
jurisdiction TEXT NOT NULL CHECK (jurisdiction IN ('NZ','AU','NZ + AU')),
parameter_key TEXT NOT NULL,
current_value JSONB,
proposed_value JSONB NOT NULL,
change_reason TEXT NOT NULL,
proposed_by UUID NOT NULL, -- staff member ID
proposed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
status TEXT NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending','approved','rejected','superseded','live')),
reviewed_by UUID, -- must differ from proposed_by
reviewed_at TIMESTAMPTZ,
review_comment TEXT,
effective_date DATE NOT NULL,
notification_required BOOLEAN NOT NULL DEFAULT false,
notification_confirmed_at TIMESTAMPTZ, -- set by MOD-063 callback
applied_at TIMESTAMPTZ
);
The proposed_by ≠ reviewed_by constraint is enforced at the database layer via a CHECK constraint on the table, not only in application code. This means no application-layer bypass can circumvent the four-eyes rule.
notification_required is set to true automatically when proposed_value represents an unfavourable change relative to current_value (higher fee, lower deposit rate, higher lending rate, stricter eligibility). The system determines "unfavourable" based on parameter-type metadata registered at startup.
Proposal and approval workflow¶
1. Propose. A product manager or pricing analyst logs in to the back-office panel and creates a proposal: selects the product, jurisdiction, parameter, enters the proposed value, effective date, and change reason. The system calculates whether notification is required and sets notification_required accordingly. The proposer submits.
2. Review. A second authorised staff member — who cannot be the proposer — reviews the proposal. They can approve, reject, or return for revision. On approval, status = approved and reviewed_by / reviewed_at are set.
3. Notification dispatch (if required). If notification_required = true, the system immediately calls MOD-063 to dispatch the advance notice to all affected customers. MOD-063 confirms dispatch via a callback that sets notification_confirmed_at. The proposal is held at approved until the callback is received.
4. Effective date gate. Even after notification is confirmed, the configuration change does not take effect until effective_date. A scheduled job runs daily and applies all approved proposals where effective_date <= today and either notification_required = false or notification_confirmed_at IS NOT NULL.
5. Application. On application, status = live, applied_at is set, and the new parameter value is written to the product configuration table. The change is logged to MOD-047 with full before/after state.
Audit trail¶
Every proposal — whether approved, rejected, or superseded — is retained permanently. The table is append-only for audit purposes; no rows are deleted. MOD-047 receives a log entry for every status transition. The combination provides a complete, queryable history of who proposed what, who approved it, when the notification was sent, and when the change took effect.
Requirements¶
FR-573 — Maker/checker enforcement: every product configuration change proposal must require approval by a second authorised staff member who is distinct from the proposer; the system must enforce this at the database constraint level; any attempt to self-approve must be rejected with a clear error.
FR-574 — Disclosure gate: any proposal that constitutes an unfavourable change to customers must not apply before the required notification period has elapsed after MOD-063 confirms dispatch; the system must block application of the change at the effective date gate if notification_confirmed_at IS NULL.
FR-575 — Configuration propagation: applied configuration changes must be propagated to all dependent modules — including MOD-110 (fee engine), MOD-050 (disclosure management), and MOD-113 (statement generation) — within 60 seconds of the change being applied, so that live product behaviour and customer disclosures are consistent with the new configuration.
FR-576 — Immutable audit log: every proposal and every status transition must be logged to MOD-047 with the staff member ID, timestamp, and full before/after parameter values; the log must be queryable by product, parameter, and date range; no records may be deleted or modified after creation.
Module dependencies¶
Depends on¶
| Module | Title | Required? | Contract | Reason |
|---|---|---|---|---|
| MOD-063 | Notification orchestration | Required | — | Unfavourable rate/fee change notifications are triggered via MOD-063; v1 optimistic dispatch (notification_confirmed_at set immediately); v2 will use MOD-063's bank.platform.notification_dispatched confirmation event. |
| MOD-047 | Agent action logger | Required | — | All configuration changes are logged to the agent action audit trail with full before/after state, satisfying GOV-006. |
| MOD-050 | Disclosure enforcement module | Required | — | Changes to product rates and fees must be reflected in the disclosure management module so that pre-contract and in-contract disclosures remain accurate; MOD-050 swaps its disclosure-context lookup to the @bank/product-config library once MOD-127 ships. |
| MOD-110 | Fee engine | Optional | — | Fee schedule changes are propagated to the fee engine via bank.app.product_config_applied; FR-575 is partially met until MOD-110 subscribes; workspace library getCurrentParameter provides the reliable read path. |
Required by¶
| Module | Title | As | Contract |
|---|---|---|---|
| MOD-140 | Chart of accounts and GL configuration | Optional enhancement | — |
| MOD-146 | Restricted activities enforcement | Hard dependency | — |
| MOD-153 | Customer acceptance engine | Hard dependency | — |
| MOD-155 | Target Market Determination (AU DDO) | Hard dependency | — |
Policies satisfied¶
| Policy | Title | Mode | How |
|---|---|---|---|
| GOV-006 | Internal Audit Policy | LOG |
Every product configuration change — rate, fee, term, threshold — is logged immutably with the proposer, approver, timestamp, and before/after values for full audit trail coverage. |
| CON-005 | Fee & Pricing Transparency Policy | GATE |
Any rate or fee change that is unfavourable to customers is blocked from taking effect until MOD-063 confirms that all affected customers have been notified with the required advance notice period. |
| REP-002 | Prudential Reporting Policy | AUTO |
Rate and fee changes are automatically published to the product data feed consumed by MOD-113 statement generation and MOD-050 disclosure management, ensuring disclosures remain consistent with live configuration. |
| GOV-007 | Conflicts of Interest Policy | GATE |
Every configuration change requires a four-eyes check — the proposer cannot be the same person as the approver; the system enforces this at the database constraint level, not only in application logic. |
Capabilities satisfied¶
(No capabilities mapped)
Part of SD08 — Customer App & Back Office Platform
Compiled 2026-05-22 from source/entities/modules/MOD-127.yaml