NightLedger — Technical Partner Brief

● Confidential — technical partner brief · not for distribution

NightLedger

Technical partner brief · full honest audit

The state of NightLedger — no varnish.

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.

00 / The goal

Run the club the POS can't — and own the payment rail under it.

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.

SaaS
per location/mo
Dancer-economy card volume
~5% flat (SmartTab charges this today)
Tickets
$1 each
Chargeback pkg
$5 each
Processing residual
the annuity
The real business: software wins the club; the processing residual pays for years. Rigo is a high-risk processor — he boards the adult MID himself in under a week, which no software competitor in this vertical can do. The code's job is to make the rail un-leaveable: once it runs payouts and the floor at 3am, switching processors means ripping out the club's operating system.
01 / The incumbent

We're replacing abandonware the industry still misses.

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.

What Club Trax got right (we copy)
  • Dancer check-in/out + hours as the spine
  • Dance-dollar scrip with serials + batch control
  • House account — the running "Amount Due"
  • Work-card expiry blocking clock-in
  • Stage rotation
  • Nightly payout with a paper trail
Where it was dangerous (we fix)
  • Fingerprint login → PIN (BIPA/biometric liability)
  • Plaintext SSNs → field-level encryption + blind index
  • Editable history → append-only ledger + hash-chain audit
  • "Fines" wording → lease adjustments + required reason (misclassification defense — Sapphire lost Terry v. Sapphire)
  • One Windows box in the office → cloud + iPads, owner sees it from home
  • No payments → integrated card rail (the business model)
02 / Honest state

What's real, what's prototype, what's vapor.

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).

PieceStatusTruth
Money engine core — append-only postings, signed credit/debit math, reversal-as-correction, debit-requires-reasonRealPure functions, integer cents, fully unit-tested (src/lib/ledger/postings.ts)
Dance dollars — mint/sell/redeem/reconcile + can't-redeem-more-than-soldRealEnd-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 payoutRealPure 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, JWTRealBuilt + 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…RealLive 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, chargebacksPrototypeClickable HTML on sample data. Zero of them talk to the backend.
Reconciliation flows — the actual product promise2 of ~5Dance 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, staffSchema-onlyFlags/tables exist; nothing reads them yet.
The door — AAMVA ID parse, 86'd match, fake-ID vendorNot builtPlan: 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 builtMirror 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 syncNot builtOffline "payout-authority device" model is designed, not written.
Payments — card-anchored digital dance dollars on our railNot builtBoarding is solved (Rigo's lane). Integration is greenfield.
03 / Architecture

Boring on purpose, correct by construction.

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…)
04 / The full feature universe

Everything the product wants to be.

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.

The dancer economy
  • Check-in/out with hours — emailed to her for her own 1099 records
  • House account — running "Amount Due" — pay / defer / NSF, carries night to night
  • Fee rules per location AND per dancer — varying by day/time; waivable with manager PIN + reason
  • Stage rotation — who's on, who's next, missed calls
  • VIP room timers with over-time alarm — session → ledger → POS, three-way
  • Dance-dollar scrip — batches, serials, surcharge, single-use
  • Driver/taxi payouts per head — clubs pay $25/head; reconciled vs door scans
  • Work-card/sheriff-card expiry blocking clock-in
  • Suspended flag, W-9/1099 records, agreements on file
  • Nightly payout + signed slip; negative payout handled (she owes the house)
The door & patrons
  • AAMVA PDF417 ID scan — identity, age, expiry
  • Fake-ID authentication — white-label vendor under our UX
  • 86'd list with full-screen alert — per-org at MVP; cross-venue opt-in later (legal minefield, casino-style)
  • VIP recognition at the door — visits, spend, status
  • Signed spend agreements captured at the table
  • Chargeback evidence packages — ID + agreement + timestamps + session → one PDF, $5/pkg
  • SMS 2FA on big spends
  • Configurable retention "shredder" for ID images — jurisdiction-aware
Money & anti-theft
  • Append-only ledger; corrections = reversing entries only
  • Hash-chain audit — insiders with DB access can't rewrite history silently
  • House/cashier bank sessions — expected vs counted, variance flags
  • Orphaned-sale catch — POS order closed but never tied to a dancer → owner flag
  • Cage Lock — owner remote-approves the night's payout release from his phone
  • Exceptions engine — every anomaly auto-surfaced, none buried
  • Manager-PIN attribution on every money action; separation of duties
