19 KiB
Gmail vs storefront widget — use-case guide
This document maps every customer-facing module from docs/req-AI.md §3 to how it behaves on email (Gmail integration) vs the storefront chat widget. It is a companion to the spec, not a replacement: identifiers (module codes, API paths) may differ in code; behavior should match the pillars below.
Legend (pillars)
| Code | Pillar |
|---|---|
| K | Knowledge (FAQ / KB / RAG; no order mutation) |
| T | Transactional L1 (verified identity + DB read / limited write) |
| X | Ticket-led (human resolves; L1 may intake + acknowledge + ticket) |
| Cat | Catalog metadata (DB-backed category metadetails via tools when enabled) |
1. Identity and verification (both channels)
1.1 Gmail (email)
| Rule | Behavior |
|---|---|
| Identity | Customer email = From: on the message. |
| Transactional / ticket “fiber” | Only trust lookups when From matches the customer/order email in your DB. No servicing “someone else’s” order from the wrong inbox. |
| OTP | Not in v1 of the spec for email — trust is email alignment only. |
| Unknown email | Generic safe reply: do not confirm whether an order exists for another address; ask them to contact support from the email used at checkout. |
| Multi-order | If From matches multiple recent/open orders, list candidates and ask which order before full detail or action. |
1.2 Storefront widget
| Rule | Behavior |
|---|---|
| Pure K (e.g. FAQ) | May answer without email if the module allows — no session required. |
| T / X / identity-dependent flows | Email asserted → OTP → verified session (TTL, e.g. 1h). No Shopify login, no magic links. |
| After TTL | Re-OTP for new transactional work. |
| Session | Server-side: asserted email, verified time, expiry, optional bound order after disambiguation. |
2. Module-by-module: Gmail vs storefront
For each row: what the customer is trying to do, then Gmail vs Widget specifics. Modules follow docs/req-AI.md §3.
ALL — Global store context
| Gmail | Storefront | |
|---|---|---|
| Role | Informs tone, links, support channels, SLA copy in all replies. | Same: baseline context for every reply. |
| Verification | N/A (not a standalone intent). | N/A |
| Notes | Uses shared fields (brand name, support channels, tone, policy links, etc.). | Same. |
FAQ — General policies & “how we work”
| Gmail | Storefront | |
|---|---|---|
| Pillar | K | K |
| Typical asks | Return window explanation, “how long do refunds take?” (policy), shipping regions. | Same; widget can be used without OTP for pure policy if FAQ module enabled. |
| Verification | None required for pure policy. | None for pure FAQ path per §1.2. |
| Human | If out of scope → suggest email or ticket. | Same. |
Important: Refund policy = K. Refund status for my order = T (REFUND_STATUS), not FAQ.
CATEGORY_METADETAILS — Category-level details from DB sync
| Gmail | Storefront | |
|---|---|---|
| Pillar | Cat | Cat |
| Typical asks | “What’s the care instruction for [category]?” after product/category resolution. | Same; often needs product/SKU → category resolution. |
| Verification | Needed when combined with order-specific T flows; for pure catalog facts, product resolution may suffice. | Gated by store categoryMetadetailsEnabled (or equivalent). If off, fall back to KB / PDP / ticket — do not call category-metadetails tools. |
| Human | If disabled, no row, or ambiguous → KB link / ticket. | Same. |
PRODUCT_FIT — Fit, sizing, compatibility
| Gmail | Storefront | |
|---|---|---|
| Pillar | K (+ optional light T to resolve product) | K (+ product resolve) |
| Typical asks | Sizing, voltage, device compatibility. | Same. |
| Sources | KB + category metadetails (if enabled) + product metafields/chunks. | Same. |
| Verification | Usually not for generic fit; if tied to “my order,” need email alignment or OTP session. | OTP if transactional coupling. |
| Human | Edge cases → ticket. | Same. |
STORE_LOCAL — Hours, pickup, local
| Gmail | Storefront | |
|---|---|---|
| Pillar | K | K |
| Typical asks | Store hours, pickup location, BOPIS rules. | Same. |
| Verification | None. | None. |
FEEDBACK — After-resolution feedback
| Gmail | Storefront | |
|---|---|---|
| Pillar | K | K |
| Typical asks | CSAT link, one-off survey. | Same. |
| Verification | Optional ticket id in context. | Same. |
| Human | Negative follow-up → human. | Same. |
HUMAN_ESCALATION — “I want a person”
| Gmail | Storefront | |
|---|---|---|
| Pillar | K / routing | K / routing |
| Typical asks | Escalation to agent. | Same. |
| Verification | Context-dependent; may create ticket per policy. | May create ticket; post-ticket human dialogue often continues email per spec §0.3. |
| Human | Queue / human ownership. | Same. |
ORDER_STATUS — Where is my order
| Gmail | Storefront | |
|---|---|---|
| Pillar | T | T |
| Prerequisites | From matches DB + order id (or disambiguation list). |
OTP-verified session + order id / disambiguation. |
| L1 | Read order state from DB; status summary. | Same. |
| Human | Anomaly outside playbook → ticket. | Same. |
ORDER_SUMMARY — Receipt / recap
| Gmail | Storefront | |
|---|---|---|
| Pillar | T | T |
| Prerequisites | Same as order status: aligned email + order resolution. | OTP session + order resolution. |
| L1 | Line items / totals from DB. | Same. |
| Human | Tax invoice edge cases → ticket if policy says. | Same. |
SHIPPING_TRACKING — Carrier, tracking, ETA
| Gmail | Storefront | |
|---|---|---|
| Pillar | T | T |
| Prerequisites | Email alignment + order. | OTP + order. |
| L1 | Tracking fields from DB for that order. | Same. |
| Human | Carrier claim / dispute → X. | Same. |
ORDER_CANCEL — Cancel order
| Gmail | Storefront | |
|---|---|---|
| Pillar | T | T |
| Prerequisites | Verified identity + order + business rules. | OTP + order + rules. |
| L1 | Eligibility + cancel if allowed by implementation; else KB explanation. | Same. (JUNOHUB MVP may be read-only — see docs/req-AI.md §10.) |
| Human | Ambiguous / edge → X. | Same. |
REFUND_STATUS — Status of my refund / payout
| Gmail | Storefront | |
|---|---|---|
| Pillar | T | T |
| Prerequisites | Verified identity + order/return reference. | OTP + references. |
| L1 | Read refund/return state from DB if modeled; else templated + ticket. | Same. |
| Human | When data missing or dispute. | Same. |
INVENTORY_STOCK — Is this in stock?
| Gmail | Storefront | |
|---|---|---|
| Pillar | T | T |
| Prerequisites | Product name / SKU; email alignment if tied to “my” purchase (product decision). | Session optional for anonymous stock checks per product policy; cart-specific may need OTP. |
| L1 | Read inventory from DB. | Same. |
| Human | SKU disambiguation across many variants. | Same. |
NOT_RECEIVED_MARKED_DELIVERED — Tracking says delivered, I don’t have it
| Gmail | Storefront | |
|---|---|---|
| Pillar | X | X |
| Prerequisites | Verified identity + order. | OTP + order. |
| L1 | Tracking snapshot + policy snippet + open ticket. | Same. |
| Human | Carrier / claim investigation. | Same. |
SHIPMENT_STUCK_OR_DELAYED — Not moving / very late
| Gmail | Storefront | |
|---|---|---|
| Pillar | X | X |
| Prerequisites | Verified identity + order. | OTP + order. |
| L1 | Last known scan + policy + ticket. | Same. |
| Human | Carrier / ops follow-up. | Same. |
PAYMENT_PROBLEM — Double charge, wrong amount, promo failed, etc.
| Gmail | Storefront | |
|---|---|---|
| Pillar | X | X |
| Prerequisites | Order-scoped: verified identity + order reference; some sub-intents need extra slots (last4, date). | Same where applicable. |
| L1 | Structured intake + ticket; no automated money movement. | Same. |
| Human | Finance / support. | Same. |
ORDER_CHANGE — Change address / items / qty
| Gmail | Storefront | |
|---|---|---|
| Pillar | X | X |
| Prerequisites | Verified identity + order + requested change. | OTP + order + change description. |
| L1 | Open ticket + acknowledgement (v1: no auto-change). | Same. |
| Human | Feasibility decision. | Same. |
RETURN_EXCHANGE — Start return or exchange
| Gmail | Storefront | |
|---|---|---|
| Pillar | X | X |
| Prerequisites | Verified identity + order (+ reason). | OTP + order (+ reason). |
| L1 | KB policy + ticket (or portal link if product adds it). | Same; spec notes post-ticket dialogue often email. |
| Human | RMA / ops. | Same. |
WARRANTY — Warranty claim
| Gmail | Storefront | |
|---|---|---|
| Pillar | X | X |
| Prerequisites | Verified identity + proof-of-purchase / order. | OTP + order. |
| L1 | Intake + ticket. | Same. |
| Human | Adjudication. | Same. |
WRONG_ITEM — Wrong / damaged / missing item
| Gmail | Storefront | |
|---|---|---|
| Pillar | X | X |
| Prerequisites | Verified identity + order + issue type; email may include photos. | OTP + order + issue type. |
| L1 | Ack + policy + ticket with structured fields. | Same. |
| Human | Reship / refund / return handling. | Same. |
COMPLAINT — Strong dissatisfaction
| Gmail | Storefront | |
|---|---|---|
| Pillar | X | X |
| Prerequisites | Strict verification same as other fiber flows. | OTP + full context. |
| L1 | Empathetic ack + ticket + severity. | Same. |
| Human | Resolution owner. | Same. |
3. Excluded use-cases (spec § opening)
Not in scope for this framework: subscriptions/repeat orders, wholesale/B2B, account & security beyond email+OTP, VIP/loyalty, Shopify customer login, magic-link verification.
4. Quick reference — channel vs pillar
| Pillar | Gmail summary | Storefront summary |
|---|---|---|
| K | Answer from KB/RAG; From not required for pure policy. |
FAQ may work without OTP; enable FAQ module. |
| T | From = identity; multi-order → disambiguate. |
Email + OTP + session TTL; disambiguate orders when needed. |
| X | Intake + ticket; thread stays on email. | Intake + ticket; ongoing human↔customer often email per spec. |
| Cat | Category metadetails tools only if store toggle on + product/category resolution. | Same + OTP when combined with T/X. |
5. Testing and operations (JUNOHUB)
- Prisma / DB: After schema changes:
npx prisma generate, migrate ordb push— seedocs/req-AI.md§10.1. - Env:
DATABASE_URL,GROQ_API_KEY, embeddings/OpenAI keys as needed,STOREFRONT_OTP_SECRET, SMTP for real OTP mail — §10.3. - Store toggles:
categoryMetadetailsEnabled,aiModulesJSON — §10.2. - Illustrative tests:
tests/l1/,tests/gmail-auto-reply/.
6. Copy-paste test examples (Gmail + storefront widget)
Use these verbatim (or with your real order numbers / SKUs) to exercise each pillar. Replace placeholders:
| Placeholder | Meaning |
|---|---|
YOUR_APP |
Base URL, e.g. http://localhost:3000 |
YOUR_SHOP |
Store shopifyDomain in DB, e.g. your-brand.myshopify.com |
YOUR_ORDER |
A real order id / name that exists in your CachedOrder rows for the tester email |
TEST_EMAIL |
For widget OTP: an inbox you can read (or watch server logs if SMTP is dev-only) |
Gmail: In production, inbound mail is processed by your Gmail/Pub/Sub pipeline; the From: address must match a customer with orders when you expect T/X behavior. For offline checks of reply generation, see tests/gmail-auto-reply/scenarios.ts and generateAutoReplyPreview in src/lib/gmail/autoReplyPreview.ts.
Widget: Open the embedded page (shop is required):
YOUR_APP/storefront-chat/widget?shop=YOUR_SHOP
6.1 Knowledge (K) — no OTP required on widget
| Use case | Gmail (Subject / Body) |
Storefront (type in widget) |
|---|---|---|
| FAQ — policy | Subject: Return policyBody: How many days do I have to return an item if I change my mind? |
Same question in one message. |
| STORE_LOCAL | Subject: PickupBody: What are your store hours and do you offer local pickup? |
Same. |
| PRODUCT_FIT (KB) | Subject: SizingBody: Does the medium hoodie run true to size? |
Same. |
| HUMAN_ESCALATION | Subject: HumanBody: I want to speak to a real person, please. |
Same. |
| FEEDBACK | Subject: ThanksBody: Thank you for the fast delivery — great experience! |
Same (short thank-you). |
6.2 Catalog metadata (Cat) — CATEGORY_METADETAILS (toggle must be on)
| Use case | Gmail | Storefront |
|---|---|---|
| Category-level facts | Subject: MaterialsBody: What materials are used for products in your [Category Name] line? |
Same; include a specific product or category name your sync has metadetails for. |
If the toggle is off, expect fallback to KB / generic copy, not DB category tools.
6.3 Transactional (T) — Gmail: From = order email; Widget: OTP first
Gmail examples (send from the same email as the order in DB):
| Use case | Subject | Body |
|---|---|---|
| ORDER_STATUS (needs order #) | Order status |
Hi, can you confirm status for order #YOUR_ORDER? Thanks. |
| ORDER_STATUS (no order # → disambiguation) | Where is my package? |
Hi, I still haven't received anything. Can you check the status for me? Thanks. |
| ORDER_SUMMARY | Receipt |
Please send a line-item recap for order #YOUR_ORDER. |
| SHIPPING_TRACKING | Tracking |
What carrier and tracking number do you have for order #YOUR_ORDER? |
| ORDER_CANCEL | Cancel |
Please cancel order #YOUR_ORDER if it has not shipped yet. |
| REFUND_STATUS | Refund status |
Has my refund for order #YOUR_ORDER been issued yet? |
| INVENTORY_STOCK | Stock check |
Do you have SKU YOUR-SKU in stock right now? |
Hint mismatch (expect “not on file” behavior):
| Subject | Body |
|---|---|
Order 9999 |
I need help with order #9999. |
Storefront — transactional flow
- Open
YOUR_APP/storefront-chat/widget?shop=YOUR_SHOP. - Verify email: enter
TEST_EMAIL→ Send code → enter the 6-digit OTP from email/logs → Verify. - Send a T message, e.g.:
Where is order #YOUR_ORDER?
or
Is SKU YOUR-SKU in stock?
Without a verified session, the app may only treat you as anonymous; OTP unlocks identity-bound tools per spec.
6.4 Ticket-led (X) — intake + human; same identity rules
Gmail (from purchaser email):
| Use case | Subject | Body |
|---|---|---|
| NOT_RECEIVED_MARKED_DELIVERED | Delivered not received |
Tracking shows delivered for order #YOUR_ORDER but I never got the package. |
| SHIPMENT_STUCK_OR_DELAYED | Shipment stuck |
Order #YOUR_ORDER — the tracking has not updated in 10 days. |
| PAYMENT_PROBLEM | Double charge |
I see a duplicate charge on my card for order #YOUR_ORDER. Please investigate. |
| ORDER_CHANGE | Change address |
Can I change the shipping address on order #YOUR_ORDER? |
| RETURN_EXCHANGE | Return |
I want to start a return for order #YOUR_ORDER — wrong size. |
| WARRANTY | Warranty |
I need a warranty claim for the item from order #YOUR_ORDER. |
| WRONG_ITEM | Wrong item |
Order #YOUR_ORDER arrived with the wrong color — see photos attached. |
| COMPLAINT | Complaint |
I am very unhappy with order #YOUR_ORDER and want this escalated. |
Storefront: complete OTP (§6.3), then paste the same body lines as in the table.
6.5 Storefront API (curl) — same payloads the widget uses
After next dev (or your deployed URL):
1) Post a chat message (anonymous FAQ path)
curl -sS -X POST "YOUR_APP/api/storefront-chat/messages" \
-H "Content-Type: application/json" \
-d '{"shop":"YOUR_SHOP","visitorId":"test-visitor-1","content":"What is your return policy?"}'
2) Request OTP
curl -sS -X POST "YOUR_APP/api/storefront-chat/otp/request" \
-H "Content-Type: application/json" \
-d '{"shop":"YOUR_SHOP","visitorId":"test-visitor-1","email":"TEST_EMAIL"}'
3) Verify OTP (replace 123456)
curl -sS -X POST "YOUR_APP/api/storefront-chat/otp/verify" \
-H "Content-Type: application/json" \
-d '{"shop":"YOUR_SHOP","visitorId":"test-visitor-1","email":"TEST_EMAIL","code":"123456"}'
4) Transactional message (same visitorId as steps 2–3)
curl -sS -X POST "YOUR_APP/api/storefront-chat/messages" \
-H "Content-Type: application/json" \
-d '{"shop":"YOUR_SHOP","visitorId":"test-visitor-1","content":"Where is order #YOUR_ORDER?","customerEmail":"TEST_EMAIL"}'
5) Load history
curl -sS "YOUR_APP/api/storefront-chat/messages?shop=YOUR_SHOP&visitorId=test-visitor-1"
6.6 Repo-automated Gmail-style scenarios
The strings in tests/gmail-auto-reply/scenarios.ts are curated for generateAutoReplyPreview (e.g. counter-question when no order #, order #1002 happy path, hint mismatch #9999, off-topic weather). Run:
npm run test (or npx vitest run tests/gmail-auto-reply/run.test.ts when your DB test stack is up — see package.json test:gmail-auto-reply for the full Docker pipeline).
Aligned with docs/req-AI.md §0–§3, §6–§7 (module questions), and §10 (implementation).