8b1e38cb4df8630abc7397974002ece1042c059c
Features - Payment reminders via Resend (candidates, send, history, test email) - Bulk import of the customer list from Excel/CSV in the dashboard - Dashboard i18n (en/nl) with language selector Security - Enforce venue isolation on all /venues/:venueId routes - Require admin for planned-tab changes and pairing codes - Rate-limit login and device registration; opt-in TRUST_PROXY - Require JWT_SECRET in production; stop leaking internal errors - Escape customer names in reminder emails Sync and commands - Remove tabs the terminal no longer reports; validate nested sync payload - Return all pending commands on every sync (fixes missed-command race) - First command ack wins; atomic registration code claim - Reject commands for revoked devices, stale versions or duplicates - Remind only unpaid balances, with a 7-day cooldown Dashboard - Share a single token refresh across concurrent 401s (random logouts) - Keep the session alive for the refresh token lifetime Deployment - Replace `db push --accept-data-loss` with migrations (baselines legacy DBs) - Set NODE_ENV=production; pass Resend and TRUST_PROXY env in prod compose
KoolTab Remote Tab Control
A production-quality remote tab control system for venues. Allows bar staff to manage and close tabs remotely from a web dashboard, with commands delivered to bar terminals via a sync API.
Architecture
- Monorepo managed with pnpm
- NestJS backend API with Prisma ORM (SQLite for dev, PostgreSQL-ready)
- Next.js dashboard with App Router, TanStack Query, and shadcn/ui
- Shared TypeScript types package
apps/
api/ # NestJS backend
dashboard/ # Next.js frontend
packages/
shared/ # Shared types & constants
scripts/
device-sync.ts # Device simulator
docs/
api.md # API documentation
architecture.md
architecture-decisions.md
local-development.md
testing.md
production.md
security.md
Requirements
- Node.js >= 18
- pnpm >= 8
Quick Start
# 1. Install dependencies
pnpm install
# 2. Generate Prisma client
cd apps/api
pnpm db:generate
# 3. Run migrations
pnpm db:migrate
# 4. Seed demo data
pnpm db:seed
cd ../..
# 5. Start both API and Dashboard in dev mode
pnpm dev
API runs on http://localhost:3001 Dashboard runs on http://localhost:3000 Swagger docs at http://localhost:3001/api/docs
Demo Credentials
| Role | Password | |
|---|---|---|
| Admin | admin@example.com | Admin123! |
| Viewer | viewer@example.com | Viewer123! |
Device Simulator
# Run a full demo (register, sync, ack)
cd scripts
npx ts-node device-sync.ts demo <venueId> <registrationCode>
# Or step by step:
npx ts-node device-sync.ts register <venueId> "Bar Terminal 1" ABC123
npx ts-node device-sync.ts sync <deviceId> <token>
npx ts-node device-sync.ts ack <deviceId> <token> <commandId> completed
Running Tests
# Unit tests
pnpm test
# E2E tests
pnpm test:e2e
Docker
docker compose up
Production Notes
See docs/production.md for production deployment and SQLite → PostgreSQL migration guide.
Languages
TypeScript
98.2%
JavaScript
0.6%
HTML
0.5%
Dockerfile
0.4%
CSS
0.3%