Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
4f3f286
chore(py-deps): update fastapi requirement
dependabot[bot] May 20, 2026
4e7ac2a
chore(py-deps): update uvicorn requirement
dependabot[bot] May 20, 2026
a063ac3
chore(py-deps): update pytest-asyncio requirement
dependabot[bot] May 20, 2026
cc57d5c
chore(py-deps): bump black in /services/python/payment-gateway-service
dependabot[bot] May 20, 2026
522132f
chore(py-deps): bump python-dotenv
dependabot[bot] May 20, 2026
2007400
chore(py-deps): bump pydantic
dependabot[bot] May 20, 2026
4390962
chore(deps)(deps): bump @types/pdfkit from 0.17.5 to 0.17.6
dependabot[bot] May 20, 2026
af0af29
chore(deps)(deps): bump react-day-picker from 9.11.1 to 10.0.1
dependabot[bot] May 20, 2026
1728a33
chore(actions): bump docker/metadata-action from 5 to 6
dependabot[bot] May 20, 2026
1ad1054
chore(actions): bump zaproxy/action-baseline from 0.12.0 to 0.15.0
dependabot[bot] May 20, 2026
023578c
chore(actions): bump docker/setup-buildx-action from 3 to 4
dependabot[bot] May 20, 2026
a11fa24
chore(actions): bump zaproxy/action-api-scan from 0.7.0 to 0.10.0
dependabot[bot] May 20, 2026
6e978ee
chore(deps)(deps): bump zod from 4.1.12 to 4.4.3
dependabot[bot] May 21, 2026
4bda43b
chore(dev-deps)(deps-dev): bump typescript from 5.9.3 to 6.0.3
dependabot[bot] May 21, 2026
9f86ac8
fix: POS gaps — geofencing, iot-smart-pos, terminal-ownership, batch …
devin-ai-integration[bot] Jun 7, 2026
19c2579
chore(deps)(deps): bump the radix-ui group across 1 directory with 26…
dependabot[bot] Jun 8, 2026
5b37ab9
fix: business logic implementation — resolve all TS errors + test fai…
devin-ai-integration[bot] Jun 9, 2026
b936358
style: run prettier to fix formatting issues
devin-ai-integration[bot] Jun 9, 2026
b34bff9
fix: wire STATUS_TRANSITIONS enforcement, persist fees, remove ~40K l…
devin-ai-integration[bot] Jun 9, 2026
8440c94
fix: enforce STATUS_TRANSITIONS in 473/475 routers, writeAuditLog in …
devin-ai-integration[bot] Jun 9, 2026
ad749ad
fix: add missing gl_journal_entries imports and fix db() call in bill…
devin-ai-integration[bot] Jun 9, 2026
0660648
style: format 4 router files with prettier
devin-ai-integration[bot] Jun 9, 2026
cc0ff40
fix: persist fee/commission in all transaction inserts, add GL journa…
devin-ai-integration[bot] Jun 9, 2026
95413a2
fix: replace inline Math.round fees with calculateFee/calculateCommis…
devin-ai-integration[bot] Jun 9, 2026
62017a8
fix: expand withIdempotency to all mutation routers, wire checkDailyL…
devin-ai-integration[bot] Jun 9, 2026
653d839
fix: add auth middleware to all services, replace Math.random with cr…
devin-ai-integration[bot] Jun 9, 2026
92ffd53
style: format files with prettier
devin-ai-integration[bot] Jun 9, 2026
2654ead
fix: add auth middleware to all remaining Go/Rust/Python services, fi…
devin-ai-integration[bot] Jun 9, 2026
e0352fc
fix: remove console.log, fix Go imports, use env vars for API keys
devin-ai-integration[bot] Jun 9, 2026
22cef04
style: format billingAudit.ts with prettier
devin-ai-integration[bot] Jun 9, 2026
6700495
fix: add global XSS/injection middleware, wrap financial mutations in…
devin-ai-integration[bot] Jun 9, 2026
01765f8
chore(docker): bump alpine in /services/go/mdm-compliance-engine
dependabot[bot] Jun 10, 2026
911e44e
Merge pull request #31 from munisp/devin/business-logic-fixes
munisp Jun 16, 2026
5af9097
Merge pull request #32 from munisp/dependabot/docker/services/go/mdm-…
munisp Jun 18, 2026
995b89b
Merge pull request #30 from munisp/dependabot/npm_and_yarn/radix-ui-3…
munisp Jun 18, 2026
f8c3d54
Merge pull request #26 from munisp/dependabot/github_actions/zaproxy/…
munisp Jun 18, 2026
b66b958
Merge pull request #25 from munisp/dependabot/github_actions/docker/s…
munisp Jun 18, 2026
bc25df3
Merge pull request #23 from munisp/dependabot/github_actions/zaproxy/…
munisp Jun 18, 2026
b40db9c
feat: optimize all infra services for millions of TPS
devin-ai-integration[bot] Jun 20, 2026
babc992
fix: add missing github.com/lib/pq dependency to mojaloop-connector-p…
devin-ai-integration[bot] Jun 20, 2026
e0d6160
Merge pull request #35 from munisp/devin/1781977683-infra-perf-optimi…
munisp Jun 20, 2026
9f3a98d
feat: fund flow audit — fix all critical/high/medium gaps with Go/Rus…
devin-ai-integration[bot] Jun 20, 2026
b351091
Merge pull request #36 from munisp/devin/1781981843-fund-flow-audit
munisp Jun 20, 2026
f90e24f
feat: full middleware integration (TigerBeetle, Fluvio, Dapr, Lakehou…
devin-ai-integration[bot] Jun 20, 2026
f228552
test: add runtime middleware integration tests (Redis, TigerBeetle, F…
devin-ai-integration[bot] Jun 21, 2026
e65cc50
Merge pull request #38 from munisp/devin/1781987951-middleware-integr…
munisp Jun 21, 2026
08db1ed
fix: harden fund flow integrity — race conditions, phantom events, va…
devin-ai-integration[bot] Jun 21, 2026
3adc47c
Merge pull request #39 from munisp/devin/1782006101-fund-flow-integri…
munisp Jun 21, 2026
adc5e16
feat: insider threat mitigation — 7 controls (Go/Rust/Python/TS) + PW…
devin-ai-integration[bot] Jun 21, 2026
7fac2d2
Merge pull request #40 from munisp/devin/1782051659-insider-threat-mi…
munisp Jun 21, 2026
4976a3a
chore(dev-deps)(deps-dev): bump tailwindcss from 4.1.14 to 4.3.1
dependabot[bot] Jun 22, 2026
2681b89
chore(deps)(deps): bump pg from 8.20.0 to 8.22.0
dependabot[bot] Jun 22, 2026
96f651c
fix: eliminate all in-memory state — persist to PostgreSQL
devin-ai-integration[bot] Jun 24, 2026
830dc18
Merge pull request #44 from munisp/devin/1782262143-eliminate-inmemor…
munisp Jun 24, 2026
6c45ba8
feat: platform enhancements — KYC/KYB/Liveness, Flow of Funds, UI/UX …
devin-ai-integration[bot] Jun 24, 2026
a97aebb
fix: add i18n backward-compatible exports (changeLanguage, default, f…
devin-ai-integration[bot] Jun 24, 2026
cd297bd
Merge pull request #45 from munisp/devin/1782265834-platform-enhancem…
munisp Jun 24, 2026
153d972
feat: POS enhancements — 32 recommendations (Go/Rust/Python/Kotlin/TS)
devin-ai-integration[bot] Jun 24, 2026
b302cff
Merge pull request #46 from munisp/devin/1782269955-pos-enhancements
munisp Jun 24, 2026
a89f8d2
Update testing skill with POS middleware and polyglot persistence pat…
devin-ai-integration[bot] Jun 24, 2026
1679fe6
fix: wire publishPosMiddleware into all POS mutation handlers (was de…
devin-ai-integration[bot] Jun 24, 2026
d35c7e7
feat: fix all 8 multi-network provider gaps — Rust failover, Android …
devin-ai-integration[bot] Jun 24, 2026
b72900b
Merge pull request #49 from munisp/devin/1782273554-fix-multi-network…
munisp Jun 24, 2026
d0f7e95
fix: TigerBeetle bi-directional persistence — eliminate all in-memory…
devin-ai-integration[bot] Jun 24, 2026
c173289
feat: ecommerce full implementation — 15 gaps + 7 enhancements + 5 in…
devin-ai-integration[bot] Jun 24, 2026
3037314
Merge pull request #51 from munisp/devin/1782302401-tigerbeetle-bidir…
munisp Jun 24, 2026
d4bd98f
Merge pull request #52 from munisp/devin/1782303891-ecommerce-full-im…
munisp Jun 24, 2026
20c2364
feat: add middleware integration (Kafka/TB/Fluvio/Dapr/Lakehouse) to …
devin-ai-integration[bot] Jun 24, 2026
40dc7b4
feat: Kafka consumers for all topics, stablecoin mutations, Redis rat…
devin-ai-integration[bot] Jun 24, 2026
0fd0b76
feat: Permify schema + relationship writes, Rust/Python PostgreSQL pe…
devin-ai-integration[bot] Jun 24, 2026
419bbc8
feat: Mojaloop mTLS/JWS/quote/settlement, OpenSearch index mappings (…
devin-ai-integration[bot] Jun 24, 2026
83f533c
feat: Temporal real workflows (Dispute/KYC/Onboarding/Commission), co…
devin-ai-integration[bot] Jun 24, 2026
dc8a973
feat: Go mutex guards, RN domain endpoints, marketplace API integrati…
devin-ai-integration[bot] Jun 24, 2026
9f0b559
fix: resolve all server-side TS errors (timestamp types, orphaned mid…
devin-ai-integration[bot] Jun 24, 2026
f683142
fix: make sync mutation handlers async where they use await
devin-ai-integration[bot] Jun 24, 2026
94d318a
fix: resolve duplicate imports after rebase with PR #52
devin-ai-integration[bot] Jun 24, 2026
872f4c1
Merge pull request #54 from munisp/devin/1782320052-full-platform-pro…
munisp Jun 24, 2026
45d663a
feat: middleware to 9 remaining routers, PgPool to 19 Rust services, …
devin-ai-integration[bot] Jun 24, 2026
47adf8b
feat: Flutter screens, Permify enforcement, APISIX financial rate lim…
devin-ai-integration[bot] Jun 24, 2026
a6d3015
feat: Lakehouse partitioning, Dapr service registry, OpenSearch searc…
devin-ai-integration[bot] Jun 24, 2026
32e8d56
fix: resolve TS errors — enforcePermission signature, duplicate impor…
devin-ai-integration[bot] Jun 24, 2026
e19424c
fix: REAL PgPool persistence for 16 Rust services — init_pg_pool, pg_…
devin-ai-integration[bot] Jun 24, 2026
23c439b
fix: wire pg_get/pg_set into 653 Python endpoint handlers across 142 …
devin-ai-integration[bot] Jun 24, 2026
9c59fcf
fix: Permify enforcePermission on ALL 44 mutations (was 15), real res…
devin-ai-integration[bot] Jun 24, 2026
533c4b4
feat: wire searchAsYouType, multiSearch, invokeDaprService, ingestToL…
devin-ai-integration[bot] Jun 24, 2026
41fcb70
fix: resolve TS errors — add ctx to mutation destructurings, make dap…
devin-ai-integration[bot] Jun 24, 2026
a079141
Merge pull request #55 from munisp/devin/1782325164-medium-low-gap-re…
munisp Jun 24, 2026
51951f6
feat: rewrite 4 Flutter screens with real ApiService calls (complianc…
devin-ai-integration[bot] Jun 24, 2026
93864c8
chore(actions): bump actions/upload-artifact from 4 to 7
dependabot[bot] Jun 25, 2026
0f0dd42
chore(actions): bump actions/setup-go from 5 to 6
dependabot[bot] Jun 25, 2026
26b1e72
chore(actions): bump docker/build-push-action from 5 to 7
dependabot[bot] Jun 25, 2026
36d5d16
chore(actions): bump actions/checkout from 4 to 7
dependabot[bot] Jun 25, 2026
1dcab70
feat: wire mtlsAgent into MojalloopConnector, add settlement window a…
devin-ai-integration[bot] Jun 27, 2026
db7dade
feat: add Stellar/Ethereum blockchain wallet integration to stablecoi…
devin-ai-integration[bot] Jun 27, 2026
b141b71
feat: rewrite 10 RN scaffold screens with domain-specific UX (benefic…
devin-ai-integration[bot] Jun 27, 2026
da2570d
chore(dev-deps)(deps-dev): bump the testing group across 1 directory …
dependabot[bot] Jun 29, 2026
a3334d3
chore(deps)(deps): bump the aws-sdk group across 1 directory with 2 u…
dependabot[bot] Jun 29, 2026
7046d61
chore(deps)(deps): bump the radix-ui group across 1 directory with 26…
dependabot[bot] Jun 29, 2026
b457334
Merge pull request #60 from munisp/devin/1782328727-remaining-gaps-9plus
devin-ai-integration[bot] Jul 6, 2026
f45c430
Merge pull request #48 from munisp/devin/1782272251-fix-pos-middlewar…
devin-ai-integration[bot] Jul 6, 2026
2cf0ee7
Merge pull request #47 from munisp/devin/update-skills-1782272236
devin-ai-integration[bot] Jul 6, 2026
57603ae
fix: settlement & reconciliation engine — eliminate in-memory state, …
devin-ai-integration[bot] Jun 24, 2026
1c34687
Merge pull request #50 from munisp/devin/1782276041-settlement-reconc…
devin-ai-integration[bot] Jul 6, 2026
259fa42
Merge pull request #59 from munisp/dependabot/github_actions/actions/…
devin-ai-integration[bot] Jul 6, 2026
78ade24
Merge pull request #58 from munisp/dependabot/github_actions/docker/b…
devin-ai-integration[bot] Jul 6, 2026
93cd6cb
Merge pull request #57 from munisp/dependabot/github_actions/actions/…
devin-ai-integration[bot] Jul 6, 2026
d0396d6
Merge pull request #56 from munisp/dependabot/github_actions/actions/…
devin-ai-integration[bot] Jul 6, 2026
20bcf79
Merge pull request #43 from munisp/dependabot/npm_and_yarn/pg-8.22.0
devin-ai-integration[bot] Jul 6, 2026
20250be
Merge pull request #42 from munisp/dependabot/npm_and_yarn/tailwindcs…
devin-ai-integration[bot] Jul 6, 2026
48d7238
Merge pull request #41 from munisp/dependabot/npm_and_yarn/radix-ui-d…
devin-ai-integration[bot] Jul 6, 2026
94541ce
Merge pull request #22 from munisp/dependabot/github_actions/docker/m…
devin-ai-integration[bot] Jul 6, 2026
ce4cefa
Merge pull request #21 from munisp/dependabot/npm_and_yarn/typescript…
devin-ai-integration[bot] Jul 6, 2026
b818bd9
Merge pull request #19 from munisp/dependabot/npm_and_yarn/react-day-…
devin-ai-integration[bot] Jul 6, 2026
03c8c66
Merge pull request #17 from munisp/dependabot/npm_and_yarn/types/pdfk…
devin-ai-integration[bot] Jul 6, 2026
5826ad9
Merge pull request #15 from munisp/dependabot/npm_and_yarn/zod-4.4.3
devin-ai-integration[bot] Jul 6, 2026
325924d
Merge pull request #14 from munisp/dependabot/npm_and_yarn/testing-23…
devin-ai-integration[bot] Jul 6, 2026
79cb406
Merge pull request #13 from munisp/dependabot/pip/services/python/pay…
devin-ai-integration[bot] Jul 6, 2026
a9d7f3a
Merge pull request #11 from munisp/dependabot/pip/services/python/pay…
devin-ai-integration[bot] Jul 6, 2026
68305b5
Merge pull request #9 from munisp/dependabot/pip/services/python/paym…
devin-ai-integration[bot] Jul 6, 2026
6aa2b8e
Merge pull request #8 from munisp/dependabot/npm_and_yarn/aws-sdk-540…
devin-ai-integration[bot] Jul 6, 2026
fec66d8
Merge pull request #5 from munisp/dependabot/pip/services/python/cbn-…
devin-ai-integration[bot] Jul 6, 2026
5c25ef4
Merge pull request #3 from munisp/dependabot/pip/services/python/cbn-…
devin-ai-integration[bot] Jul 6, 2026
67711b1
Merge pull request #2 from munisp/dependabot/pip/services/python/cbn-…
devin-ai-integration[bot] Jul 6, 2026
e3f74db
Merge main into production-hardened branch for PR #61
devin-ai-integration[bot] Jul 6, 2026
55d78df
fix: resolve CI failures — TS6 baseUrl deprecation, dependency audit …
devin-ai-integration[bot] Jul 6, 2026
79eb7fc
style: run prettier to fix 382 formatting issues
devin-ai-integration[bot] Jul 6, 2026
d34b7e1
fix: add graceful shutdown handlers to all Go services + fix test exp…
devin-ai-integration[bot] Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
222 changes: 222 additions & 0 deletions .agents/skills/testing-agentbanking-fund-flows/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
---
name: testing-agentbanking-fund-flows
description: Test fund flow routers (cashIn, cashOut, NFC, QR, loans, BNPL, FX, etc.) for middleware completeness. Use when verifying tRPC router changes that affect financial transactions.
---

# Testing Agent Banking Fund Flow Routers

## Overview

The platform has 485+ tRPC routers. Financial routers that move money must have up to 10 middleware layers:

**Core (required for all financial mutations):**

1. **FOR UPDATE** — PostgreSQL row-level locking inside `withTransaction()` to prevent race conditions
2. **GL Journal Entries** — Double-entry accounting via `db.insert(gl_journal_entries).values({...})`
3. **Kafka Events** — Domain event publishing via `publishEvent(topic, ref, payload, metadata)`
4. **Idempotency** — Duplicate prevention via `withIdempotency(key, fn)` wrapper
5. **CBN Limits** — Nigerian regulatory daily limits via `checkDailyLimit(db, agentId, tier, amount)`
6. **Audit Log** — Mutation trail via `writeAuditLog({agentId, agentCode, action, resource, ...})`

**Extended (fire-and-forget, fail-open):** 7. **TigerBeetle** — Immutable dual-ledger via `tbCreateTransfer({debitAccountId, creditAccountId, amount, ref, txType, agentCode})` 8. **Fluvio** — Real-time fraud streaming via `publishTxToFluvio({txRef, agentCode, amount, type, timestamp})` 9. **Dapr** — Cross-service pub/sub via `dapr.publishEvent("pubsub", topic, payload)` 10. **Lakehouse** — Analytics pipeline via `ingestToLakehouse(table, data)`

**Optional (context-dependent):**

- **Redis** — Balance cache invalidation via `cacheSet(\`agent:balance:\${id}\`, "", 1)` on balance-affecting mutations

## Environment Setup

- **Primary repo:** `munisp/agentbanking` (default for all work)
- **Branch:** `production-hardened` is the main development branch
- **No live server available** in most sessions — no DATABASE_URL, Redis, or Kafka env vars
- **TypeScript check:** `npx tsc --noEmit` (6 pre-existing client errors in react-i18next and @dnd-kit are expected)
- **Test suite:** `npx vitest run` (5 pre-existing failures in db-performance and sprint46 are expected)
- **Package manager:** pnpm

## Devin Secrets Needed

- `DATABASE_URL` — PostgreSQL connection string (not currently available; testing is shell-based without it)
- No other secrets required for structural validation testing

## Testing Approach (Shell-Based)

### 1. TypeScript Compilation

```bash
npx tsc --noEmit 2>&1 | grep "error TS" | grep -v "react-i18next\|@dnd-kit\|i18next"
```

**Expected:** Zero output (only 6 pre-existing client errors filtered out)

### 2. Vitest Regression

```bash
npx vitest run 2>&1 | grep -E "Test Files|Tests " | tail -3
```

**Expected:** 4,241+ pass, 5 pre-existing failures, no new failures

### 3. Import Completeness Check

Verify all financial routers have required middleware imports:

```bash
for f in cashIn cashOut agentLoanFacility nfcTapToPay dynamicQrPayment stablecoinRails loyalty commissionPayouts crossBorderRemittance multiCurrencyExchange bnplEngine chargebackManagement reversalApproval ecommerceOrders airtimeVending billPayments splitPayments recurringPayments; do
FILE="server/routers/$f.ts"
TB=$(grep -c 'from "../tbClient"' "$FILE")
FL=$(grep -c 'from "../fluvio"' "$FILE")
LH=$(grep -c 'from "../lakehouse"' "$FILE")
DA=$(grep -c 'from "../middleware/middlewareConnectors"' "$FILE")
MISSING=""
[ "$TB" -eq 0 ] && MISSING="$MISSING tbClient"
[ "$FL" -eq 0 ] && MISSING="$MISSING fluvio"
[ "$LH" -eq 0 ] && MISSING="$MISSING lakehouse"
[ "$DA" -eq 0 ] && MISSING="$MISSING middlewareConnectors"
if [ -n "$MISSING" ]; then echo "FAIL $f: missing$MISSING"; else echo "PASS $f"; fi
done
```

### 4. Active Middleware Call Verification

Verify imports aren't dead — each router has actual function calls:

```bash
for f in <router_list>; do
FILE="server/routers/$f.ts"
TB=$(grep -c 'tbCreateTransfer(' "$FILE")
FL=$(grep -c 'publishTxToFluvio(' "$FILE")
DA=$(grep -c 'dapr.publishEvent(' "$FILE")
LH=$(grep -c 'ingestToLakehouse(' "$FILE")
echo "$f: TB=$TB FL=$FL DA=$DA LH=$LH"
done
```

**Pass criteria:** All counts >= 1 for every router.

### 5. Fail-Open Pattern Verification

All extended middleware calls MUST have `.catch(() => {})`. Use Python for multi-line detection:

```python
import re
for fn in ['tbCreateTransfer', 'publishTxToFluvio', 'dapr.publishEvent', 'ingestToLakehouse']:
for m in re.finditer(fn + r'\(', content):
chunk = content[m.start():m.start()+500]
if '.catch(' not in chunk:
print(f'UNCAUGHT: {fn}')
```

**Important:** Do NOT use single-line grep for this — `tbCreateTransfer` spans multiple lines with `.catch` on the closing `})` line. Naive single-line grep will produce false positives.

### 6. GL Account ID Correctness

Use Python regex for reliable multi-line extraction of GL account pairs:

```python
import re
m = re.search(r'tbCreateTransfer\(\{([^}]+)\}', content)
block = m.group(1)
debit = re.search(r'debitAccountId:\s*"(\d+)"', block)
credit = re.search(r'creditAccountId:\s*"(\d+)"', block)
```

**Do NOT use `grep -A3 | grep -oP`** — it captures debit IDs for both fields due to how multi-line grep works.

### 7. Reversible Operation GL Consistency

Verify that payment/refund pairs use reversed GL account IDs:

- cashIn(1001→2001) ↔ cashOut(2001→1001)
- loanDisburse(2001→2004) ↔ loanRepay(2004→2001)
- nfcPayment(1001→2001) ↔ nfcRefund(2001→1001)

### 8. Dapr Topic + Lakehouse Table Uniqueness

```bash
# Dapr topics should be unique and semantic
grep -rn 'dapr.publishEvent("pubsub"' server/routers/ | grep -oP '"pubsub", "[^"]*"' | sort -u
# Lakehouse tables — each should appear in exactly 1 router
grep -rn 'ingestToLakehouse(' server/routers/ | grep -oP 'ingestToLakehouse\("[^"]*"' | sort | uniq -c | sort -rn
```

## Key GL Account IDs

| ID | Name | Usage |
| --------- | ------------------ | ----------------------------------- |
| 1001 | Cash-on-Hand | Cash deposits/withdrawals |
| 1003 | Stablecoin Holding | Crypto-fiat |
| 2001 | Agent Float | Agent balance operations |
| 2004 | Loan Payable | Loan disbursement/repayment |
| 2005 | Loyalty Payable | Points redemption |
| 3001 | Remittance Payable | Cross-border |
| 3002 | FX Conversion | Currency exchange |
| 4001 | Fee Revenue | Transaction fees/commission payouts |
| 4002 | Penalty Revenue | Late penalties |
| 5001-5004 | Expense accounts | Chargebacks, refunds, loyalty |
| 6001 | Interest Expense | Savings interest accrual |

## Middleware Client Files (Function Signatures)

- `server/tbClient.ts` — `tbCreateTransfer(req: TBTransferRequest)` where `debitAccountId` and `creditAccountId` are **strings** (not numbers)
- `server/fluvio.ts` — `publishTxToFluvio({txRef, agentCode, amount, type, timestamp})`
- `server/redisClient.ts` — `cacheSet(key: string, value: string, ttlSeconds?: number)`
- `server/lakehouse.ts` — `ingestToLakehouse(table: string, data: Record<string, unknown>, source?: string)`
- `server/middleware/middlewareConnectors.ts` — `dapr.publishEvent(pubsubName, topic, data)`

## Key Kafka Topics

All financial events publish to `pos.transactions.created` with a `type` field distinguishing event types (e.g., `nfc_payment`, `qr_payment`, `loan_disbursement`, `stablecoin_created`, `loyalty_redemption`).

## Common Issues

- **`ctx.user` has no `agentCode` property** — The tRPC user context type only has `id`, `keycloakSub`, `name`, `email`, `role`, etc. Use `String(ctx.user?.id ?? "system")` instead of `ctx.user?.agentCode`.
- **`CommissionSplit` has no `commission` property** — Use `agentShare`, `platformShare`, `superAgentShare`, or `aggregatorShare` instead.
- **Duplicate schema imports** — If adding `gl_journal_entries` to a file that already imports from `../../drizzle/schema`, consolidate into one import statement.
- **`input.billerCode` doesn't exist** — The billPayments schema uses `billerId`, not `billerCode`. Always check the Zod schema before referencing input fields.
- **`input.amount` doesn't exist on split payments** — splitPayments uses `input.totalAmount` and `input.splits[].amount`. Check the router's input schema.
- **Multi-line middleware calls** — `tbCreateTransfer({...})` spans 4-5 lines. Testing with single-line grep will miss `.catch()` on the closing line. Use Python or multi-line tools.
- **Script-generated code may have wrong variable names** — When using Python scripts to bulk-add middleware, the script may use generic `ref` or `input.amount` variables that don't exist in the target router's scope. Always verify with `npx tsc --noEmit` after scripted changes.
- **Pre-existing TS errors** — 6 errors in `client/src/components/LanguageSelector.tsx` and `client/src/pages/POSShell.tsx` for missing `react-i18next` and `@dnd-kit` type declarations. These are NOT from your changes.
- **Pre-existing test failures** — `db-performance.test.ts` (4 failures, fetch failed) and `sprint46.test.ts` (1 failure, activePairs 48 vs expected 42).

## POS Router Middleware Testing

POS routers (posTerminalFleet, posBatchSettlement, posFirmwareOTA, posDispute, canaryReleaseManager, deviceFleetManager, mdm, terminalLeasing) use a `publishPosMiddleware` helper pattern instead of inline calls:

```ts
function publishPosMiddleware(eventType: string, key: string, payload: Record<string, unknown>) {
publishEvent("pos.<domain>", key, { eventType, ...payload });
fluvioPublish("pos.<domain>", { key: "pos", value: JSON.stringify({...}) }).catch(() => {});
dapr.publishEvent("pubsub", "pos.<domain>.updated", {...}).catch(() => {});
lakehouseIngest("pos_<table>", {...}).catch(() => {});
}
```

**Critical test:** Verify the helper is actually CALLED from mutation handlers, not just defined. Use:

```bash
DEFN=$(grep -c 'function publishPosMiddleware' "$FILE")
TOTAL=$(grep -c 'publishPosMiddleware' "$FILE")
CALLS=$((TOTAL - DEFN))
# CALLS must be >= 1 — if 0, the helper is dead code
```

**Fluvio shape:** POS routers use `fluvioProduce` (aliased as `fluvioPublish`) which requires `FluvioRecord = {key?: string, value: string}`. This is different from `publishTxToFluvio` used by fund flow routers. Verify all calls pass `{ key: "pos", value: JSON.stringify(...) }`.

**KafkaTopic:** POS topics must be in the KafkaTopic union in `server/kafkaClient.ts`. Check for all 13: pos.terminal.fleet, pos.batch.settlement, pos.firmware.ota, pos.dispute, pos.mdm, pos.terminal.leasing, pos.canary.release, pos.device.fleet, pos.card.payment, pos.eod.reconciliation, pos.geo.velocity.alert, pos.ota.delta.requested, pos.canary.rollback.

## Polyglot Service Persistence Testing

When verifying Go/Rust/Python services have no in-memory state:

| Language | In-Memory Red Flags | PostgreSQL Green Flags |
| -------- | ------------------------------------------------- | -------------------------------------------------------------------- |
| Go | `var x map[...]` (exclude static config) | `"database/sql"`, `lib/pq`, `db.Query/Exec` |
| Rust | `Mutex<Vec/HashMap>`, `static mut`, `lazy_static` | `PgPool`, `sqlx::query`, `ON CONFLICT` (UPSERT) |
| Python | Module-level `dict/list/set` assignments | `import asyncpg`, `CREATE TABLE IF NOT EXISTS`, `conn.execute/fetch` |

**False positives to exclude:** Go `allPermissions`/`allRoles` (static config), Python `_pool: Optional[asyncpg.Pool]` (connection pool, not state), Rust `web::Data<AppState>` with only PgPool (infrastructure, not state).

## Recording

No recording needed for fund flow testing — all validation is shell-based. Only record if testing involves browser UI interactions (e.g., testing the PWA QR scanner page or NFC settings dashboard).
Loading
Loading