Book a Show Technical Reference
Architecture, Data Model, Workflow Rules & Integration Surface
The shape of the app for developers and technical evaluators — database schemas, Next.js App Router architecture, 8-stage bid workflow pipeline, partner API specification, and source-level quality gates.
Platform & Architecture Choices
Core architectural decisions driving performance, security, and document fidelity:
Next.js App Router
TypeScript codebase with React Server Components by default and targeted Client Components for interaction.
PostgreSQL & Prisma ORM
16 data models and 9 enums powered by Prisma via the Postgres driver adapter for type-safe database queries.
NextAuth & Scrypt Security
JWT session management with separate credentials providers for Staff (email) and Producers (Company Reg ID).
Dual PDF Generation Engine
Browser HTML->Canvas->PDF for signed documents (capturing exact signature layout); server headless browser for previews.
Build-Time Bidi Locale
Full bidirectional (RTL and LTR) support driven by build-time constant, eliminating missing translation key runtime errors.
Nodemailer SMTP Engine
Direct SMTP email delivery with every email template editable in the admin panel.
Database Topology (16 Models & 9 Enums)
PostgreSQL database schema structured into 5 logical domain groups:
3.1 Identity and Access
Venue staff. Role is ADMIN (pricing, user management, API keys) or VIEWER (operations). Scrypt password hash.
Counterparty. Company name, registration ID (login ID, unique), contact person, email, phone, password hash.
NextAuth standard authentication tables.
3.2 The Calendar
One row per day. Status is OPEN, OPEN_CANCELLABLE, BLOCKED, PENDING, or ASSIGNED.
Contiguous run of days a producer asked for. Carries range status and optional document folder.
Join row linking DateRange to each CalendarDate it covers.
3.3 Requests & Pricing
Central record: artist, show type, status, frozen price snapshot, document timestamps.
Free-text additional cost lines on a bid, ordered.
Audit trail of every change to global rates with who and when.
Key/value settings: rates, calendar window, storage path, SMTP, contracting entity.
3.4 Documents
File attached to a bid (COMMITMENT, FINAL_AGREEMENT, DRAFT_OBLIGATION, CONTRACT, SIGNED_RETURN, OTHER).
Admin-editable wording: built-in default -> venue override -> per-booking override.
3.5 Integration
Credential for downstream system stored as SHA-256 hash with clear prefix, expiry, and lastUsedAt.
Results of external calendar synchronisation runs.
8-Stage Bid Workflow Pipeline
State progression matrix for requests, holds, and assigned dates:
| Bid Status | Workflow Meaning | Calendar Days State |
|---|---|---|
| SUBMITTED | Requested, competing for dates | No |
| DOCS_READY | Commitment form prepared, not sent | No |
| AWAITING_SIGNATURE | Form sent, awaiting producer | Yes — PENDING |
| DOCS_RETURNED | Producer signed, awaiting staff | Yes — PENDING |
| APPROVED | Confirmed by venue staff | Yes — ASSIGNED |
| REJECTED | Never finalised | No |
| CANCELLED | Reversed after being promised | No |
| ESCALATED | Passed to next-ranked candidate | No |
Read-Only Partner API Specification (`/api/v1`)
Exposes contracted shows to downstream finance, ERP, and document management systems:
Contracted shows, filterable by date overlap, paginated
One contracted show details and cost breakdown
The signed final agreement PDF document
Security & Scope Rules:
9 Quality Gate Assertion Check Suites
Source-level automated check suites executing on every change:
Every template's fields and defaults resolve without errors
Uploaded files cannot escape the designated storage root
Date-span labels render accurately across month and year boundaries
Default -> template -> per-booking override layering functions correctly
Day counts, night teardown, and discount ordering evaluate precisely
The signature is embedded into document canvas, not stamped on after
Partner API authentication, scope limits, and rate limiting behave strictly
Calendar availability vs revokable booking statuses stay 100% distinct
No client component imports a server-only module that reaches the database
