Budget, Cart & Orders
What it is
Four related planning/commerce modules: budget (per-event line-item budget tracking), cart (shopping cart for store products, including party bundles), order (checkout from cart into an order tied to an event), and wishbasket (guest crowdfunding toward wishlist items — a distinct concept from a shopping cart).
Core concepts
- Budget is planner-only bookkeeping, gated by
EventSections.Budget— line items an event owner tracks (addBudget,updateBudget,deleteBudget), not something guests interact with. - Cart is store-scoped —
GET/POST /cart/store/:storeId— a user can have items in multiple stores' carts simultaneously (plus a separatepartybundlecart namespace), not one global cart. - Wishbasket ≠ a shopping cart — it's the crowdfunding layer on a wishlist item: guests contribute a cash amount (
AddWishBasketContributorValidationRule) toward a specific item rather than buying it outright. This is the payment-trackingcash-gift/gift-registryservice type referenced in the Payments guide.
How it works
Budget
Simple per-event CRUD: GET /budget/:eventId (list), POST /budget/event/:eventId/add-budget, PATCH /budget/:eventId/budget-item/:id, DELETE /budget/:eventId/budget-item/:id. All require EventSections.Budget planner access.
Cart → Order
- Add items:
POST /cart/store/:storeId(validated viaaddToCartRules) orPOST /cart/partybundlefor bundle products. - Adjust:
PUT /cart/:updatetype/product/:productId(quantity increase/decrease),DELETE /cart/:productId(remove one),DELETE /cart/(clear). - Checkout:
POST /order/event/:eventIdcreates an order from the current cart, tied to the event. GET /order,GET /order/:id— order history and detail.
Wishbasket contributions
- A wishlist item exists (created via giftstore's registry flow — see Gift & Giftstore).
- A contributor (guest or authenticated user) pledges money toward it: contribution payload includes
amount,isAnonymous, and — only required when not anonymous —fullName(email/phone are optional even for named contributors). An optionalcontributorMeta(account name/number/bank name) can be captured, presumably to support refunds if a contribution needs to be returned. GET /wishbasket/wishlist/:wishlistReference/contributions— see all contributions to a wishlist;GET /wishbasket/my-contributions— a user's own contribution history across wishlists.- Public, no-auth read paths exist specifically for the web view of a shared wishlist (
.../public,.../public/info) so a contributor doesn't need an account just to see what's been funded so far.
Key business rules & edge cases
- Anonymous contributors skip identity fields entirely — the schema's
superRefineonly requiresfullNamewhenisAnonymousisfalse; don't assume a contribution record always has a name to display. - Cart quantity updates use a single endpoint with an
:updatetypepath segment (increase/decrease) rather than separate increment/decrement routes — check which value that segment expects before wiring a client to it. - Budget line items have no connection enforced to actual spend (payments, vendor payouts) — it's a planning/tracking tool, not a reconciled ledger; don't build a report that assumes budget numbers match real transaction totals without an explicit join.
Related endpoints
Budget: GET /v1/budget/{eventId}, POST /v1/budget/event/{eventId}/add-budget, PATCH /v1/budget/{eventId}/budget-item/{id}.
Cart/Order: GET /v1/cart/, POST /v1/cart/store/{storeId}, POST /v1/order/event/{eventId}, GET /v1/order.
Wishbasket: GET /v1/wishbasket/wishlist/{wishlistReference}/items, GET /v1/wishbasket/wishlist/{wishlistReference}/contributions, GET /v1/wishbasket/my-contributions.
Not yet in the generated OpenAPI spec.
Related code
src/modules/budget/budget.route.ts,budget.controller.tssrc/modules/cart/cart.route.ts,cart.controller.ts;src/modules/order/order.routes.ts,order.controller.tssrc/modules/wishbasket/wishbasket.routes.ts,wishbasket.controllers.ts,wishbasket.service.tssrc/modules/wishbasket/dto/wishbasket.dto.ts—AddWishBasketContributorValidationRule