Events, venues and seat layouts
What an event and its ticket types hold, how an organiser creates, publishes and cancels one, venues on the map, seat layouts with drafts and published versions, and how a timed hold keeps seats for a buyer.
For the Full Stack package
What an event holds
| Part | Values |
|---|---|
| Texts, in English and Arabic | Title (160 characters), summary (500) and description (5000). The English title and description are needed to publish. |
| Address | A slug made from the English title when none is given, kept unique with a number. |
| Category | workshop, talk or festival as seeded |
| Venue and admission | A venue, and reserved seating (seats from the venue's published layout) or general admission (a quantity, no seat numbers) |
| Schedule | Start and end in the event's own time zone, and an agenda of up to 24 items (a time, a title and an optional detail) |
| Visibility | public (listed in the catalogue and search) or unlisted (sold by its link only) |
| Colour | pink, yellow, teal or blue. An event has no photograph: its title, date and colour are drawn as a ticket. |
| Ticket types | 1 to 10, each with a name, a price (0 for free), a capacity, the most per order (1 to 8) and a sales status: on sale, paused or closed |
Prices are kept in minor units of the workspace's currency (2000 is $20.00), and the editor's price column names that currency: the one the event's ticket types were priced in, or for a new event the workspace's. The booking fee, 3% as seeded, is added per ticket at checkout and paid by the attendee; a free ticket carries none.
Statuses and what the website shows
| Status | On the website |
|---|---|
| Draft | Hidden. Every new event starts here. |
| Published | Listed (when public), searchable, in the sitemap, and on sale. |
| Sold out | Listed, with every ticket type showing sold out. The page stays open and the event can still be saved. |
| Cancelled | Off the catalogue. Its page says it was cancelled, and its tickets no longer open the door. |
| Archived | Hidden, in the dashboard's Ended tab, and dropped from attendees' saved lists. |
A fresh seed has 36 events across four organisers: 29 published, 2 sold out, 1 called off and 4 drafts. The website lists the 22 that are on sale or on now, 3 of them on now, and 9 are already over.
Publishing, cancelling and the other actions
| Action | What it does |
|---|---|
| Publish | Needs the English title and description, at least one ticket type with capacity, a start in the future and, for reserved seating, a published layout at the venue. Otherwise the editor lists what is missing. |
| Unpublish | Back to draft: new sales stop, live holds are released, and tickets already sold stay valid. |
| Cancel event | Sales and admission stop at once, holds are released, and every paid order is emailed. No money moves: refund each order from its page. Confirmed by typing the event's slug. |
| Duplicate | A new draft named "(copy)" with the same ticket types and no sales. |
| Archive | For a draft, a cancelled event or one that has ended. Orders and tickets are kept. |
Orders and tickets are never deleted once money has moved. Every action is written to the audit trail.
The events page and the editor
- Tabs for All, Published, Draft and Ended, a search, and filters for category, status and dates (next 30 days, next 90 days, this year, past events), eight events a page, with sold against capacity and revenue on each row.
- Each row's menu previews, edits, opens the attendees, duplicates, publishes, unpublishes, archives or cancels the event.
/en/dashboard/events/newcreates an event and/en/dashboard/events/<id>/editchanges one, in four tabs (Details, Tickets, Schedule, Visibility) beside a ticket preview and a readiness checklist.- A price locks after the first sale, so what buyers paid stays true. The venue and the admission mode are fixed once tickets are sold, a sold ticket type cannot be removed, and a capacity below what is sold is refused.
- If someone else saved the event after you opened it, the editor says so and keeps your typing unsaved until you reload.
/en/dashboard/events/<id>/attendeeslists the event's tickets: holder, seat, type, status and admission time, with a search and filters for admitted, not admitted and void.
Venues
- A venue holds a name in both languages, an address, a city, a time zone, a capacity, accessibility and transit notes in both languages, and an optional point on the map.
- The dashboard's Venues page shows every venue on a map and in a list with its seating (reserved with its layout version, or general admission) and its upcoming events. The venue editor has a map picker with place search.
- The maps draw OpenFreeMap tiles and the place search uses the public Photon service, both without a key.
NEXT_PUBLIC_MAP_STYLE_LIGHT,NEXT_PUBLIC_MAP_STYLE_DARKandNEXT_PUBLIC_PLACE_SEARCH_URLin the dashboard point them elsewhere. - The website has a page per venue with its events and, for a seated venue, its published layout.
- The seed has 9 venues. Room 3 and Mill Street Lecture Hall each have a published 72-seat layout; the others sell general admission.
Seat layouts
A layout is a grid of 1 to 40 rows of 1 to 60 seats, with up to six aisles. Seats are labelled by row letter and number (A12). The seating editor opens at /en/dashboard/venues/<id>/seating.
- Each seat can be marked accessible or companion (both shown on the buyer's map), disabled (hidden from buyers, for a broken seat or a camera position), and given a price tier: tier 1 sells as the event's first ticket type, tier 2 as its second, and so on.
- Save layout keeps a draft, which is edited freely. A venue has one draft at a time.
- Publish freezes the draft as a version. A published version never changes again: seats sold against it keep pointing at it, and a later change is a new version made with Create new version. Publishing needs at least one enabled seat and no more enabled seats than the venue's capacity.
- A reserved event sells the newest published layout of its venue, from the moment the event is published.
Timed seat holds
- Choosing seats on the map books nothing; a hold does. It keeps the seats (or a general-admission quantity) for one buyer for the workspace's hold time, ten minutes as seeded, counted on the server's clock, and the buyer sees the countdown.
- Two buyers can never hold the same seat. A seat taken a moment earlier is refused with a message to choose another.
- One order holds at most 8 tickets, and never more than a ticket type's own limit. A signed-in attendee has one live hold per session: a new choice replaces the old one.
- When the time is up the seats are free for others at once, and a sweep every 15 seconds tidies the expired holds. A hold's amounts are a snapshot, so a later price change never alters it.
- The hold time and the per-order limit are workspace values (
hold_seconds, 600, andmax_per_order, 8, as seeded). The dashboard does not edit them.
Who can do what
| Permission | Allows |
|---|---|
events.view | Seeing every event, drafts included, and its attendees |
events.edit | Creating, editing and duplicating events |
events.publish | Publishing, unpublishing, cancelling and archiving |
venues.view | Seeing venues and their layouts |
venues.edit | Creating and editing venues, and saving and publishing layouts |
The seeded Owner and Manager roles hold all five; Finance and Check-in hold none.
What the API checks
- The editor and the API refuse with a machine-readable
code:VERSION_CONFLICT(someone saved first),PRICE_LOCKED,HAS_SALES,EVENT_CLOSED,NOT_READY(with what is missing indetails.missing),INVALID_TRANSITIONandCONFIRMATION_REQUIRED. - Saving a layout draft that someone else saved after you loaded it is a 409
VERSION_CONFLICT; publishing one over the venue's capacity is a 400OVER_CAPACITY. POST /api/holdsneeds anIdempotency-Key, and answers the hold with a token shown once, sent afterwards asX-Hold-Token. A seat that is gone is a 409SEAT_UNAVAILABLE, a sold-out type a 409SOLD_OUT, an expired hold a 410HOLD_EXPIRED.GET /api/public/sessions/:code/availabilityanswers the server's time, the hold time, the fee and, for a reserved session, every seat's state. The website reads it every 20 seconds while the map is open.