● Confidential — technical partner brief · not for distribution

Technical partner brief · full honest audit
This is the engineer's version: the goal, the money, the dead incumbent we're replacing, exactly what's real vs. prototype vs. vapor, the full feature universe, the idea backlog, the unsolved hard problems, and the legal landmines. Written to be argued with — poke holes, out-invent it, make it yours. Nothing below is sacred except the two rules at the end.
A companion system that sits beside any venue POS (never replaces it) and runs the dancer economy, the door, and the operational cash — with every money flow reconciled against an independent second source, so an owner never wonders who's stealing. Beachhead: gentlemen's clubs (~2,000–4,000 US). First target: Sapphire (Vegas + NYC) — their GM described this product to Rigo unprompted, and the old Club Trax tech is now their IT guy.
Club Trax ran entertainer ops in clubs for ~20 years: dancer check-in, dance-dollar scrip, house fees, payouts, even fingerprint login — on Windows, in 2003. The vendor is gone (site dead since ~2016, trademark cancelled 2023). Demand proven, competitor deceased, modern players (SmartTab et al.) ship generic bar POS with zero entertainer tooling. We tore down the real 2003 UI screen by screen and built a feature-parity tracker — both linked below.
Three tiers. Real = working code, tested, most of it running against the live DB. Prototype = looks real, faked logic. Schema-only = table exists, no code reads it. As of today: 39 unit tests passing, typecheck clean, 31-model schema migrated to a live Postgres (Neon).
| Piece | Status | Truth |
|---|---|---|
| Money engine core — append-only postings, signed credit/debit math, reversal-as-correction, debit-requires-reason | Real | Pure functions, integer cents, fully unit-tested (src/lib/ledger/postings.ts) |
| Dance dollars — mint/sell/redeem/reconcile + can't-redeem-more-than-sold | Real | End-to-end on the live DB. Race-guarded (conditional updates), money writes on the audit chain. Second-pass review (Fable) found + fixed two real concurrency bugs here. |
| Nightly payout — ledger → payout snapshot, never recompute a finalized payout | Real | Pure computation + service just landed; snapshot model (ledger stays source of truth) |
| Security foundation — field encryption (AES-GCM + KMS envelope), blind index, audit hash chain, argon2 auth, lockout, JWT | Real | Built + unit-tested. Auth routes exist; end-to-end wiring needs Redis decision. |
| Database — 31 models: org/locations, entertainers, ledger, VIP, patrons, payouts, exceptions, fee rules, scrip, staff… | Real | Live on Neon (migration applied). But most tables have no service code yet. |
| The 9 screens — door, check-in, rotation, VIP watchdog, house account, cage, driver payouts, owner dash, chargebacks | Prototype | Clickable HTML on sample data. Zero of them talk to the backend. |
| Reconciliation flows — the actual product promise | 2 of ~5 | Dance dollars ✓, payout-vs-ledger ✓. Not built: VIP-vs-ledger, taxi-vs-door-count, orphaned-POS-sale, exceptions engine. |
| Cage Lock (owner approves payout release), exceptions engine, credentials blocking clock-in, stage rotation, staff | Schema-only | Flags/tables exist; nothing reads them yet. |
| The door — AAMVA ID parse, 86'd match, fake-ID vendor | Not built | Plan: open-source PDF417/AAMVA parse + our banned-match; white-label Intellicheck/IDScan.net for document authentication. |
| POS integration — read-only mirror (Clover first, then SkyTab/Toast) | Not built | Mirror tables exist (Clover-named — should be generalized with a pos_type). Must work standalone with no POS at all. |
| Tablet app (React Native, iPad) + offline sync | Not built | Offline "payout-authority device" model is designed, not written. |
| Payments — card-anchored digital dance dollars on our rail | Not built | Boarding is solved (Rigo's lane). Integration is greenfield. |
Money math lives in pure, dependency-free functions in integer cents — exhaustively unit-testable, no DB required — and the service layer converts at the boundary and persists atomically. The ledger is append-only; corrections are reversing entries; every money write lands on a tamper-evident hash chain. Everything correctness-critical is testable without standing up infrastructure.
Stack: Node 24 · TypeScript · Fastify · Prisma → Postgres (Neon, AWS-backed) · vitest Web: Cloudflare Pages (public site + this confidential tier) — $0/mo today src/lib/ledger/ postings · danceDollars · payout ← pure money engine (tested) src/lib/ crypto (AES-GCM+KMS envelope, blind index) · auditHash · tokens · password src/modules/ auth · danceDollars · payouts ← services on the live DB docs/ the 9 prototype screens + the site ← not wired to any of the above prisma/ 31 models, migrated + live
The data model is the map of the whole product — 31 models, live, most waiting for their code:
Core: Organization · Location (POS creds, business-day cutoff, biometric+retention
config, cageLockEnabled) · User (roles: owner/manager/staff/auditor, PIN) · UserLocation
Dancers: Entertainer (encrypted legal name/phone/SSN, W-9, suspended) · EntertainerShift
· EntertainerAgreement · Credential (work-card expiry → blocks clock-in)
· EntertainerCharge/Payment (the house account "Amount Due") · EntertainerFeeRule
Money: LedgerEntry (append-only, reversals, reason codes) · NightlyPayout (snapshot)
· NightlySettlement (Cage Lock) · DrawerSession/CashMovement (the house bank)
· SoftwareFeeLedger (our own billing) · LocationFeeRule (fees by day/time)
Scrip: DanceDollarBatch (denomination, surcharge, serials) · DanceDollarTicket (single-use)
Floor: VipRoom/VipRoomSession (timers→ledger link) · StageRotation · Staff/StaffShift
Door: PatronProfile (encrypted PII + blind-index lookup) · PatronAgreement (signed spend)
POS: CloverOrderMirror/PaymentMirror (read-only; to be generalized pos_type)
Truth: AuditLog (hash chain) · Exception (ORPHANED_SALE, drawer variance, VIP overrun…)
The complete map — Club Trax parity plus everything it never dreamed of. Most of this has schema waiting; almost none has code. This is the canvas.
Ideas we've collected but not committed — some from our own recon, some adopted from adversarial reviews of the spec. None of this is sacred. Improve it, kill it, out-invent it.
| Landmine | Why it's real | Design consequence |
|---|---|---|
| Dancer misclassification | Sapphire LOST Terry v. Sapphire (Nev. 2014) — dancers ruled employees. Our deduction ledger is discoverable evidence. | Debits are "lease adjustments," never "fines"; every deduction requires a reason; wording never says "hired/employee." |
| Biometrics (BIPA etc.) | Club Trax used fingerprint login — that's a class-action magnet now. Face photos on patron profiles are borderline. | PIN auth, biometric features per-location toggleable, consent captured, jurisdiction-aware. |
| Dance-dollar sales tax | RCI (biggest club chain) was indicted over ~$8M unpaid sales tax on Dance Dollars. | Scrip engine should track taxability per jurisdiction — a compliance feature nobody else has. Sales angle, not just risk. |
| Adult-vertical payment bans | Stripe/PayPal ban adult businesses — even for OUR OWN billing of clubs. | Rail choices vetted for the vertical; Rigo's high-risk lane is the answer, code must not assume mainstream PSPs. |
| ID data retention | Scanned licenses = a breach jackpot; laws differ NV vs NY. | The retention "shredder" is configurable per location; encrypt everything; keep the minimum. |
| "100% fraud-proof" is a lie | Pure off-books cash that never touches the system can't be caught by software. | We never claim it. The honest claim: anything that touches the system is locked, attributed, reconciled — fraud can't happen silently. |
Target: Sapphire pilot in ~3–4 months, MVP-first (door + dance dollars + payouts + reconciliation), proven by a 2-week parallel run against paper. Governing rule from Rigo: correctness over timeline — penny-perfect, survives 8pm–4am and an internet drop. Second governing rule: no feature ships without its independent-source reconciliation.
Powered by NightLedger