Happy House - Ecommerce Docs
Developer ResourcesWishlist

Wishlist Features and Flows

Complete feature list, actor journeys, state flows, business rules, edge cases, and diagrams for the Wishlist module.

Wishlist Features and Flows

Use this page for the wishlist domain: what it does for customers, and how each flow behaves from start to finish.

1. Documentation Evidence

Source TypeFiles or DocsWhat Was Extracted
APIapps/api/src/modules/wishlist/customer/wishlist-customer.controller.tsRoutes, status codes, idempotency semantics
Backendwishlist-customer.service.ts, wishlist-response.builder.tsON CONFLICT add, reason precedence, sort tiebreakers
Schemapackages/db/src/schema/wishlist/wishlist-item.tsUnique constraint, cascades, hard delete, 200 cap
Cache@happy-shop/redis CACHE_TTL.VOLATILE30s membership cache
Error registryapps/api/src/common/types/error-codes.ts (// WISHLIST)WISHLIST_* codes

2. Feature Summary

FieldValue
Modulewishlist
SubmoduleN/A
Primary user valueA customer keeps products they intend to buy, with live prices and stock, and gets told why a saved item is no longer buyable
ActorsCustomer (signed in)
Main entry points/api/mobile/wishlist (4 routes)
Main outputsWishlist list with reason per unavailable item, membership id-set, save/remove confirmations
Related docsAPI, Backend

3. Actor Matrix

ActorCan DoCannot DoAuth RequirementNotes
CustomerList their saved products (filtered/sorted/paginated), read their membership id-set, save a product, remove a productSave a product that is not currently published or unlisted (404 WISHLIST_PRODUCT_NOT_FOUND), exceed 200 saved items (409), see another customer's wishlistJWTCUSTOMER_READ 60/min, CUSTOMER_WRITE 20/min — account-keyed
AdminNo admin surface, no permissions

4. Capability Matrix

CapabilitySurfaceActorRoute/TriggerState ReadState WrittenLinked API Section
List wishlistCustomerCustomerGET /api/mobile/wishlistwishlist rows + live product dataAPI §4
Membership idsCustomerCustomerGET /api/mobile/wishlist/product-idswishlist rows— (30s cache)API
Save productCustomerCustomerPUT /products/:productIdwishlist rows, productwishlist rowAPI
Remove productCustomerCustomerDELETE /products/:productIdwishlist row deletedAPI

5. User-Facing Flows

5.1 Save a product (heart icon)

Summary

A customer taps the heart on a product card. The call is idempotent — tapping twice, or a retry after a timeout, changes nothing and looks the same.

Sequence Diagram

Branches and Edge Cases

BranchConditionBehaviorError/Result
Already savedRow existsNo-op success, identical response200
Concurrent tapsTwo parallel callsOne row (unique constraint)200 both
Not saveabledraft/archived/deleted/unknown product404 — deliberately the same code as nonexistentWISHLIST_PRODUCT_NOT_FOUND
At 200 capAdding a genuinely new item409WISHLIST_LIMIT_REACHED
At 200 cap, re-saveRe-saving an item already heldSucceeds — the call adds nothing200

5.2 The wishlist page

Summary

The page lists saved items, paginated by default. Every item resolves live product data — price, stock, media — at read time. Items whose product was withdrawn, archived or sold out stay in the list with a reason.

Sequence Diagram

Branches and Edge Cases

BranchConditionBehaviorError/Result
Unavailable itemwithdrawn/archived/sold outStays in list with reasonstatus.reason set
availability=availableFilter appliedUnavailable items hiddenFiltered list
availability=unavailableFilter appliedExactly the unavailable itemsFiltered list
Empty wishlistNo rowsitems: [], summary.totalItems: 0, lastUpdated: null200

5.3 Remove a product

Summary

DELETE always returns 200 — removing something never saved, or a product id that names nothing, is the outcome the caller asked for. The API never 404s on remove.

6. Admin Flows

None. There is no admin surface and no permission — the wishlist is customer-only.

7. Lifecycle and State Transitions

7.1 The item lifecycle

FromEvent/ActionToGuard ConditionSide Effects
save (PUT)savedProduct currently published or unlisted; cap not reachedUnique constraint is the idempotency guarantee
savedremove (DELETE)gone (hard delete)None — never a 404Row deleted; product-ids cache cleared
savedproduct withdrawn/archived/deletedstill savedNone — the item staysstatus.reason explains why

7.2 The availability reasons

reasonMeansavailable
nullBuyable nowtrue
out_of_stockTemporarily unavailable — worth waiting forfalse
draftWithdrawn by an admin; may returnfalse
archivedRetired; will not returnfalse
removedDeleted from the cataloguefalse

Precedence runs bottom-up: a product both archived and deleted reads removed, the more final fact and the one the customer can act on. Unlisted products count as available — reachable by direct link and buyable, following the products module's purchasableOf.

9. Data and Side Effects by Flow

FlowDB WritesCache EffectsJobsRealtimeAnalyticsNotifications
Savewishlist rowproduct-ids cache cleared
Removerow deletedproduct-ids cache cleared
List
Membership idsproduct-ids read (30s)

10. Error and Recovery Flows

ScenarioTriggerUser/System ExperienceRecoverySource
Save of unsaveable productdraft/archived/deleted/unknown404 — same code for allRefresh the productanti-enumeration
Cap reached200 items held409Remove something firstservice
Cache stalenessWrite in another tabHeart up to 30s staleLocal optimistic state30s TTL
Product hard-deletedCatalogue removalWishlist row cascade-deletedFK cascade

11. Diagrams Required Per Module

  • Actor capability diagram — §3/§4.
  • Sequence diagram per major flow — §5.1/§5.2.
  • State machine diagram — §7.
  • Data side-effect diagram — §9.
  • Error branch diagram — §10.

12. Mandatory Feature and Flow Deep-Dive Pack

12.1 Feature Inventory With Minor Behaviors

FeatureMinor BehaviorActorTriggerUser/System ResultBackend Side EffectSource
SaveIdempotent retryCustomerSame tap twiceNo duplicateON CONFLICT DO NOTHINGservice
Save200 not 201CustomerCreate pathRetry never looks like failure@HttpCode(OK)controller
SaveCap re-saveCustomerRe-save at capNo-op successservice
ListLive dataCustomerAny readToday's price/stockassembler + inventory seamservice
Listsummary.totalItemsCustomerPage/filterWhole-list count, not pageseparate countservice
ListlastUpdated nullCustomerEmpty listnull
ListUnpaginated boundCustomerpagination=false≤200 itemscap
Membership30s cacheCustomerHeart gridOne small payloadCACHE_TTL.VOLATILEservice
RemoveNever 404CustomerUnknown product200anti-enumerationservice
SortTiebreakerCustomerLow-cardinality sortNo dup/omit pagesbuildWishlistOrderBybuilder

12.2 Business Process Diagram Pack

12.3 Business Rules and Policy Traceability

RuleBusiness ReasonActor ImpactEnforced InAPI ImpactBackend ImpactTests
Unique (customer, product) = idempotencyDuplicate taps safeHeart never double-savesDB unique constraintPUT 200 both pathsON CONFLICT DO NOTHINGconcurrency spec
No soft deleteConstraint stays simpleRemove is finalSchemaDELETE never 404hard deleteprobe
Saveable only while visibleAnti-enumeration404 for hidden/unknown alikeServiceWISHLIST_PRODUCT_NOT_FOUNDsame code both casesspec
Stays saved after withdrawalCustomer learns whyReason shownServicestatus.reasonreason precedencespec
Unlisted = availableFollows purchasableOfUnlisted savableServicespec
No new stock utilityReuse the seamConsistent availabilityArchitectureinventory seamreviewed
Sort tiebreakerStable pagingNo dup/omitBuilderbuildWishlistOrderBypaging spec
200 cap approximate under concurrencyAbuse boundRare 201st itemService409accepted approximationspec

12.4 Tradeoffs and Product Rationale

Product DecisionUser BenefitEngineering BenefitAlternativeTradeoffRisk
Hard deleteRe-add is one insertUnique constraint stays simpleSoft deleteNo removal historyAccepted
Live data on readAlways current price/stockNo syncSnapshot on saveRead costBatched
30s membership cacheCheap heartsOne cache keyNo cacheCross-device stalenessCleared on own writes
Reason on unavailableCustomer acts on truthSingle sourceHide itemsList shows non-buyable rowsavailability filter
200-item capBounded readsAbuse boundNo capRare legit overflowApproximate under concurrency

12.5 Flow Edge-Case Matrix

FlowEdge CaseTriggerExpected BehaviorUser/System FeedbackSource
SaveConcurrent duplicateTwo parallel PUTsOne row200 bothunique constraint
SaveUnknown productBad id404PRODUCT_NOT_FOUNDanti-enumeration
SaveCap + re-save200 held, re-saveNo-op success200service
RemoveNever savedBad id200successdeliberate
ListProduct hard-deletedCascadeItem gone from listFK
ListArchived productSaved earlierStays with reasonarchivedservice
MembershipStale cacheOther deviceUp to 30s oldheart lagTTL
SortEqual keysname sortTiebreaker ordersstable pagesbuilder

12.6 Flow-to-Data Trace

FlowReadsWritesCacheJobs/EventsResponse Fields
Listwishlist rows, products, inventorycustomer, summary, items
Membershipwishlist rowsproduct-ids (30s)productIds, totalItems
Saveproducts, wishlistwishlist rowclear product-idssaved item
Removerow deletedclear product-idsmessage

12.7 Experience Quality Checklist

  • The doc explains what the actor is trying to accomplish.
  • The doc explains what the backend does that the actor does not see (ON CONFLICT, cache, live data seam).
  • The doc covers every minor flow and branch.
  • The doc includes user and system flows.
  • The doc explains business logic, tradeoffs, and rationale.
  • The doc maps every flow to API routes and backend side effects.
  • The doc includes diagrams appropriate to each flow type.
  • The doc covers edge cases and failure recovery.

13. Completion Checklist

  • Every feature, minor action, and submodule capability is listed.
  • Every actor has allowed and forbidden behavior.
  • Every major and minor flow includes steps, branches, and diagrams.
  • Every lifecycle has a transition table and state diagram.
  • Every flow links to the API and backend docs.
  • TDD dependencies are called out where they shape behavior (no TDD pages published yet).

See Also