🗄️ Backend & MyLipaix
The backend of the LIPAIX platform is built on PayloadCMS 3 running inside the Next.js application. PayloadCMS handles the database schema, the MyLipaix UI, and authentication. Custom MyLipaix views and API endpoints extend its default capabilities.
PayloadCMS in brief
PayloadCMS is a headless CMS — it manages your data (the schema, validation, relations) and gives you a MyLipaix interface automatically. In LIPAIX, the entire schema is defined in TypeScript files rather than through a GUI.
The configuration entry point is apps/web/src/payload.config.ts.
Collections
A collection in PayloadCMS is like a database table with a schema and a corresponding MyLipaix UI section. LIPAIX defines the following collections:
Shows (Show)
Upcoming and past performances. Key fields:
format— relation to a Formatdate— date and timevenue— relation to a Venuestatus— Draft or PublishedbookingType— BilletWeb, external URL, or nonebilletwebUrl,billetwebPrice— if booking type is BilletWebexternalBookingUrl— if booking type is externaldescription— rich textimage— relation to Media
The title is auto-generated from the format name and date if not set manually.
Formats (Format)
Types of shows (e.g., Apéro Impro, Public Investigation, Battle). Each format has a name, a type identifier, and an optional image.
Venues (Venue)
Performance locations. Stores the venue name, address, and any relevant details.
Users (Users)
MyLipaix accounts. Linked to Discord via OAuth — there is no email/password authentication. Fields include display name, email, Discord user ID, and access role.
Players (Show members / Joueurs)
Member profiles for the improv group. Separate from MyLipaix Users — a player record holds the public-facing member data (display name, photo).
Availabilities (Availability)
Records of member availability per show. Fields:
player— relation to a Playershow— relation to a Showstatus—available,unavailable, ormayberoles— ordered list of preferred rolescomment— optional free text
Selections (Selection)
The finalized cast for a show. Fields:
show— relation to a Showslots— array of role + player assignmentsmemberNotes— per-member notesdiscordMessageId,discordThreadId— stored after publishing to Discordstatus— Draft or Published
Roles (Role)
Named roles used in availabilities and selections (e.g., Comédien·ne, Meneur·euse de jeu, Arbitre).
PI Sessions (PublicInvestigationSession)
Live show data for Public Investigation format shows. Stores the current display mode and all dynamic content: player character names, traits, relationships, victim/culprit info, and Act III clues. Updated in real time during the show.
Troupes (Troupe)
Improv troupes that participate in matches or partner shows.
Contacts (Contact)
Contact form submissions.
Media (Media)
Uploaded images (show posters, player photos, etc.). Managed via PayloadCMS's built-in media handling.
Settings (global)
A single global configuration document (not a collection — there's only one). Contains:
festivalMode— boolean togglefestivalVideoUrl— embed URL for festival home pagefestivalHeadline— text headline for festival mode
Custom MyLipaix views
PayloadCMS allows replacing or extending the default MyLipaix UI with custom React components. LIPAIX uses several custom views:
| View | Path | What it does |
|---|---|---|
| Dashboard | /admin | Overview with shortcuts |
| My Availabilities | /admin/mes-dispos | Member's own availability declarations |
| Availabilities Listing | /admin/dispos | All shows with availability summary |
| Event Availabilities | /admin/dispos/[eventId] | Per-show availability breakdown |
| Selections | /admin/selections | List of selections per show |
| Edit Selection | /admin/selections/[id] | Build/edit a lineup |
| Live Show | /admin/live/[eventId] | Real-time show control |
Authentication
Authentication uses Discord OAuth only — no email/password login.
The flow:
- User clicks "Login with Discord" on the MyLipaix page
- Browser redirects to Discord's OAuth page
- Discord redirects back to
/api/auth/discord/callback - The callback looks up the Discord user ID in the
Userscollection - If found, a PayloadCMS session is created
New users can't self-register — an administrator must create their Users record first and link their Discord ID.
API endpoints
Custom REST endpoints live under /api/v1/ in the (payload) route group:
| Endpoint | Method | What it does |
|---|---|---|
/api/v1/events | GET | List upcoming shows (requires API token) |
/api/v1/players | GET | List members |
/api/v1/players/[id] | GET | Single member |
/api/v1/availabilities/single-player | GET / POST | A player's availability for a show |
/api/v1/availabilities/single-event | GET | All availabilities for a show |
/api/v1/selections/[eventId] | GET / POST | Selection for a show |
/api/v1/pi-session/[eventId] | GET | Current PI session data |
/api/v1/pi-session/[eventId]/stream | GET | SSE stream for live updates |
/api/v1/discord/interactions | POST | Handles incoming Discord bot interactions |
/api/v1/discord/commands | GET / POST | Manage Discord slash commands |
/api/v1/cache | POST | Trigger ISR cache revalidation |
PayloadCMS also exposes its own REST API at /api/[collection] and GraphQL at /api/graphql, but the application code uses the local API directly rather than these HTTP endpoints.
Database
PostgreSQL, managed via the PayloadCMS postgres adapter. Schema is defined entirely in TypeScript (PayloadCMS collection configs) — do not edit the database schema manually. Use pnpm web:db:migrate to apply pending migrations.
