Planners
What it is
Governs co-planner access to an event — who besides the event owner can manage what. Nearly every other guide on this site references isEventPlanner([EventSections.X]) middleware gating a route; this module is where those permissions actually get granted, checked, and revoked.
Core concepts
EventSectionsis the permission unit —PartyBank,Rsvp,Vendor,TicketHero,MiniShop,GiftRegistry,PlannerAccessControl, and others, each independently grantable per co-planner. A planner might haveRsvpaccess but notPartyBank— permissions aren't all-or-nothing.PlannerAccessControlis itself a section — managing other planners' permissions is gated the same way as any other section, meaning a co-planner could theoretically be granted the ability to manage other planners without being the event owner.- Owner vs. planner is a separate axis from sections —
isEventOwner(only the true event creator) gates a narrower set of actions thanisEventPlanner([...])(any planner with the right section access). Toggling whether planners are even allowed to invite others (allow-planner-invite) is owner-only, not delegable viaPlannerAccessControl.
How it works
GET /planners/event-sections— the full catalog of sections and their metadata (what a client renders as togglable permissions in an invite/manage UI).POST /planners/event/:eventId/invite— invite a co-planner (requiresPlannerAccessControl+ transaction PIN).POST /planners/event/:eventId/planner/:plannerId/permissions— grant/adjust which sections a specific planner has (alsoPlannerAccessControl+ PIN-gated).GET /planners/event/:eventId/my-permissions— the calling user's own access, for client-side UI to know what to show/hide.PATCH /planners/event/:eventId/allow-planner-invite— owner-only toggle for whether planners (not just the owner) can invite further planners.DELETE /planners/event/:eventId/planner/:id— remove a co-planner (PIN-gated).GET /planners/public/event/:eventId— public, unauthenticated list of an event's planners (for guest-facing display, e.g. "hosted by").
Key business rules & edge cases
- Permission-management actions are transaction-PIN-gated, not just role-gated — inviting, changing permissions, and removing a planner all require
encryptedPinMiddlewarein addition toPlannerAccessControlaccess. This is the same step-up pattern used for money movement elsewhere, applied here because planner access is itself a sensitive capability (a malicious or compromised co-planner with the right sections could reach PartyBank). - Because
PlannerAccessControlcan be granted to a non-owner, don't assume only the event owner can add/remove other planners — check the actual granted sections, not just "is this the owner." allow-planner-invitebeing owner-only (not delegable) is a deliberate ceiling — even a planner with fullPlannerAccessControlcan't turn on the ability for other planners to invite if the owner has it switched off.
Related endpoints
GET /v1/planners/event-sections, GET /v1/planners/event/{eventId}/my-permissions, POST /v1/planners/event/{eventId}/invite, POST /v1/planners/event/{eventId}/planner/{plannerId}/permissions, DELETE /v1/planners/event/{eventId}/planner/{id}. Not yet in the generated OpenAPI spec.
Related code
src/modules/planners/planner.routes.ts,planners.controllers.tssrc/shared/enum/event.enum.ts—EventSectionssrc/shared/middlewares/iseventplanner.middleware.ts,iseventowner.middleware.tssrc/shared/validations/planners.validation.ts