Gift & Giftstore
What it is
Two related but distinct modules: giftstore is the product catalog (browsing, search, AI-powered collections, wishlists) that both event gift-registries and standalone gift orders draw from; gift is the order lifecycle for sending someone a curated physical gift box (wrap, items, delivery). Neither should be confused with the event gift types (Secret Santa, My Birthday — see Events & Event Types), which are a category of event rather than a product order.
Core concepts
- Giftstore products are organized by category, with both traditional filtering (
gift-category/:categoryId/products) and AI-powered discovery — semantic search (search/products) and generated "collections" (collections/generate) backed by vector embeddings, the same pattern used by Vendors discovery. - Wishlist has a staged, two-phase commit: items added via
wishlist/:ref/add-temporaryland in a Redis-cached staging area (WISHLIST_TEMP_KEY:{userId}:wishlist-{ref}), not the database — nothing is persisted untilwishlist/:ref/confirm({ confirm: true }) writes the whole batch to the permanent wishlist at once. This lets a client build up a wishlist interactively (add, remove, reconsider) without committing partial state, and without a DB write per add/remove. - A gift order starts minimal and grows:
POST /gift/ordersonly requirestitleandwrapId— everything else (items, recipient, delivery, theme) is attached afterward through separatePATCHcalls, not a single large create payload.
How it works
Building a gift order
POST /gift/orders— create with just a title and a wrap (GET /gift/wrapslists available wrap designs).PATCH /gift/orders/:id/items— add items to the box incrementally.PATCH /gift/orders/:id/recipient— set who it's going to.PATCH /gift/orders/:id/theme-title— adjust presentation.POST /gift/orders/:orderId/delivery-fee— calculate delivery cost once contents/recipient are known (fee depends on what's being shipped and to where, so it's computed on demand rather than upfront).PATCH /gift/orders/:id/payment— record payment info once the order is ready to finalize.PATCH /gift/orders/:id/status— move through the order lifecycle (OrderStatus: pending → ongoing/scheduled → delivered, or missed/rejected/cancelled).
DELETE /gift/orders/:id cancels; DELETE /gift/orders/:id/force is a distinct force-delete path — worth checking what state a normal cancel refuses to leave before reaching for the force variant.
Discovery (giftstore)
GET /giftstore/products,GET /giftstore/products/:id,GET /giftstore/products/categories/:slug— standard catalog browsing.GET /giftstore/search,GET /giftstore/search/products— search, with a query-result cache (POST /search/clear-cacheto bust it).POST /giftstore/collections/generate— AI-generated product collections (curated groupings, not manually assembled); also cached (POST /collections/clear-cache).GET /giftstore/public/wishlist/event/:eventId/items— the public-facing view of an event's permanent wishlist (registry), distinct from a user's personal temporary/permanent wishlist above.
Key business rules & edge cases
- Temporary wishlist items are Redis-backed and therefore expire/evictable — don't treat an unconfirmed temporary wishlist as durable; if a client needs to guarantee an item survives a long gap between add and confirm, that's a product risk worth flagging, not just an implementation detail.
- A gift order's minimal creation requirement (
title+wrapIdonly) means a lot of the order's validity (has items, has a recipient, delivery is calculable) isn't enforced at creation time — check order completeness explicitly before assuming it's ready to progress pastpending. - Vector-index maintenance endpoints (
POST /giftstore/vector/index,/index-all,/index-bundles) are separate, manually-triggered operations — new products don't automatically become searchable via semantic search until indexed.
Related endpoints
Gift orders: GET /v1/gift/wraps, POST /v1/gift/orders, GET /v1/gift/orders, GET /v1/gift/orders/{id}, PATCH /v1/gift/orders/{id}/items, PATCH /v1/gift/orders/{id}/status.
Giftstore: GET /v1/giftstore/products, GET /v1/giftstore/search, POST /v1/giftstore/wishlist/{wishlistReference}/add-temporary, POST /v1/giftstore/wishlist/{wishlistReference}/confirm.
Not yet in the generated OpenAPI spec.
Related code
src/modules/gift/gift.routes.ts,gift.controller.ts,gift.service.tssrc/modules/giftstore/giftstore.routes.ts,giftstore.controller.ts,giftstore.service.ts,giftstoreVector.service.tssrc/shared/enum/status.enum.ts—OrderStatus