Skip to content

Migrate PayGuard to PostgreSQL and integrate Vault - #35

Merged
Amir-Golmoradi merged 2 commits into
mainfrom
amg-postgres-vault
Oct 12, 2026
Merged

Amir-Golmoradi merged 2 commits into
mainfrom
amg-postgres-vault

Conversation

@Amir-Golmoradi

@Amir-Golmoradi Amir-Golmoradi commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Why

PayGuard's planned jOOQ development should not require a paid database-dialect license. Oracle support is provided by commercial jOOQ editions, with Professional covering full Oracle support; PostgreSQL is supported by the jOOQ Open Source Edition. This migration lets PayGuard keep explicit SQL where jOOQ is appropriate without buying a commercial jOOQ license. See the official jOOQ editions and dialect matrix.

Vault addresses a separate requirement: database passwords and application secrets need scoped access, explicit rotation and failure handling rather than static runtime credentials or a known development pepper.

Changes

  • Replace Oracle dependencies/configuration with PostgreSQL for the migrated service paths, preserving JPA for Identity/Loan/Collateral and the existing OSS jOOQ approach for Wallet.
  • Add vendor-specific PostgreSQL Flyway schemas while retaining historical Oracle scripts and requiring approved historical identifier mappings. Preserve prefixed identifiers, UUID audit IDs, exact decimal amounts and microsecond timestamp semantics.
  • Provision independent service databases with TLS/SCRAM, separate durable owners/migration roles/runtime DML privileges, and persistent non-dev Vault with TLS, AppRole and audit.
  • Consume actual short-lived Vault database credentials through Hikari pool replacement before lease expiry, with bounded draining, revocation/outage handling and readiness checks.
  • Add scoped KV v2 OTP key rings and authenticator lookup, explicit legacy HMAC compatibility, and safeguards against premature key/legacy-alias retirement.
  • Serialize OTP verification and issuance/replacement through PostgreSQL locks and constraints, preserving rejected-attempt commits and keeping remote calls outside database locks.
  • Add real dependency verification, migration rehearsal tooling, CI, ADRs 0011–0014, an implementation guide and separate follow-up Issue drafts.

Ownership and integration dependency

This commit contains only migration work. It intentionally excludes the owner's 32-file Identity domain work in PR #33, unrelated shared/Wallet nullness edits, local Git-hook/event-schema changes, and the old OTP module retirement/root module switch. The original working tree and index were preserved.

This is an integration-dependent draft. PR #33 and the remaining separately owned Identity application/port/bootstrap integration must be applied before this branch can represent the complete migrated application. The old OTP module remains selected in the migration-only parent POM because switching it was excluded owner work. Its remaining Oracle references are not presented as migrated runtime behavior. The new database/security CI job expects the Identity module to be registered by that integration.

Validation

Evidence from the complete local implementation checkout, including the separately owned Identity foundations:

  • 95 Maven tests passed; zero failures/errors/skips. Full verify still exited 1 on six existing Identity typed-ID PMD naming findings; checks were not disabled.
  • 15 real Vault/PostgreSQL lifecycle/security tests passed, including concurrency-related infrastructure, privilege isolation, renew/revoke, pool replacement beyond max TTL, outages/recovery, scoped TOTP lookup and HMAC/legacy-alias rotation. Audit and secret-marker checks passed.
  • Three synthetic export/mapping tests passed.
  • All four actual Dockerfiles built, and all four packaged services reached readiness UP with service-only AppRole files and verified PostgreSQL TLS.
  • Separately privileged local Identity/Loan/Collateral migrations and fresh disposable PostgreSQL role provisioning succeeded.

These results are not claims that this migration-only commit builds independently. On the exact isolated publication checkout, Maven validate passed. The unmodified pre-push hook then ran the local quality-check workflow successfully: Spotless, Checkstyle, PMD, SpotBugs and reactor tests all passed. Its registered reactor still contains the old OTP module; it does not run the excluded/new Identity module or the new database/security workflow. Complete Identity runtime verification remains dependent on the excluded integration. No remote CI pass is claimed.

Remaining limits

Live Oracle data and approved historical identifier mappings were unavailable. Wallet lacks a SQL schema/adapter/code-generation setup; Loan/Collateral lack concrete repository adapters. No platform-wide persisted financial concurrency, production readiness, HA/auto-unseal, deployment or destructive data cutover is claimed. Durable audit/event/delivery recovery, authenticator enrollment and production operations remain separate work.

See the implementation guide, ADRs and follow-up drafts for exact commands, evidence and boundaries.

The original publication's local pre-push reactor reported 25 tests: 24 executed, 1 skipped, 0 failures and 0 errors. The skipped test belongs to the unchanged legacy Oracle integration path; it does not replace the separately reported real PostgreSQL/Vault verification.

Amir-Golmoradi and others added 2 commits October 12, 2026 02:05
Use PostgreSQL with the jOOQ Open Source Edition to avoid requiring a
commercial license for Oracle dialect support.

Keep service databases and runtime/migration privileges isolated. Add
vendor-specific Flyway schemas, Vault AppRole and scoped application
secrets, dynamic credential pool replacement, and OTP concurrency checks.

Preserve historical Oracle scripts and document cutover, key rotation,
local verification and remaining limitations. Include only migration
work; the separately owned Identity foundation remains a dependency.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant