Dillo example

Little Theater

Book a seat. It's yours.

What this demonstrates

Community theater ticketing. Book your seats here. The box office checks reservations on the same backend — what you see is what they see. No double-booking, no confusion at the door. Seats are inventory; Dillo treats them that way.

How it works

The permissions are the app. This is the whole data model — schema.ts, the first of the app's three files (its import line, not shown, brings these names in from "create-dillo/schema"):

schema.ts
// The schema the live backend serves today (span2/live-schemas filing, re-verified at deploy).
export default schema({
  Performance: table({
    capacity: integer().min(1).max(500),
    showId: relation('Show'),
    startsAt: string().datetime(),
    theaterId: relation.team(),
  }).permissions({ view: anyone, edit: owner }),

  Rental: table({
    assignee: relation.user().optional().nullable(),
    item: string().min(1).max(120),
    theaterId: relation.team(),
  }).permissions({ view: roles('actor', 'owner', 'volunteer'), edit: roles('owner', 'volunteer') }),

  Reservation: table({
    guest: string().min(1).max(120),
    performanceId: relation('Performance'),
    seats: integer().min(1).max(8),
    theaterId: relation.team(),
  }).permissions({ view: roles('box', 'owner'), edit: nobody }),

  Show: table({
    summary: string().min(1).max(500),
    title: string().min(1).max(160),
  }).permissions({ view: anyone, edit: owner }),
});

Try it

  1. Open the live demo
  2. Pick a performance
  3. Tap seats on the map
  4. Book them under your name
  5. Open the box office link to see the same reservations