Skip to content

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