DuoCount
Countersigned cash, scratch-off and inventory counts for multi-site retail.
Overview
A multi-tenant app where a retail business registers its locations, named cash drawers and tracked inventory items, then has staff log opening and closing counts under a PIN. Managers verify each count; an analytics dashboard breaks activity down by day, employee, drawer, item and location. Each business's data is isolated by Firestore security rules keyed on server-issued auth claims.
The problem
Retail shrink is discovered late, if at all. Counts live on paper or in a spreadsheet one person controls, so a missing amount cannot be tied to a shift, a drawer or a person — and nothing stops the record being edited after the fact.
The approach
An append-only log is the trust spine: staff sign counts with a per-employee PIN, managers verify them, and nothing is editable afterwards. Multi-tenancy is enforced at the database, not in the app — signing in mints a Firebase custom token whose claims carry the vendor, role and location, and Firestore rules only serve requests whose token vendor matches the data's, so one business cannot read another's logs even from dev tools. PINs are stored as salted scrypt hashes.
Outcome
- Three kinds of count — cash drawers, scratch-off packs and shelf counts of high-shrink items — share one verification flow, one log and one dashboard, with no special cases per kind.
- Owners choose whether locations see each other's logs: Shared, or per-location with managers and owners always seeing everything.
- English and Spanish reach full parity in the app, including a low-literacy count path — the repo's reasoning being that a monitoring notice a Spanish-first clerk can only read in English is not notice.
- A measured WCAG AA contrast audit across both themes is recorded in docs/, with the failures found and the token fixes shipped.
- Paper backup logs are generated on demand and branded with the signed-in store, so there are no static PDFs to keep in sync.
What it does
Countersigned counts
Opening and closing counts are signed, timestamped and append-only; a manager verifies another person's count rather than their own.
Per-business isolation
Every business lives under its own Firestore path, guarded by rules keyed on server-issued token claims rather than on client-side checks.
Reporting and accountant export
Reports for any period — daily through annual, custom and fiscal-year — as PDF, CSV and print, plus close-of-day and journal exports for an accountant.
Bulk import
Owner-only CSV import for items, staff and opening baselines, so a store can migrate off paper or Excel without re-keying.
Multi-store rollup
A portfolio view across a vendor's locations for owners running more than one site.
Ask about DuoCount
Want something like this, or curious how a piece of it works? Send a note — it reaches me tagged with this project, so I have the context before I reply.