Skip to content

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:

  1. Connects to the domain database on the target branch using the migrate_user direct connection
  2. Checks the flyway_schema_history table for applied versions
  3. Applies pending migrations in version order within a transaction
  4. Fails fast — any error halts the deploy pipeline before Lambda code is deployed
  5. 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