Partner API, Website, Blog, Flower & Product Catalogs
What it is
A grab-bag of external-facing surfaces: third-party-api (a scoped, permissioned API for external partners), website (a per-event public landing page), blog and flower (content/commerce verticals with their own admin+public split), and product/partybundle (additional catalog surfaces alongside Giftstore).
How it works
Third-Party API (partner integrations)
A separate permission model from the rest of the platform — partners get scoped API keys rather than user JWTs, checked via requirePermission(ApiPermission.X). Permissions: events:read, tickets:read, purchases:create, purchases:direct, purchases:read, bundled into presets (readonly, standard, full) for quick assignment rather than hand-picking permissions per partner. This is the caller behind the third-party-purchase payout service type in Payments & Payouts — a partner-initiated purchase settles through the same payout pipeline as any other, just tagged with a different destination.
Website
A minimal public landing page per event: POST/PUT/DELETE /website/event/:eventId (planner manages it, authenticated), GET /website/public/:websiteId (public view), GET /website/public/memories (recent public memories feed — cross-references Memories & Comments). Distinct from an event's normal invite/RSVP flow — this is a shareable standalone page.
Blog
Conventional CMS split: GET /blog, GET /blog/:slug public; full CRUD (listAll, getById, create, update, delete) admin-gated (Zod-validated create/update).
Flower
An admin-managed product vertical (SKUs, orders) with a public product listing (GET /flower/products) but everything else — order management, product create/update — admin-only. Structurally similar to a lightweight version of Giftstore, scoped to one product category rather than a general catalog.
Product & Partybundle
product is yet another catalog surface (findAll, getSingleProduct, plus a gift-store/items alias overlapping with the giftstore module) and partybundle is simple bundle CRUD (addPartyBundle, findOnePartyBundle, admin-gated findAllPartyBundles) — referenced from Budget, Cart & Orders as the partybundle cart namespace.
Key business rules & edge cases
- There are now multiple overlapping product/catalog surfaces (giftstore, product, flower, partybundle) — before adding a new product type, check whether it belongs in an existing catalog rather than becoming a fifth one. This guide doesn't attempt to fully reconcile them; treat the overlap as a real architectural question worth asking rather than an already-settled distinction.
- Third-party API permissions are additive scopes, not a single access level — a partner with
purchases:createbut notpurchases:directcan create normal-flow purchases but not whatever the "direct" flow specifically unlocks; check the exact preset/permission set granted rather than assuming "the partner has API access" implies full access.
Related endpoints
Not yet in the generated OpenAPI spec. GET /v1/blog, GET /v1/website/public/{websiteId}, GET /v1/flower/products, partner endpoints under the third-party-api prefix (partner-specific base path, not /v1/*).
Related code
src/modules/third-party-api/— routes/controllers,types/permissions.types.ts(ApiPermission,PERMISSION_PRESETS)src/modules/website/website.routes.ts,website.controller.tssrc/modules/blog/blog.routes.ts,blog.controller.tssrc/modules/flower/— routes/controllersrc/modules/product/— routes/controllersrc/modules/partybundle/partybundle.route.ts,partybundle.controller.ts