Appearance
Festival Stall — discovery brief
The R1 launch vertical, and the first brief completed under the one-industry-at-a-time process (QRS-475). Ganapati idol stalls, Maharashtra first.
For what is actually designed, built and implementation-ready across this vertical's whole journey, see the journey map & implementation readiness matrix. This brief is the discovery record; that page is the delivery state.
Session held 2026-08-10 — and it overturned four of this brief's own assumptions
The pre-session draft guessed at the vendor's story and got several things wrong in the same direction: it assumed an artisan with a craft narrative, an eco-claim trust problem, pre-orders, and a catalogue of a dozen or so items. The vendor is a reseller who buys finished idols, whose customers do not care about shadu-vs-POP, who never back-orders, and who carries 1,400-1,500 pieces a season.
⚠ That last number is the single most consequential finding in this brief and nothing in the design or the Store editor was built for it. Corrections are marked ↺ CORRECTED below rather than quietly rewritten, because the pattern in what I got wrong is more useful than the individual errors: every wrong guess made the vendor more romantic and the problem smaller than reality.
0 · Front matter
| Field | Value |
|---|---|
| Industry key | festival_stall |
| Archetype | goods |
| Primitive composition | ['catalogue','ledger'] — the thinnest of all 14, and the only one without party |
| User categories served | 1 (solo owner) and 3 (consumer buying an idol) |
| Release | 26.0.1. Hard deadline Ganesh Chaturthi, 14 September 2026 — external, annual, unrepeatable |
| Status | 🟢 approved |
| Evidence | Session held 2026-08-10 by the product owner with a Dadar-market stall vendor: reseller, ~1,500 pcs/season, ₹1,000-₹40,000. ⚠ Vendor identity to be recorded by the owner — the process requires naming who was spoken to, and this row is incomplete without it |
⚠ The Status row is the machine-readable source of truth for the G-D gate: a scope item declaring "vertical": "festival_stall" needs this brief to exist at scoped and read approved at scope_frozen.
1 · What the vendor actually said
The shape of the business
- Purely seasonal: 3-4 weeks. Enquiries begin 2-3 weeks before the festival, bookings peak at ~2 weeks, and it ends at the muhurat. The rest of the year is other work.
- They BUY and RESELL. Idols are bought from other vendors and artists and held on the stall. ↺ CORRECTED — the draft assumed an artisan. There is no craft-provenance story here, so "artisan shaping the clay" video and a "craft in progress" gallery are the wrong content for this persona and must be removed from the demo data.
- 1,400-1,500 pieces per season, ₹1,000 to ₹40,000. At a rough ₹3,000 average that is roughly ₹45 lakh of GMV in four weeks.
- Found through every channel at once: passed down, footfall, hoarding, mandal contacts, WhatsApp. No single dominant path.
The pain, in their words
"Showing Bappa idols seamlessly and without cluttered UI, as idols are too much, so end user should have very flexible filters/sections to view every single category with attractive UI — and not the same size of grids. Small, medium, large grids with placements in various zigzag patterns."
⚠ The primary pain is a BROWSING problem at scale, not a business-process problem. That is unusual and it is worth taking literally: the vendor is not asking for bookkeeping, they are asking for a way to present 1,500 items that does not exhaust the buyer. Everything else they raised is secondary to it.
Second pain, from Q7: customers repeatedly ask size, price, material, booking status and collection time — all five. Whatever the card renders once removes five conversations.
Advance booking — the answer that mattered most
- Yes. Advances are real. They start 1-2 weeks ahead, minimum 10%, taken as cash or UPI.
- Proof today is a paper slip. Tracking is a notebook.
- ⚠ Non-collection: the vendor keeps the advance AND keeps the idol to resell. There is no refund.
- Bookings never close — they continue until the muhurat.
- Buyers are emotional about choosing a murti, so "the application should have large clear images in detail".
Stock, collection, custom work
- Stock is a COUNT, not one-of-a-kind: mostly unique designs, but 2-4 of the same variant in several sizes. So
catalog_item_variants(size) plusstock_quantityis the right shape. - Sold is sold. No back-order, no arranging more — carrying stock across a year is what they avoid. ↺ CORRECTED — the draft assumed a
coming_soonpre-order idol. That does not exist here. - No delivery. Collection only, every buyer comes to the stall. So the
fulfilmentprimitive is genuinely unnecessary, which matches the composition. - No custom orders. They sell only what is on the stall. ↺ CORRECTED — the draft suggested
pricing_mode = 'on_enquiry'might be the default here. It is not used at all: Q18 confirms prices are displayed on the idols physically and there is no reluctance to publish them.
Trust, media, and the end of the season
- ⚠ Eco-friendly is NOT the conversation. ↺ CORRECTED — the draft made shadu-clay-vs-POP the governance risk. Buyers care about "finishing, size, design, freshness, uniqueness and attractiveness". The claim exposure is real but far smaller than assumed, and it should not shape the design.
- They have started posting Instagram reels and WhatsApp status for branding. So video is relevant, but it is stall and idol footage, not craft documentary.
- They do not want to show what is sold. Offline, a sold idol is simply gone. ⚠ Design consequence: a sold item should DISAPPEAR from the card, not render greyed out with an "Out of stock" badge. The card should match the physical reality of the stall.
- When the season ends the card should go away. Remaining stock is stored and reused next year, so inventory carries over between seasons while the public surface does not.
Money
- Cash and UPI, and Q20 did not produce a yes to taking an online advance from a stranger — it produced a restatement of cash and UPI. Treat online advance acceptance as unproven, not agreed.
- ⚠ The beneficiary account is fluid: "mostly self or family or relative, whichever works during the season, and no hard rule of using current, so savings account also works — we have to catch the season." See §4 for why this is the most serious commercial finding in the brief.
- Q21 (what would you pay) returned NA. ⚠ There is no willingness-to-pay evidence for this vertical. Recorded as a gap rather than filled in with a guess.
2 · What the architecture answers, and what it does not
enabled_primitives = ['catalogue','ledger'] resolves to twelve features as of QRS-480: the six core ones, plus store, store.media, store.stock, daily_sales, and now orders and payments.
✅ Fits unchanged: idols as catalog_items with catalog_categories · sizes as catalog_item_variants with absolute prices · photographs as catalog_item_media · 2-4 per variant as stock_quantity (numeric(12,3)) · sold-out as availability = 'out_of_stock' · advances as a payments row below the order total, which flips orders.payment_status to the partly_paid value already reserved for exactly this.
⚠ Three genuine gaps the answers exposed:
- A CASH advance cannot be recorded.
payments.providerischeck (provider in ('razorpay')), and the vendor takes cash. Since the product's concrete win is replacing the notebook, and the notebook's contents are cash advances, this is a blocker rather than a nicety. Fixed by QRS-484 — one CHECK widened to acceptcashandupi_manual. - 1,500 items breaks both sides of the product. See §3 and QRS-481.
- The payout account is unlikely to pass Razorpay onboarding. See §4 and QRS-482.
3 · Content types — rewritten around 1,500 items
| Content type | Needed? | Shape |
|---|---|---|
| Photographs | The product itself | ⚠ Large and clear, in detail — the vendor said buyers are emotional and choose on the image. Not thumbnails |
| Video | Yes, as reels | Stall and idol footage, short, vertical. ↺ NOT artisan craft |
| Before / after | No | Nothing transforms. Do not render the block for this vertical |
| Documents | No | ↺ Eco certification is not the conversation |
| A changing published number | No | Prices are set for the season. No ADR-0027 freshness case at all |
| A schedule | Stall hours only | setu_card_hours covers it |
| Structured specs | Yes, and they are FILTERS | Height, material, design/style, price band — all four are filtered on, so typed columns, not attributes |
| Long-form text | Minimal | Collection instructions |
⚠ The browsing requirement is the design brief, and it is not a card-anatomy problem. 1,500 items needs: faceted filters (size band, price band, style, availability), search, and a mixed-size masonry grid rather than a uniform two-column one. The vendor asked for that in those words.
ADR-0019 D6 answer: still no new block type. A masonry catalogue with facets is a variant of the existing catalogue block, not a new type — which is the D6 rule working as intended. But it is a substantial variant, and it is the first one where the block's internals matter more than its placement.
4 · Acquisition, conversion and money
- Why the vendor shares: the card answers the five repeated questions (size, price, material, booking status, collection) without a conversation, for four weeks, at 1,500-item scale.
- Why the customer forwards: a family or mandal chooses collectively, so the link naturally enters a WhatsApp group. Best forward-rate vertical of the four, and the OG preview matters more here than the card body.
- The concrete product win is small and achievable: the paper slip becomes a digital booking, and the notebook becomes the order list. That is a replaceable artifact with a known shape, which is a far better wedge than "grow your business".
- ⚠ THE COMMERCIAL RISK, and it is serious. The vendor's beneficiary account is "self or family or relative, whichever works during the season", often a savings account. Razorpay Route linked accounts require KYC that matches the beneficiary, and the release plan already names name-mismatch as the failure that will dominate support. Three consequences:
- Onboarding will fail or stall for a meaningful share of stalls, inside a four-week season, which is the worst possible time to be blocked on KYC.
- An account that changes mid-season is not something Route models cheaply.
- ⚠ So online payment may be substantially unusable for this vertical in R1 — and that is not a reason to skip the schema (advances still need recording, in cash), it is a reason not to build the product story on online collection. QRS-482.
- ⚠ Non-refundable advances need disclosure. The vendor keeps the advance and resells the idol on non-collection. Offline that is a handshake; published on a platform it is a contract term, and under the Consumer Protection (E-Commerce) Rules the terms of a cancellation must be disclosed before payment. QRS-483.
- Monetization: unestablished. Q21 returned NA.
5 · Governance and verification
- No capability here is legally gated. ↺ CORRECTED — the draft treated eco-claims as the risk.
- Material stays a
specfield, never a platform badge. Unchanged conclusion, weaker reason: a factual "Material: shadu clay" is the vendor's statement; a styled "Eco-friendly ✅" badge is QRSETU endorsing it. Buyers do not ask for it, so there is no product cost to omitting the badge. - The real disclosure obligation is the advance-forfeiture term (§4.5), not a material claim.
- Legal read needed: only for the forfeiture term, and only if advances are collected online.
6 · Divergence seams (QRS-297)
| Seam | Android | iOS | Web PWA |
|---|---|---|---|
| Camera — photographing 1,500 idols | expo-image-picker (bundled) | same | getUserMedia / file input |
| Storage — upload at that volume | presigned direct-to-R2 | same | same |
| Share | native sheet | native sheet | navigator.share + clipboard fallback |
| Push — a booking arrived | ⚠ not built | ⚠ not built | ⚠ deferred |
⚠ Push is now a harder blocker than before the session. The vendor tracks bookings in a notebook they carry. If a customer can book from the card, the vendor must learn of it without opening the app — and with no push, the only channel is email, which is broken (QRS-285). A booking nobody hears about during a four-week season is worse than no booking at all.
7 · Proactive-value answer
- Action: "Bhadrapad is in 12 days. 340 idols have no photo, and photos are what buyers choose on."
- Timely: the festival date is fixed years ahead, so every nudge can be dated exactly — and with a four-week season the urgency is real rather than manufactured.
- Source: a pure
@qrsetu/domainderivation over the festival calendar plus stored item state. No fabricated insight, no per-vertical hardcoding — festival dates are archetype config (ADR-0009), so a Diwali sweet shop inherits the mechanism. - ⚠ And the anti-noise ceiling matters unusually much here: a four-week season tempts daily nudging. In-app surfacing only, dismissible, and never a push for anything but a real booking.
8 · Part 2 — capability mapping (complete)
| Workflow (their words) | Existing capability | New capability needed | Generalises to ≥2 industries? |
|---|---|---|---|
| "Show my idols with photos and prices" | store + store.media | — | — |
| "Browse 1,500 without clutter" | store | catalogue-block facets + masonry variant | ✅ any large-catalogue merchant (kirana, boutique) |
| "Say which are sold" (and hide them) | store.stock | — | — |
| "2-4 of the same size" | catalog_item_variants + stock_quantity | — | — |
| "Take a booking with 10% advance" | orders ✅ built | — | — |
| "Record a CASH advance" | ❌ blocked by a CHECK | payments.provider += 'cash' | ✅ every industry |
| "Give proof instead of a slip" | orders.reference | booking confirmation view | ✅ every industry |
| "Know a booking arrived" | ❌ none | notification transport | ✅ every industry |
| "Replace the notebook" | orders list | — | — |
| "Carry stock to next year" | catalog_items persist | season archive/sleep for the CARD | ✅ any seasonal vertical |
No new primitive. No new block type. The gaps are one CHECK widening, one block variant, one notification transport, and one card lifecycle state.
9 · Sign-off
| Session held | ✅ 2026-08-10, product owner with a Dadar stall vendor. ⚠ Vendor identity still to be recorded |
| Capability mapping complete | ✅ both sides |
| New primitives proposed | none |
| New block types proposed | none — the masonry/faceted catalogue is a variant (ADR-0019 D6) |
The four open decisions, now closed by evidence
| # | Question | Answer |
|---|---|---|
| a | Does orders land on ledger? | ✅ Yes, and it is already built and verified — festival_stall gains orders with no composition change |
| b | Is an advance held, or is the vendor paid on capture? | ✅ An advance is real: minimum 10%, 1-2 weeks ahead, and NON-REFUNDABLE. The existing shape expresses it (a payments row below the order total → payment_status = 'partly_paid') with no schema change, but it needs provider = 'cash' and a disclosed forfeiture term |
| c | Notification transport before Pay Now? | ⚠ Still open, and now more urgent — see §6. Push is unbuilt, email is broken, and the vendor carries a notebook rather than the app |
| d | Material as spec, not badge? | ✅ Yes, and the cost of omitting the badge is zero — buyers do not ask about it |
Still unresolved, recorded rather than guessed
- Willingness to pay — Q21 returned NA. No pricing evidence for this vertical.
- Online advance acceptance — Q20 restated cash and UPI rather than agreeing. Unproven.
- Vendor identity for the evidence row.
Tracker rows raised: QRS-480 · QRS-481 · QRS-482 · QRS-483 · QRS-484