Architecture
POS Partner API is a NestJS service providing wallet operations (balance, top-up, settlement) and member lookup for third-party POS terminals (Trident Phase 1).
Stack
| Component | Technology |
|---|---|
| Runtime | NestJS on Node.js 22 (distroless) |
| Database | PostgreSQL on Tier 2 shared CNPG |
| ORM | Prisma (pos-data, mca_v1_za, mca_v1_uk) |
| Auth | x-partner-key header + HMAC member ID validation |
| External | MCA Xano API (ZA) |
| Image | registry.digiwedge.com/digiwedge/pos-partner-api |
Endpoints
| Route prefix | Controller | Purpose |
|---|---|---|
v1/pos/partners | PosPartnersController | Primary Trident contract: lookup, balance, table link, top-up, settlement |
pos | PosPartnersCompatibilityController | Compatibility routes for legacy Xano-era integrations |
transactional | PosPartnersLegacyBalanceController | Legacy balance endpoints |
Settlement model
CRM-linked settlements use an acceptance-anchor model:
- Table-linked settlements are protected by
table_links.settlementClaimedBy - CRM-linked settlements (
quoteId/reservationId) admit throughsettlement_acceptance_anchors - Idempotency keys are replay keys within an accepted anchor lifecycle
- Claim-token-based submit fencing prevents double-debit races
See the Prisma schema at libs/prisma/pos-data/prisma/schema.prisma for the full data model.
Database
- Logical database:
pos_dbontier2-shared(UAT) /tier2-shared-prod(prod) - Prisma schema:
libs/prisma/pos-data/prisma/schema.prisma - Env var:
POS_DATA_DATABASE_URL - Migrations run via PreSync hook (
pre-sync-migrate-job.yaml)
Member resolution
- Member lookup is source-routed by club, not hardcoded to MCA v2.
- Legacy ZA clubs resolve through
libs/prisma/mca_v1_za(MCA_SA_LIVE_V1_URL). - Legacy UK clubs resolve through
libs/prisma/mca_v1_uk(MCA_UK_LIVE_V1_URL). - SCL remains the strategic target member domain, but the card/member bridge is not implemented in
pos-partner-apiyet. - Wallet operations remain on the external Xano path today and are intentionally separate from member identity resolution.
Deployment
- UAT:
pos-uatnamespace, ArgoCD apppos-partner-api - Prod:
pos-prodnamespace, ArgoCD apppos-partner-api-prod - Gateway routes: UAT (
pos-partner-api.uat.digiwedge.com), prod (pos-partner-api.digiwedge.com) - Publish workflow:
.github/workflows/pos-partner-api-publish.yml - Smoke test:
tools/scripts/smoke/pos-partner-api.sh - Reconciliation sync writer: Kubernetes CronJob
pos-partner-api-reconciliation-sync - Replica count is no longer coupled to reconciliation writer ownership