xiaomai 6194c96ead feat(bookings): implement ticket receipts and seat sharing system
Add receipt tokens and booking_seats table to track individual tickets
Create receipt and seat view pages with QR code generation
2026-04-12 22:48:26 +08:00
2026-04-12 16:00:31 +08:00
2026-04-12 16:00:31 +08:00
2026-04-12 16:00:31 +08:00

Dinner Ticket System

Nuxt 4 app with:

  • Public dinner ticket booking page
  • Staff login with password and passkey support
  • PostgreSQL-backed users and passkeys
  • Redis-backed sessions and WebAuthn challenge storage
  • Seeded xiaomai super-admin account
  • Super-admin user creation and password reset flow
  • First-login enforcement: temporary password change plus passkey enrollment

Environment

Create .env from .env.example and set:

NUXT_DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:5432/dinner_ticket_system
NUXT_REDIS_URL=redis://127.0.0.1:6379
NUXT_PUBLIC_APP_URL=http://localhost:20013

NUXT_PUBLIC_APP_URL should be your final HTTPS origin in production. Passkeys rely on the RP origin being stable and correct.

Setup

Install dependencies:

pnpm install

Development

Start the app:

pnpm dev

The backend bootstraps its schema automatically on startup and seeds this initial super-admin account if it does not already exist:

  • Username: xiaomai
  • Temporary password: 123456

On first login, the user is forced to change that temporary password and register a passkey before accessing the protected area.

Production

Build:

pnpm build

Preview the built server:

node .output/server/index.mjs

Docker

The repo now includes a production-ready container stack:

Bring up the full environment:

docker compose up --build

This starts:

  • Nuxt/Nitro app on http://localhost:20013
  • PostgreSQL only on the internal Docker network
  • Redis only on the internal Docker network

The app container waits on PostgreSQL and Redis health checks, and exposes:

  • GET /api/health for container/runtime health

Stop the stack:

docker compose down

Stop and remove persisted database/cache volumes:

docker compose down -v

For passkey testing in Docker, set NUXT_PUBLIC_APP_URL to the exact origin you open in the browser. In production, this should be your final HTTPS URL.

Docker Development With Hot Reload

Use the dev override when you want live reload instead of rebuilding the image after every code change:

docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build

This keeps PostgreSQL and Redis in Docker, but runs the app container in Nuxt dev mode with:

  • the project directory bind-mounted into /app
  • a persistent /app/node_modules volume so dependencies stay inside Docker
  • an automatic pnpm install --frozen-lockfile during app container startup
  • polling-based file watching for reliable reloads on mounted filesystems

After the first start, code changes on the host should reload automatically without rebuilding the image.

When you change dependencies, restart the app container so it reruns pnpm install against the current lockfile:

docker compose -f docker-compose.yml -f docker-compose.dev.yml restart app

Protected Areas

  • /login
  • /security
  • /management/users

User Flows

  • Password login with Redis-backed session cookie
  • Passkey login using WebAuthn discoverable credentials
  • Super admin creates users with default password 123456
  • Users must change password and set a passkey after first login
  • Users can change their own password from Security
  • Super admin can reset a user's password back to 123456

Verification

The codebase currently verifies cleanly with:

pnpm build
Description
Dinner Ticket System
Readme 341 KiB
Languages
Vue 50.6%
TypeScript 48.9%
Dockerfile 0.4%