QuickCart collapses "check five apps" into one action. Everything below is written from the shopper's point of view first, then unpacked into the system behaviour that makes each step fast and reliable.
The end-to-end journey
A shopper opens the app, finds a product by browsing or searching, sees the best offer across all connected platforms, and either checks out in-app or is handed off to the source app. If nothing matches, the query is captured so the catalogue can grow โ the shopper never hits a dead end.
+ location permission"] B -- "No" --> HOME["Home screen"] ONB --> HOME HOME --> ACT{"Browse or search?"} ACT -- "Browse" --> CAT["Category / list screen"] ACT -- "Search" --> SR["Enter query"] CAT --> SR SR --> RES["Aggregated results
best price ยท stock ยท ETA"] RES --> DET["Product detail
5-source compare"] DET --> M{"Found a match?"} M -- "No match" --> MISS["Missing-SKU loop"] M -- "Yes" --> ADD["Add to cart"] ADD --> CART["Cart / review"] CART --> CO["Checkout + payment"] CO --> H{"Fulfilment mode?"} H -- "In-app" --> PLACED["Order placed
in QuickCart"] H -- "Deep-link" --> HAND["Handoff to
source app"] PLACED --> TRK["Live order tracking"] HAND --> TRK TRK --> DEL(["Delivered"]) DEL --> RATE["Rate & reorder"] RATE --> HOME MISS -. "notify when added" .-> HOME
Search request lifecycle
Behind a single search, the API gateway checks a short-lived cache and, on a miss, fans out to all five platform MCPs in parallel. Results are normalised, matched to canonical SKUs and ranked before returning. A hard deadline guarantees the shopper sees something even if one source is slow.
results if a source is slow AGG->>AGG: Normalise + SKU-match + rank AGG->>Cache: Store ranked offers (TTL 60s) AGG-->>GW: Ranked offers[] GW-->>App: 200 offers[] App-->>Shopper: Render best price / stock / ETA
Missing-SKU capture loop
When a search returns nothing (or only weak matches), the query is never thrown away. It enters a queue that clusters similar misses, enriches them from platform browse endpoints and external product data, and either auto-creates a canonical catalogue entry or routes it to human review. The full data model lives in Document 03 โ Missing-SKU Discovery.
no / low match"] --> LOG[("Missing-SKU
queue")] LOG --> DED["Dedupe & cluster
similar queries"] DED --> ENR["Enrich:
MCP browse +
external product data"] ENR --> AUTO{"Auto-match
confidence?"} AUTO -- "High" --> ENT["Create canonical
catalogue entry"] AUTO -- "Low" --> REV["Human review
queue"] REV --> ENT ENT --> SRCH["Becomes
searchable"] SRCH --> NOTE["Shopper notified
/ auto-retried"]
Order lifecycle
Once a shopper checks out, the order moves through a well-defined state machine owned by the Order service, with payment and refunds coordinated by the Payment service. Every transition emits an analytics event (see Document 03 โ Analytics).
Who owns each stage
Edge cases we handle
The happy path is easy; the value is in the failure paths. Each of these has an explicit branch in the flows above.
Nothing matched
Show related suggestions, log the query to the missing-SKU queue, and offer "notify me when available."
A source is down or slow
Drop the source past the 1.2s deadline, badge results "4 of 5 sources," and backfill on the next refresh.
Price or stock changed at checkout
Re-validate the winning offer before payment; if it moved, show a one-tap "accept new price" or re-rank.
Address outside all delivery zones
Detect at location step; fall back to standard-delivery sources (Amazon/Flipkart) or waitlist the pincode.
Payment failure & retry
Keep the cart, hold the order in PAYMENT_PENDING, allow a different method, and auto-expire after N minutes.
Duplicate / ambiguous match
When two SKUs match the query closely, present a disambiguation card instead of guessing the wrong pack size.