Payment Intelligence Modules is a static, browser-only suite for inspecting and anonymising ISO 20022 payment data without uploading customer or counterparty data.
For the latest repo/session handoff, start with HANDOFF.md.
The root suite remains static and browser-only. Standalone adjacent applications live under apps/** as separate, explicitly scoped apps; they are not Payment Intelligence modules and are not part of the root browser runtime.
| Module | Route | Status | What it does |
|---|---|---|---|
| Scrubber | /scrubber |
Available | Strip personally identifying fields from pacs.* / camt.* XML before sharing with peers or vendors. Produces a privacy-safe mapping summary. |
| Storyteller | /storyteller |
Available | Turn a pacs.002 / 004 / 008 / 009 or camt.052 / 053 / 054 message into a plain-language narrative plus a structured field projection and quick insights. |
| IBAN Workbench | /iban |
Available | Validate, build, catalogue, and trace provenance for IBANs from bundled SWIFT IBAN Registry-derived data. Builder computes MOD-97 check digits from exact-length BBAN fields; no live BIC, VOP, account existence, or reachability checks. |
| BIC Validator* | /bic |
Demo | ISO 9362 syntax checks plus a tiny bundled snapshot lookup. Demonstration only: bundled BIC data is not accurate/current enough for production, routing, compliance, reachability, or payment decisions. |
| CBPR+ Readiness Checker | /cbpr |
Available | Browser-only AppHdr / Document namespace / CBPR+ schema-profile coverage checks, plus UETR, BIC syntax, and IBAN syntax/checksum hints. Not a certified validator or MyStandards usage-rule engine. |
| Payment Insights Lite | /insights |
Available | Local lifecycle insight over ACK/NACK, pacs.*, and camt.* files you provide. Groups files by identifiers in memory; not live payment tracking, VOP, reachability, or settlement monitoring. |
| Vault | /vault |
Prototype | User-controlled encrypted local export/import prototype using browser crypto and file download/import only; no cloud vault, no server storage, and no persistent browser storage by default. Security threat model still required before sensitive use. |
*The BIC module intentionally does not perform live BIC Directory lookup, current bank-directory enrichment, current SEPA reachability checks, SWIFT FIN reachability checks, Verification of Payee, or account-owner/name matching.
SSI Control Tower is not a Payment Intelligence module or workflow. It is a
standalone adjacent app under apps/ssi-control-tower/, with its own
FastAPI/Jinja runtime, Python dependencies, tests, and synthetic fixtures. It is
intentionally absent from the suite navigation and the home launcher.
The root browser suite keeps /ssi only as an unlinked static boundary pointer:
it documents the boundary, stays fetch-free, iframe-free, storage-free, and
telemetry-free, and does not link to localhost. Repo extraction and the
product-boundary decision for the standalone app are still pending.
The standalone app runs separately:
cd apps/ssi-control-tower && make run # serves http://localhost:8000This is the load-bearing property of the suite, not a footer line:
- All parsing, validation, explanation, and rendering happens in the browser using platform APIs and pure JS/TS.
- In the root browser-suite runtime, there is no backend API. No analytics, no telemetry, no error reporting, no remote logging.
- No persistence —
localStorage,sessionStorage,indexedDB, and cookies are never written. - The only network calls made by the app are same-origin requests for sample
fixtures shipped under
/samples/**. - Any text you paste, any file you open, any output you generate stays on your device until you copy it out or download it yourself.
These rules are enforced in CI by
scripts/privacy-audit.sh, which fails the build if
banned APIs or absolute-URL fetch calls appear under src/.
- IBAN: uses generated browser data derived from the curated SWIFT IBAN
Registry material available to the project, with deterministic metadata beside
the generated JSON.
/ibanexposes Validate, Build, Catalogue, and Provenance panels; Build derives MOD-97 check digits locally from exact-length BBAN fields and still does not perform account existence, VOP, live BIC, or reachability checks. - BIC: uses a deliberately tiny, allowlisted demo snapshot plus source-snapshot country-code evidence for shape feedback. It is snapshot-bound and not a replacement for a current BIC Directory feed/update process.
- CBPR+: uses a generated browser manifest derived read-only from the bundled MyStandards/SWIFT CBPR+ SR2025 schema archive. The shipped checker performs local readiness/structure checks only; it is not a certified validator, not a full XSD validation engine, and not a MyStandards usage-rule engine.
- Payment Insights Lite: derives local lifecycle threads from ACK/NACK,
pacs.*, andcamt.*files the user provides in the browser. It is not live payment tracking, settlement monitoring, VOP, SEPA reachability, or live bank lookup. - SSI Control Tower: the standalone adjacent app under
apps/ssi-control-tower/uses synthetic fixtures plus a sanitized public-evidence sidecar from official bank SSI/wire/settlement pages. The sidecar stores only bank name, URL, title, and abstract field categories; no account numbers, IBANs, BICs, routing codes, correspondent chains, excerpts, hashes, or real SSI values are committed. - VOP / Verification of Payee: out of scope for the offline suite because it requires live certified EPC access.
- Current SEPA reachability, bank address enrichment, and live BIC validation: out of scope unless a separate live-feed/API product is explicitly approved.
- Node.js >= 20
- pnpm >= 9
For the standalone SSI Control Tower adjacent app only:
- Python 3.11
- Run commands from
apps/ssi-control-tower/; the standalone app owns its ownpyproject.toml,Makefile, tests, and SQLite development data.
pnpm install
pnpm dev # Vite dev server on http://localhost:5173
pnpm typecheck # tsc -b without emit
pnpm lint # ESLint
pnpm format:check # Prettier check (read-only)
pnpm format # Prettier write
pnpm test # Vitest unit tests (single run)
pnpm test:e2e # Playwright end-to-end (boots dev server)
pnpm audit:privacy # Fail on banned browser-storage / external-fetch usage in src/
pnpm data:iban # Regenerate generated IBAN registry data
pnpm data:iban:check # Verify generated IBAN registry data matches script output
pnpm data:bic # Regenerate generated BIC demo snapshot data
pnpm data:bic:check # Verify generated BIC demo snapshot data matches script output
pnpm data:cbpr # Regenerate generated CBPR+ schema-profile manifest data
pnpm data:cbpr:check # Verify generated CBPR+ manifest data matches script output
pnpm build # Type-check then produce a static, host-agnostic bundle in dist/
pnpm preview # Preview the production bundle locally
pnpm verify # lint + format:check + typecheck + test + privacy/data checks + build- Vite + React 18 + TypeScript strict mode
- Tailwind v3 with light fintech tokens in
src/index.css, derived fromDESIGN.md - React Router for
/,/scrubber,/storyteller,/iban,/bic,/cbpr,/insights,/ssi, plus a*fallback - Vitest + Testing Library for unit/page tests
- Playwright for end-to-end smoke tests
- ESLint + Prettier
- GitHub Actions CI: install → lint → format:check → typecheck → test → audit:privacy → data checks → playwright install (with deps) → e2e → build
src/
App.tsx # route table
main.tsx # entry point
index.css # Tailwind layers + light fintech design tokens
version.ts # SUITE_VERSION constant (kept in sync with package.json)
components/
bic/ # BIC demo validator UI primitives
iban/ # IBAN Workbench UI primitives
layout/
SuiteLayout.tsx # shell with skip link, header, outlet, footer
SuiteHeader.tsx # wordmark + primary nav
SuiteFooter.tsx # version + browser-only privacy tag
ModuleLayout.tsx # per-module page chrome
scrubber/ # Scrubber-specific UI primitives
storyteller/ # Storyteller-specific UI primitives
ui/
SampleSelect.tsx # shared "load sample" dropdown
pages/
HomePage.tsx # suite overview, privacy banner, modules, "How it works"
BicPage.tsx
CbprPage.tsx
IbanPage.tsx
ScrubberPage.tsx
SsiPage.tsx # unlinked static boundary pointer to the standalone SSI app
StorytellerPage.tsx
NotFoundPage.tsx
lib/
bic/ # browser-only BIC syntax/demo snapshot helpers
cbpr/ # browser-only CBPR+ readiness checks + generated manifest
iban/ # browser-only IBAN validate/build/catalogue/provenance helpers
iso20022/ # Scrubber parsing/rewriting (no UI deps)
storyteller/ # Storyteller parsing + narrative builders
utils.ts # cn() helper
public/
favicon.svg
samples/** # bundled fixtures served same-origin
e2e/
bic.spec.ts
iban.spec.ts
smoke.spec.ts
scrubber.spec.ts
storyteller.spec.ts
scripts/
build-bic-snapshot.ts
build-cbprplus-schema-manifest.ts
build-iban-registry.ts
privacy-audit.sh
apps/
ssi-control-tower/ # Standalone adjacent FastAPI/Jinja SSI app; not a Payment Intelligence module
app/ # Python app, routers, services, web templates
data/ # Synthetic fixtures/reference YAML only; local DBs ignored
docs/ # SSI docs including sanitized public-source evidence methodology
tests/ # pytest suite for the standalone SSI app
pyproject.toml # Python dependencies owned by the nested module
Makefile # module-local test/install commands
The build output in dist/ is a static SPA with root-relative asset paths
(vite.config.ts declares base: "/"). It is host-agnostic.
To deploy on any static host, the host must:
- Serve the contents of
dist/from the site root. - For unknown / deep-link routes (for example
/scrubber,/storyteller,/iban,/bic,/cbpr,/insights,/ssi, or/anything-else), fall back to servingindex.htmlso React Router can resolve the route on the client. This is sometimes called "SPA fallback" or "rewrite all to index.html". - Not require any server-side execution for the root static SPA. There is no root API.
- Preserve the privacy posture: no analytics injection, no remote logging, and no third-party scripts added by the host configuration.
This repo intentionally does not ship host-specific configuration files
(_redirects, 404.html copy, vercel.json, netlify.toml, wrangler.toml,
etc.). A specific host and its matching SPA-fallback artifact will be added in a
later, focused step once a deployment target is approved.
See ROADMAP.md for the current shipped baseline, recommended next modules, deployment decision points, and out-of-scope live/certified capabilities.
See BACKLOG.md for candidate modules and shared UX patterns under consideration.
Tokens are HSL triplets defined in src/index.css and consumed via Tailwind's
hsl(var(--token)) pattern. The suite ships a single light fintech canvas — no
theme toggle.
| Token | HSL |
|---|---|
| background | 210 20% 98% |
| foreground | 222 46% 11% |
| card | 0 0% 100% |
| primary | 199 91% 36% |
| primary-foreground | 0 0% 100% |
| muted | 210 40% 96% |
| muted-foreground | 215 16% 47% |
| accent | 185 82% 43% |
| accent-foreground | 201 90% 27% |
| border | 213 22% 90% |
| destructive | 0 75% 62% |
| ring | 199 91% 36% |
| radius | 0.875rem |
color-scheme: light is set globally. Visual direction and component guidance
are documented in DESIGN.md.
The suite uses a system font stack with Inter / Plus Jakarta Sans / JetBrains Mono / Fira Code listed first, so locally-installed copies are picked up automatically without any external CDN. No remote fonts are loaded.
MIT — see LICENSE.