Back office & ops
  • Owner dashboard from home — tonight live, multi-club, one screen
  • Reports + one-click accountant export; regulatory export
  • Staff (non-dancer) clock-in — bartenders, security, DJs, cashiers
  • Our own billing ledger — SaaS + $1/ticket + $5/chargeback, self-reconciling
  • Multi-tenant: org → locations, NV + NY jurisdictions from day one
05 / The idea backlog

Territory to get creative in.

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.

Money & payments (the prize)
  • Digital dance dollars — card-anchored QR/token scrip. The card sale IS the independent "sold" anchor, and it moves the volume onto our rail. Server-authoritative, single-use, redeemed≤sold. Hybrid path: physical scrip sold on card first, fully digital later.
  • Dedicated POS custom tender for scrip — makes the register itself the independent sold-source
  • Digital dancer payouts to her debit card — $1–2/payout fee, instant-pay as a perk
  • VIP/dance processing in-app — the app as payment terminal in VIP rooms, not just tracker
  • Tip reassignment via ledger correction — never touching the POS record
Fraud & trust
  • Hard-stop (not just flag) when redeemed > sold
  • 60-second idle auto-logout on floor devices
  • Turnstile/door-count vs cover charges — the cover-charge theft vector
  • Cross-venue ban network — "assault a dancer in one state, flagged in another"; opt-in, casino-model, needs counsel
  • Anomaly patterns: same manager voiding, variance streaks, after-cutoff entries
The dancer's side
  • Her own PIN-guarded view — hours, earnings, balance (privacy from other dancers)
  • Hours + earnings emailed nightly for her own records
  • Instant digital payout as a recruiting pitch for clubs — "dancers prefer working where the money's clean"
Beyond the beachhead
  • Nightclubs/bars: door + patron + cash modules stand alone (entertainer module optional)
  • Festival / bar-crawl multi-venue voucher module (deferred, same scrip engine)
  • Participants+fee-rules abstraction — generalize entertainer→"participant" when venue type #2 arrives, not before
06 / Hard problems worth your brain

The unsolved stuff — where a real engineer moves the needle.

Correctness under chaos
  • Offline-first at 2am — internet drops mid-shift; payouts can't stop. Designed answer is a "payout-authority device" (provisional → finalized on reconnect). Is that right? CRDTs? Event-sourced queue? Your call to make.
  • Idempotency everywhere — double-taps on a cage tablet must never double-pay. Race-guards exist on scrip; the pattern needs to be systemic.
  • Postgres vs. dedicated ledger engine (TigerBeetle/Formance) for the money core.
  • Business-day boundary — 1am belongs to yesterday's shift; every reconciliation respects the cutoff.
The physical world
  • Thermal printers (Star/Epson) driven from iPads — independent of the club's POS, keeps working when Clover dies
  • Barcode/QR scanning — camera vs. dedicated Bluetooth 2D at a dark, busy door
  • Signature capture on-device for slips + spend agreements
  • PDF generation — payout slips, chargeback evidence packages, 1099 exports
  • Device fleet — MDM, kiosk-mode, 60s auto-logout, a dropped iPad mid-shift
Integration
  • POS adapters as a pluggable read-only interface — Clover first, SkyTab/Toast next, and standalone-with-no-POS must always work
  • High-risk payment-gateway integration — boarding is solved (Rigo's lane); the code isn't. Stripe bans adult — rail choice matters even for our own SaaS billing.
  • ID-verification vendor SDK under our door UX
Security & scale
  • Multi-tenant isolation — org/location scoping everywhere, RLS as backstop
  • KMS envelope encryption in production (dev uses a local master key)
  • Blind-index search over encrypted PII — already built, extend the pattern
  • The audit chain at scale — per-org chains, verification jobs, alerting on a broken link
07 / Constraints to design around

The landmines. Respect these while being creative.

LandmineWhy it's realDesign consequence
Dancer misclassificationSapphire 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 taxRCI (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 bansStripe/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 retentionScanned 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 liePure 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.
08 / The build queue

What's next, in order — and where you plug in.

Now — the correctness heart
  • Remaining reconciliation flows: VIP-vs-ledger, taxi-vs-door, orphaned-POS-sale
  • Exceptions engine (the fraud-flag pipeline to the owner)
  • Cage Lock enforcement + signed-slip PDF
  • Wire auth end-to-end (Redis decision)
Then — make it usable
  • API routes for the built services; screens → real backend
  • The door: AAMVA parse + 86'd match + vendor fake-ID
  • iPad app + offline sync
  • Card-anchored digital dance dollars on our rail
  • POS mirror adapter #1 (generalized, not Clover-hardcoded)

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