Neon database platform bootstrap¶
| ID | MOD-103 |
| System | SD07 |
| Repo | bank-platform |
| Build status | Deployed |
| Deployed | Yes |
| Last commit | 51f87d31636881e1ae8dce5f48a0149b48e7c801 |
Purpose¶
Provisions all Neon Postgres infrastructure: the project, environment branches, databases, roles, connection pools, and schema migration pipeline. This is an IaC module — it does not contain Lambda application code. It runs via the bank-platform CI/CD pipeline on configuration change and must be fully deployed before any module that reads from or writes to Postgres can operate.
This module is the implementation of ADR-024.
Execution pattern¶
Unlike runtime modules, this module uses:
- Neon API scripts — plain CI steps that call the Neon REST API directly to create/update project configuration, branches, databases, and roles. No Terraform state file or provider.
- Flyway for schema migrations, integrated into each system domain's deploy pipeline
- Deployed via CI/CD on merge to main; not a running process
Using direct API scripts keeps the provisioning footprint small and avoids a second state management layer. The Neon project and branch model is simple enough that idempotent API calls (create-if-not-exists) are sufficient.
Project and branch structure¶
One Neon project for the entire platform. Environments are persistent branches; preview environments are ephemeral branches off dev.
bank (single Neon project)
├─ prod (persistent branch — production databases)
├─ uat (persistent branch — UAT / release verification)
├─ dev (persistent branch — CI baseline; shared team instance)
│ └─ pr-{number} (ephemeral preview branches, auto-created per PR, auto-deleted on close)
└─ (local development points at dev branch or a personal preview branch)
Each branch is an instant zero-copy clone of its parent — preview branches cost near-zero storage overhead. Branch-level isolation ensures dev and UAT schemas and data cannot cross-contaminate prod.
Databases (per branch)¶
Each branch carries the same set of databases, one per system domain:
| Database | System domain | Primary schemas |
|---|---|---|
bank_core |
SD01 Core Banking | accounts, postings, treasury, contexts, assets |
bank_kyc |
SD02 KYC Platform | kyc, party, banking, regulatory |
bank_aml |
SD03 AML Monitoring | aml |
bank_payments |
SD04 Payments | payments |
bank_credit |
SD05 Credit | credit |
bank_app |
SD08 App | app, access |
SD06 (Risk Platform) and SD07 (Data Platform) write to Snowflake, not Neon — no Neon databases for those domains.
Role provisioning (per database, per branch)¶
Three roles are provisioned per database. Role names are the same across all branches — environment isolation is provided by the branch, not the role name.
| Role | Permissions | Used by |
|---|---|---|
{domain}_app_user |
SELECT, INSERT, UPDATE, DELETE on all tables in domain schema | Lambda execution role |
{domain}_migrate_user |
DDL — CREATE, ALTER, DROP on domain schema | Migration pipeline only |
{domain}_readonly |
SELECT on all tables in domain schema | CDC replication source (MOD-042), reporting |
Passwords are generated at provisioning time and stored in Secrets Manager (MOD-045), scoped per branch (dev, uat, prod secrets are separate paths). App roles connect via PgBouncer. Migration role uses a direct connection (bypasses pooler — DDL requires session mode).
No cross-domain database connections from application code. The _readonly role is the only permitted cross-domain access path, used exclusively by MOD-042 for CDC replication from prod.
Connection pooler configuration¶
Neon's built-in PgBouncer is configured in transaction pooling mode — required for Lambda (ephemeral, high-concurrency) workloads. Exact pool sizes and max connection limits are defined as IaC variable overrides per environment. The principle:
- prod — sized for production concurrency; generous limits with head-room for peak
- uat — moderate capacity; sufficient for full acceptance test suites running concurrently
- dev — minimal; enough for CI pipelines, not sized for sustained load
- preview branches — minimal; single-developer or single-pipeline usage only
Connection strings for each database and branch are stored in Secrets Manager as structured secrets referenced by Lambda environment variables.
Direct (non-pooled) connection strings are maintained for: - Migration operations (DDL requires session mode) - CDC logical replication source (requires persistent connection — MOD-042) - PAM-gated DBA access (MOD-046)
Schema migration pipeline (Flyway)¶
Each system domain repository contains a db/migrations/ directory with versioned SQL files (V001__description.sql, V002__description.sql). The migration pipeline:
- Connects to the domain database on the target branch using the
migrate_userdirect connection - Checks the
flyway_schema_historytable for applied versions - Applies pending migrations in version order within a transaction
- Fails fast — any error halts the deploy pipeline before Lambda code is deployed
- Every forward migration (
Vxxx__description.sql) must have a corresponding undo migration (Uxxx__description_rollback.sql)
Preview branches: CI creates a Neon branch from dev for each PR via the Neon API. Flyway runs the PR's migrations against the branch. The branch is deleted when the PR closes (merged or abandoned).
Promotion path: Migrations are applied independently per branch as the environment advances through the promotion pipeline. The same migration files run on dev → uat → prod in sequence; they are never applied directly to prod without first passing dev and uat.
Data in lower environments¶
Neon branching means that when a preview or dev branch is created from dev, it inherits whatever data is in dev. The dev branch holds synthetic data only — prod data never flows to dev or UAT. Synthetic data generation is the responsibility of each system domain's test fixtures.
Data residency¶
The Neon project is provisioned in AWS region ap-southeast-2 (Sydney) for both NZ and AU environments — Neon's nearest available region. Customer data does not leave this region. This satisfies the NZ Privacy Act 2020 and AU Privacy Act 1988 requirements for data localisation when processing is in a country with comparable privacy laws.
If NZ-only data residency is required by future regulation, the evolution path is Neon's planned NZ region or migration to Neon on RDS in ap-southeast-4 (Melbourne), per ADR-024.
Module dependencies¶
Depends on¶
| Module | Title | Required? | Contract | Reason |
|---|---|---|---|---|
| MOD-104 | AWS shared infrastructure bootstrap | Required | — | Neon projects are provisioned in AWS regions; the AWS account structure, IAM roles, and KMS keys provisioned by MOD-104 are required before Neon can be configured. |
Required by¶
| Module | Title | As | Contract |
|---|---|---|---|
| MOD-001 | Double-entry posting engine | Hard dependency | — |
| MOD-002 | Immutable transaction log | Hard dependency | — |
| MOD-003 | Real-time balance engine | Hard dependency | — |
| MOD-004 | Multi-currency ledger (NZD/AUD) | Hard dependency | — |
| MOD-005 | Daily accrual calculator | Hard dependency | — |
| MOD-006 | Rate change propagation | Hard dependency | — |
| MOD-007 | Account state machine | Hard dependency | — |
| MOD-008 | Dormancy & escheatment engine | Hard dependency | — |
| MOD-009 | eIDV & document verification | Hard dependency | — |
| MOD-010 | CDD tier assignment engine | Hard dependency | — |
| MOD-011 | KYC periodic review scheduler | Hard dependency | — |
| MOD-012 | KYC audit trail store | Hard dependency | — |
| MOD-013 | Real-time sanctions screener | Hard dependency | — |
| MOD-014 | List change propagation | Hard dependency | — |
| MOD-015 | False positive management | Hard dependency | — |
| MOD-016 | Rule-based typology engine | Hard dependency | — |
| MOD-017 | ML behavioural scoring model | Hard dependency | — |
| MOD-018 | Alert case management system | Hard dependency | — |
| MOD-019 | Regulatory report submission module | Hard dependency | — |
| MOD-020 | Pre-payment validation suite | Hard dependency | — |
| MOD-021 | Payment limit & velocity controller | Hard dependency | — |
| MOD-022 | Payment audit trail | Hard dependency | — |
| MOD-023 | Transaction fraud scorer | Hard dependency | — |
| MOD-024 | Device & session intelligence | Hard dependency | — |
| MOD-025 | FX rate lock & conversion | Hard dependency | — |
| MOD-026 | IFTI / CMIR reporting trigger | Hard dependency | — |
| MOD-027 | Affordability calculator | Hard dependency | — |
| MOD-028 | Credit score & risk rating | Hard dependency | — |
| MOD-029 | Pre-approval engine | Hard dependency | — |
| MOD-030 | Stage allocation model | Hard dependency | — |
| MOD-031 | ECL calculation & GL posting | Hard dependency | — |
| MOD-049 | Open banking consent management | Hard dependency | — |
| MOD-050 | Disclosure enforcement module | Hard dependency | — |
| MOD-051 | Financial automation rules engine | Hard dependency | — |
| MOD-052 | Role-scoped data access | Hard dependency | — |
| MOD-053 | Case & complaint management module | Hard dependency | — |
| MOD-054 | Call recording & transcript attachment | Hard dependency | — |
| MOD-059 | Credit bureau submission engine | Hard dependency | — |
| MOD-061 | Open banking API platform | Hard dependency | — |
| MOD-064 | Operations work queue | Hard dependency | — |
| MOD-065 | Credit servicing & collections | Hard dependency | — |
| MOD-066 | Collateral & security management | Hard dependency | — |
| MOD-067 | Trade finance operations | Hard dependency | — |
| MOD-068 | Authentication & session management | Hard dependency | — |
| MOD-069 | Customer app shell | Hard dependency | — |
| MOD-070 | Transaction history & search | Hard dependency | — |
| MOD-071 | Payment initiation | Hard dependency | — |
| MOD-072 | Customer profile & settings | Hard dependency | — |
| MOD-073 | Document vault | Hard dependency | — |
| MOD-074 | Back-office customer 360 | Hard dependency | — |
| MOD-077 | Account dashboard & insight feed | Hard dependency | — |
| MOD-078 | Card & account controls | Hard dependency | — |
| MOD-081 | Payment reconciliation engine | Hard dependency | — |
| MOD-082 | Nostro & FX treasury management | Hard dependency | — |
| MOD-083 | Agent assist & compliance coaching panel | Hard dependency | — |
| MOD-084 | Open banking data access — data recipient | Hard dependency | — |
| MOD-086 | Funds transfer pricing engine | Hard dependency | — |
| MOD-087 | Transaction enrichment engine | Hard dependency | — |
| MOD-096 | Multi-entity party graph manager | Hard dependency | — |
| MOD-108 | Product offer engine | Hard dependency | — |
| MOD-109 | Product deal engine | Hard dependency | — |
| MOD-110 | Fee engine | Hard dependency | — |
| MOD-111 | Term deposit maturity engine | Hard dependency | — |
| MOD-112 | Amortisation schedule engine | Hard dependency | — |
| MOD-113 | Statement generation | Hard dependency | — |
| MOD-114 | Direct debit mandate management | Hard dependency | — |
| MOD-118 | Member equity and share registry | Hard dependency | — |
| MOD-122 | NZ faster payments and A2A integration | Hard dependency | — |
| MOD-128 | Credit bureau enquiry and CCR integration | Hard dependency | — |
| MOD-130 | Notice account management | Hard dependency | — |
| MOD-132 | Loan restructure and variation workflow | Hard dependency | — |
| MOD-135 | Batch payment and payroll file processing | Hard dependency | — |
| MOD-136 | BPAY biller registration and inbound BPAY | Hard dependency | — |
| MOD-137 | Agency banking adapter | Hard dependency | — |
| MOD-143 | Open Bank Resolution pre-positioning | Hard dependency | — |
| MOD-144 | Confirmation of payee — account name verification | Hard dependency | — |
| MOD-145 | Payment hold & friction engine | Hard dependency | — |
| MOD-146 | Restricted activities enforcement | Hard dependency | — |
| MOD-148 | Privacy access request (DSAR) workflow | Hard dependency | — |
| MOD-149 | Scam intelligence reporting & reimbursement | Hard dependency | — |
| MOD-151 | Risk case console | Hard dependency | — |
| MOD-153 | Customer acceptance engine | Hard dependency | — |
| MOD-154 | Correspondent banking risk gate | Hard dependency | — |
| MOD-155 | Target Market Determination (AU DDO) | Hard dependency | — |
| MOD-158 | Test seed data loader | Hard dependency | — |
| MOD-161 | Transfer pricing | Hard dependency | — |
| MOD-162 | Loan facility & component manager | Hard dependency | — |
| MOD-163 | Break-cost calculator | Hard dependency | — |
| MOD-164 | Facility component self-service | Hard dependency | — |
| MOD-165 | Synthetic swap book aggregator | Hard dependency | — |
| MOD-166 | Transaction category corrections | Hard dependency | — |
| MOD-168 | Maker-checker enforcement engine | Hard dependency | — |
Policies satisfied¶
| Policy | Title | Mode | How |
|---|---|---|---|
| DT-001 | Information Security Policy | GATE |
Each system domain is provisioned with its own Postgres database and role — cross-domain direct DB connections are structurally prevented by the role provisioning model. |
| PRI-001 | Privacy Policy | GATE |
Database roles and column-level permissions are configured at bootstrap to enforce the data minimisation principle — application roles are granted access only to the schemas and columns they require. |
| PRI-003 | Personal Information Retention & Destruction Policy | AUTO |
Neon project is provisioned in the correct AWS region for data residency (NZ and AU environments in region-appropriate endpoints), satisfying the data localisation obligation. |
Capabilities satisfied¶
(No capabilities mapped)
Part of SD07 — Data Platform & Governance Infrastructure
Compiled 2026-05-22 from source/entities/modules/MOD-103.yaml