Tickets
What it does
This isn't an issue tracker — despite the name, a "ticket" here is a physical numbered card. Cafes that rent out board games hand customers a card (often an RFID card) to identify their table's rental, and each card prints a friendly number like "Ticket 01" that staff and customers can both read. The Tickets feature is a small registry that maps the two: the raw code an RFID scanner reads off the card (RFID-0001) to the printed number a human actually sees (Ticket 01). Managing tickets means keeping that list in sync with the physical cards the shop owns — add one when a new card is printed, rename or retire one if a card is replaced.
The payoff shows up entirely inside the rental workflow. When staff scan or type a card's code during check-in, the system resolves it against this registry and confirms the match live — a green "→ Ticket 01" if it's recognized, a yellow warning if the card isn't registered — but never blocks the check-in either way. Whatever ticket name was resolved at that moment is stamped onto the rental and carried through to the transaction note at checkout (e.g. "Ticket 01 – 2 hour(s)"), so the receipt says which table's rental a line item belongs to.
Why it matters
A scanned RFID code is meaningless to a person — nobody wants to see "RFID-0001" on a receipt or a rental list. But the printed number alone isn't enough either, because a lost or damaged card eventually gets reissued with a new physical code while the shop still wants to call it "Ticket 01" on the floor. Keeping the code and the name as two separately-managed fields is what lets a card be swapped out without staff having to relabel anything or worry about mismatched receipts.
Just as importantly, resolution never blocks operations: if a card is scanned that isn't in the registry, check-in still proceeds — the rental simply carries the raw code instead of a friendly name until someone registers it. And because the resolved name is snapshotted onto the rental the moment it's checked in, renaming or retiring a ticket later never rewrites a receipt or rental record that already used it — exactly the same frozen-snapshot guarantee used everywhere else in the product, from stock checks to checklist sessions.
Screenshot

Key capabilities
- Code ↔ name registry — each ticket is just a scanner code and a printed name, both required and globally unique, so neither one can accidentally point to two different physical cards.
- Live resolution at rental check-in — as staff scan or type a code, the rental check-in form instantly shows the matching ticket name or flags the code as unregistered, with no lookup step required.
- Never blocks check-in — an unrecognized code doesn't stop a rental from being created; it just falls back to showing the raw scanned code until the ticket is registered.
- Snapshotted onto the rental — the resolved ticket name is captured at check-in time and carried onto the checkout transaction's note, so past receipts and rental records read correctly forever, even after a ticket is renamed or retired.
- Simple CRUD list — create, rename, or soft-delete tickets the same way as any other lookup table in the product (comparable to coupons); deleting one only stops it from resolving new check-ins, it doesn't touch history.
For engineers
- Screens:
libs/ui/src/presentation/screens/Ticket{List,Create,Update}Screen.tsx - Components:
libs/ui/src/presentation/components/tickets/{TicketList,TicketListItem,TicketFormView}.tsx - Entity:
libs/ui/src/domain/entities/Ticket.ts - Backend:
apps/api/domain/ticket_{entity,usecase}.go; routes inapps/api/presentation/restapi/ticket_route.go; sample data inapps/api/seeds/ticket_seeder.go - Web routes:
apps/web/src/pages/tickets/{index,create,[ticketId]}.tsx - Rental integration:
apps/api/domain/rental_usecase.go(code → ticket resolution at checkin, name snapshot onto checkout notes),libs/ui/src/presentation/components/rentals/RentalCheckinFormView.tsx(live scan feedback) - Design doc:
docs/prd-ticket-management.md(the RFID-code-vs-printed-number rationale in full) - Related: Board-game Rentals — the only place a ticket has any real effect