# TrakopLens "Show Me" — Canonical Knowledge Model & Architecture Design

> **Status:** Design / analysis only. No code changed by this document.
> **Source analyzed:** full `support.trakop.com` knowledge-base export (the uploaded PDF, ~100+ articles across 4 surfaces).
> **Reconciled against:** live journey registry (`webroot/js/trakoplens/journeys.js`, 21 journeys), `IntentRouter` surface/intent classifier, `showme.js` menu gate (`MENU_FRAG`), and the in-flight KB-enrichment SDD (EnrichmentMerger / FaqIndexer / WalkthroughIndexer).
> **Author's stance:** the architect's job here is *not* to invent a second knowledge base out of the PDF. It is to (a) prove where the PDF adds signal the runtime lacks, (b) fold that signal into the **single** knowledge model that already exists, and (c) report every place the PDF and the runtime disagree rather than paper over it.

---

## 0. The one architectural decision everything else follows from

**The PDF is the same content already ingested as the `faq` corpus.** `support.trakop.com` → scraped → snapshot NDJSON → pgvector (`faq`, ~490 rows, vendor_id 0) → `Retriever` → `_faqGroundingBlock`. The PDF is a *snapshot of the runtime's own source*, not a new source.

Therefore the knowledge model is **not a new table**. It is three existing artifacts, cross-linked, with the PDF used only to *populate enrichment fields* and *validate classification*:

| Artifact | Source of truth for | Lives in | PDF's role |
|---|---|---|---|
| **KB article** (atom, keyed by `slug`) | answer content, `category`→surface, `question_variants`, `synonyms`, `related_intents`, `follow_up_questions`, `keywords`, `user_intent` | snapshot NDJSON → `faq` corpus | **authoring input** for the enrichment fields |
| **Journey** (executable tour, keyed by `name`) | steps, DOM selectors, `permission`, surface, action types | `journeys.js` registry | **cross-checked** for steps/nav, never overrides verified selectors |
| **Slug ↔ Journey cross-map** | which article launches which tour | `WalkthroughIndexer` (SDD Task 3) | derived, hand-authored, validated against both above |

**Non-negotiable rule (restating the user's):** the PDF is prose written by a docs team. Where it conflicts with a hand-verified selector or a controller route, **the verified runtime wins and the conflict is logged** (§18). The PDF never silently mutates a journey.

This decision means the design *confirms and formalizes the SDD work already in flight* rather than replacing it. Every recommendation below routes into the existing pipeline.

---

## 1. Feature Catalogue

Grouped by surface (the top-priority axis). `WT?` = walkthrough-suitable (Y / N / partial). `Journey` = existing registry name or `—`. Granularity = module + leaf action, collapsed where the PDF repeats a procedure verbatim.

### 1a. Backoffice / Vendor Dashboard (admin surface)

| # | Feature (leaf action) | Nav path | WT? | Journey |
|---|---|---|---|---|
| A1 | Add customer | Customers › Customers › Add New Customer | Y | `add_customer` ✅ |
| A2 | Edit customer profile | Customers › Customers › (name) | Y | — (gap) |
| A3 | Delete customer | Customers › Customers › bin | partial | — |
| A4 | Add credit limit (per customer) | Customers › Customers › Add New (Eligible for Credit) | Y | — (premium) |
| A5 | Customer wallet: recharge / refund / deduct | Customers › (name) › Wallet / `+` | partial | — |
| A6 | Customer reward points: add/deduct/redeem | Customers › (name) › Reward Points | partial | — |
| A7 | Customer addresses: add / edit / enable-disable | Customers › (name) › Addresses | Y | — (gap) |
| A8 | Add contact (receiver) | Customers › (name) › Contacts | Y | — |
| A9 | Customer notes (customer/driver/admin) | Customers › (name) › Notes | Y | — |
| A10 | Customer bulk: export / import / re-sync / notify / assign group | Customers › More | partial | — |
| A11 | Customer groups: create / edit / delete | Customers › Customer Groups | Y | — (gap) |
| A12 | Group-wise credit limit / wallet balance | Customers › Customer Groups | partial | — (premium) |
| A13 | Bulk invoice download (group) | Customers › Customer Groups › download | N (async job) | — |
| A14 | Unallocated addresses → serviceable area | Customers › Unallocated Address | N (map polygon) | — |
| A15 | Unsubscribed customers (view) | Customers › Unsubscribed Customers | N (view-only) | — |
| A16 | Feedback / trial request (view+resolve) | Customers › Feedback | partial | — |
| A17 | Add category | Catalogue › Categories › Add | Y | `add_category` ✅ |
| A18 | Modify category | Catalogue › Categories › pen | Y | `edit_category` ✅ |
| A19 | Enable/disable category | Catalogue › Categories › switch | Y | `toggle_category` ✅ |
| A20 | Delete category | Catalogue › Categories › bin | Y | `delete_category` ✅ |
| A21 | Add sub-category | Catalogue › Sub Categories › Add | Y | `add_subcategory` ✅ |
| A22 | Modify sub-category | Catalogue › Sub Categories › pen | Y | `edit_subcategory` ✅ |
| A23 | Enable/disable sub-category | Catalogue › Sub Categories › switch | Y | `toggle_subcategory` ✅ |
| A24 | Delete sub-category | Catalogue › Sub Categories › bin | Y | `delete_subcategory` ✅ |
| A25 | Reorder (sequence) sub-categories | Catalogue › Sub Categories › drag | partial | `sequence_subcategory` ✅ |
| A26 | Add brand | Catalogue › Brands › Add | Y | `add_brand` ✅ |
| A27 | Modify / delete brand | Catalogue › Brands › pen/bin | Y | — (edit gap) |
| A28 | Add unit (+ conversion) | Catalogue › Units › Add | Y | `add_unit` ✅ |
| A29 | Modify / delete / toggle unit | Catalogue › Units | Y | — (edit gap) |
| A30 | Add product (single) | Catalogue › Products › Add | Y | `add_product` ✅ |
| A31 | Add configurable product | Catalogue › Products › Add (variants) | partial (branch) | — (extends `add_product`) |
| A32 | Add combo product | Catalogue › Products › Add (combo) | partial (branch) | — |
| A33 | Product min/max qty | Catalogue › Products › Add | Y | — (extends `add_product`) |
| A34 | Product-wise days allocation | Catalogue › Products › Add | partial | — (premium) |
| A35 | Product-wise cut-off time | Catalogue › Products › Add | partial | — (premium) |
| A36 | Area-wise product listing | Catalogue › Products › Add | partial | — (premium) |
| A37 | Edit / enable-disable / delete product | Catalogue › Products | Y | — (edit gap) |
| A38 | Bulk update / import products | Catalogue › Products › More | N (file upload) | — |
| A39 | Group-wise product price | Catalogue › Products › More | partial | — |
| A40 | Manage product taxes / bulk area / commission | Catalogue › Products › More | partial | — |
| A41 | Product featuring | Catalogue › Products › toggle | Y | — |
| A42 | Create delivery area | Delivery › Delivery Area › Add | N (map polygon) | — |
| A43 | Edit/expand/reduce/delete delivery area | Delivery › Delivery Area | N (map polygon) | — |
| A44 | Skipped/weekly frequency area | Delivery › Delivery Area | N (map polygon) | — |
| A45 | Add delivery time slot | Delivery › Delivery Time Slot › Add | Y | `add_time_slot` ✅ |
| A46 | Edit/enable-disable/delete time slot | Delivery › Delivery Time Slot | Y | — (edit gap) |
| A47 | Add route | Delivery › Delivery Routes › Add | Y | `add_route` ✅ |
| A48 | Edit route | Delivery › Delivery Routes › pen | Y | — (gap) |
| A49 | Master-route sequencing (manual drag) | Delivery › Delivery Routes › Master Route | N (drag reorder) | — |
| A50 | Auto/dynamic route optimization | Delivery › Delivery Routes | partial | — (premium, HITS) |
| A51 | Service route (view) | Delivery › Delivery Routes › Service Route | N (view) | — |
| A52 | Route-wise negative balance report | Delivery › Delivery Routes › report | N (view) | — |
| A53 | Add / modify / delete delivery apartment | Deliveries › Delivery Apartment | Y | — (premium) |
| A54 | Add delivery vehicle | Deliveries › Delivery Vehicles › Add | Y | `add_vehicle` ✅ |
| A55 | Edit / delete vehicle | Deliveries › Delivery Vehicles | Y | — (edit gap) |
| A56 | Add driver | Deliveries › Delivery Drivers › Add | Y | `add_driver` ✅ |
| A57 | Edit / delete driver | Deliveries › Delivery Drivers | Y | — (edit gap) |
| A58 | Driver device details (view) | Deliveries › Delivery Drivers › device | N (view) | — |
| A59 | Driver shift management | Deliveries › Delivery Drivers › Shifts | partial | — |
| A60 | Driver attendance (view) | Deliveries › Delivery Drivers › Attendance | N (view) | — |
| A61 | Create delivery area hub | Delivery › Delivery Area Hubs › Add | partial (map) | — |
| A62 | Delivery map / live tracking (view) | Delivery › Delivery Map | N (view) | — |
| A63 | Delivery sheet: view/filter/mark/print/reject | Delivery › Delivery Sheet | partial | — |
| A64 | Create one-time order (admin) | Orders › One-time Orders › Add | Y | `create_order` ✅ (variant) |
| A65 | Modify / confirm / reschedule / cancel one-time order | Orders › One-time Orders | partial | — |
| A66 | Auto/direct-assign driver to order | Orders › One-time Orders › edit driver | partial | — |
| A67 | Create subscription (daily/alt/custom/recurring/multi) | Orders › Subscriptions › Add | Y (branchy) | — (**major gap**) |
| A68 | Edit subscription | Orders › Subscriptions › pen | partial | — |
| A69 | Missed orders: view/mark/edit/reject | Orders › Missed Orders | partial | — |
| A70 | Create / edit order (Beta) | Orders › Create order – Beta | Y | — |
| A71 | Take-away / create new order | Orders › Create Order | Y | overlaps `create_order` |
| A72 | Purchase orders (view/export) | Orders › Purchase Orders | N (view) | — |
| A73 | Edit product weight in order (CPW/MCPW) | Orders › One-time Orders › Edit | partial | — |
| A74 | Add subscription package | Promotions › Subscription Packages › Add | Y | `add_subscription_package` ✅ |
| A75 | Modify / delete subscription package | Promotions › Subscription Packages | Y | — (edit gap) |
| A76 | Add discount coupon (recharge/order/checkout/subscription) | Promotions › Discount Coupons › Add | Y (branchy) | `add_coupon` ✅ (one variant) |
| A77 | Modify / delete coupon; coupons-used (view) | Promotions › Discount Coupons | partial | — |
| A78 | Add promotional banner (mobile/website/refer-earn) | Promotions › Promotional Banners › Add | Y | `add_banner` ✅ |
| A79 | Edit / enable-disable / delete banner | Promotions › Promotional Banners | Y | — (edit gap) |
| A80 | Send notifications (area/customer/group/route-wise) | Promotions › Notifications | Y (branchy) | — (gap) |
| A81 | Refer & earn config | Settings › Preferences › Refer & Earn | partial | — |
| A82 | Sales reports (sales/txn/product/schedule/area/customer/performance) | Reports › Sales | N (view) | — |
| A83 | Payment reports (received/failed/billing/driver-cash/revenue) | Reports › Payments | N (view) | — |
| A84 | Delivery reports (sales/summary/by-driver/rejected/attendance) | Reports › Delivery | N (view) | — |
| A85 | Inventory reports (inventory/future/picked/dispatch) | Reports › Inventory | N (view; set-limit partial) | — |
| A86 | Customer reports (pending containers/containers/created-by-driver/rewards) | Reports › Customers | N (view) | — |
| A87 | Route history report | Activities › Route History | N (view) | — |
| A88 | SMS history / email history / log history (view+resend) | Activities › … | partial | — |
| A89 | Users & permissions: add/modify/delete role | Settings › Preferences › Users & Permissions | Y | — (gap) |
| A90 | Static pages: add / edit / delete | Settings › Static Pages | Y | — |
| A91 | App links (QR) | Settings › App Links | Y | — |
| A92 | Contact settings | Settings › Contact Settings | Y | — |
| A93 | Manage taxes: add/edit/delete/exemption/group | Settings › Preferences › Manage Taxes | Y | — (gap) |
| A94 | Predefined reasons: add/edit/delete | Settings › Preferences › Predefined Reason | Y | — |
| A95 | Order state settings | Settings › Preferences › Order State | Y | — |
| A96 | Container settings: add/edit/delete | Settings › Preferences › Container Settings | Y | — |
| A97 | Email / SMTP config | Settings › Preferences › Email Config | partial (external SMTP) | — |
| A98 | Notification settings (SMS/push/email toggles) | Settings › Preferences › Notification Settings | Y | — |
| A99 | Mailchimp config | Settings › Preferences › Mailchimp | Y | — |
| A100 | Payment methods (Paytm/PayU/Razorpay/PayPal/Stripe/Trust/Authorize.net) | Settings › Preferences › Payment Methods | partial (keys external) | — |
| A101 | Delivery charges: add/edit/delete/area-wise/per-order | Settings › Delivery Charges | Y | — (gap) |
| A102 | System settings (COD, plus-codes, wallet, stock, first-login, dashboard graph, invoice, vendor alerts, website, cache, taxes…) | Settings › Preferences › System Settings | partial (toggles) | — |
| A103 | Website settings (general/metatags/social/communication/style) | Settings › Preferences › Website Settings | Y | — |
| A104 | Work holidays | Settings › Work Holidays › Add | Y | — (gap) |
| A105 | Vendor profile / store address / vendor ID / invoice history | My Account | partial (view+form) | — |
| A106 | Manage branches (multi-branch) | Catalogue › Manage Branches | partial | — (premium) |
| A107 | Vendor commissions (multi-store) | Catalogue › Vendor Commissions | partial | — (premium) |
| A108 | Dashboard: manage widgets / create order / search / graphs | Dashboard | partial | overlaps `create_order` |

### 1b. Customer App (customer surface — **engine cannot reach; documentation-only**)

Login/OTP/register/forgot · Home screen · My Account (profile, change password, delete account, edit, wallet, subscriptions, one-time, addresses, cards, rewards) · Wallet (transactions, invoices, balance, recharge) · Calendar (view/modify/remove/reschedule/delete) · Cart flows (one-time, subscription, combined, multiple-product, infinite-wallet, weekly-frequency) · Create order (one-time, COD, combo, subscription daily/alternate/custom, alternate-recurring, weekly, infinite, date-population, take-away, min/max, add-card, modify, delete) · Help & Support (feedback on services/products, other message, contact us) · Trial request · WhatsApp order · Change language · Refer & earn · Policies · App info.

### 1c. Driver App (driver surface — **engine cannot reach; documentation-only**)

Login (username+password+vendor ID) · check-in/check-out (selfie) · delivery schedules (active/upcoming) · deliver order (details, notify, edit order, containers update, sign-and-deliver, receiver detail, deliver-with-OTP) · payments (cash / already-paid / OTP / sign) · cash collected (customer collection / paid-to-vendor) · create order (subscription / one-time / new customer) · created orders · created subscriptions · containers (view / add-edit / history) · summary (route-wise / category-wise / combo child) · history · my profile (view / update) · settings (column / language / general) · app info.

### 1d. Website (website surface — customer replica; **engine cannot reach; documentation-only**)

Home · My Profile (address add/edit/delete/enable-disable/default, change password, reward history, subscription view/pause/resume/reactivate/cancel) · Wallet (transactions, add money) · Container / history · Subscriptions · Orders (view, place one-time custom/next-delivery/pickup, subscription daily/alternate/custom) · Next delivery + live status · Calendar · Trial request · Policies · Contact · Feedback · Login/register (username, mobile OTP) · Plus code.

**Catalogue headline:** ~108 admin leaf-actions; 21 have journeys (≈19% of admin, but the highest-traffic create-flows are covered). Customer App / Driver App / Website = **0 journeys and 0 possible journeys** (see §3).

---

## 2. Navigation Tree (admin, canonical — matches controller routes, not PDF prose)

```
Dashboard  (Orders/dashboard)
Customers
  ├─ Customers            Users/view      → Users/add          [add_customer]
  │    └─ (name)          Users/view/:id  → Wallet | Reward | Addresses | Contacts | Notes | Subscriptions | One-time | Invoices | Containers | Payment Methods
  ├─ Customer Groups      customergroups
  ├─ Unallocated Address  users/unallocated
  ├─ Unsubscribed         users/unsubscribed
  └─ Feedback             feedbacks
Catalogue
  ├─ Categories           Categories/index → Categories/add    [add_category | edit_category | toggle_category | delete_category]
  ├─ Sub Categories       SubCategories/index → Categories/add?cat_type=sub  [add/edit/toggle/delete/sequence_subcategory]
  ├─ Brands               Brands/… → Brands/add                [add_brand]
  ├─ Units                Units/… → Units/add                  [add_unit]
  ├─ Products             Products/index → Products/add        [add_product]
  ├─ Manage Branches      (multi-branch)
  └─ Vendor Commissions   (multi-store)
Orders
  ├─ One-time Orders      Orders/… → Orders/addManualOrder     [create_order*]
  ├─ Subscriptions        Orders/subscriptions                 (** no journey **)
  ├─ Missed Orders        Orders/missed
  ├─ Purchase Orders      (view)
  └─ Create order – Beta
Delivery / Deliveries
  ├─ Delivery Area        (map polygon — not WT)
  ├─ Delivery Time Slot   DeliverySchdules/add                 [add_time_slot]
  ├─ Delivery Routes      Routes/lists → Routes/add            [add_route]  (+ Master Route drag, Service Route view, optimization)
  ├─ Delivery Vehicles    Vehicles/lists → Vehicles/add        [add_vehicle]
  ├─ Delivery Drivers     Users/driver → Users/driverAdd       [add_driver]  (+ Shifts, Attendance, Device)
  ├─ Delivery Apartment   (premium)
  ├─ Delivery Area Hubs   (map)
  ├─ Delivery Sheet       (ops grid)
  └─ Delivery Map         (view)
Promotions
  ├─ Subscription Packages  Durations/index → Durations/add    [add_subscription_package]
  ├─ Discount Coupons       Coupons/index → Coupons/add        [add_coupon*]
  ├─ Promotional Banners    Banners/index → Banners/add        [add_banner]
  └─ Notifications          (area/customer/group/route)
Reports        (all view-only: Sales | Payments | Delivery | Inventory | Customers)
Activities     (Route History | SMS History | Email History | Log History — view/resend)
Settings
  ├─ Preferences  (System Settings | Users & Permissions | Manage Taxes | Predefined Reason | Order State | Container | Email | Notification | Mailchimp | Payment Methods | Website Settings | Refer & Earn)
  ├─ Static Pages | App Links | Contact Settings | Delivery Charges | Work Holidays
My Account   (vendor profile | store address | vendor ID | invoice history)
```

**Nav mismatch already handled by the runtime (report, not fix):** the PDF says "Catalogue › Sub Categories › Add new sub category", but the *route* the add link uses is `Categories/add` with `cat_type=sub` (see `add_subcategory` journey: it clicks `a[href*="cat_type=sub"]` from `SubCategories/index`, then operates on the `Categories/add` DOM). The journey is correct; the PDF label is user-facing. **Slug/nav authoring must use controller routes, not PDF breadcrumb text.**

---

## 3. Surface Classification — and the requirement that is satisfied *by construction*

The user's headline requirement: *"Show Me must never open a Driver App walkthrough while the user is inside Backoffice; never confuse Customer App with Vendor Dashboard."*

**Finding (critical, and reassuring):** for the **walkthrough engine** this is impossible by construction, not by policy. The engine (`walkthrough.js` + `journeys.js` + `showme.js`) runs *inside the admin dashboard DOM*. It drives `document` elements on admin pages. It physically cannot spotlight a screen in the Customer App or Driver App — those are separate mobile apps / a separate website with no shared DOM. So:

- Every journey is, and can only be, **admin-surface**. All 21 are. There is no mechanism by which Show Me launches a driver/customer tour.
- `showme.js::allowedByMenu()` adds a second gate: a journey is only offered if a menu `<a href>` to its area exists on the page — and the admin sidebar only renders admin, ACL-passed, feature-flag-enabled links. So the tour is gated to *reachable admin screens* automatically.

**Where the surface risk actually lives: the ANSWER (retrieval) layer, not the tour.** A user in the admin dashboard asks "how do I log out?" — the KB has three logout articles (customer app, driver app, admin). Answering an admin question with *Driver App* steps is the real failure mode. This is already mitigated by three components (all present):

1. `IntentRouter::querySurface($question)` → `driver | customer | admin` from question text (defaults `admin`, since the widget lives in admin).
2. `IntentRouter::categorySurface($category)` → maps a KB article's `category` to a surface; **only** `Driver App` / `Customer App` / `Customer Website` map away from admin — every back-office section (incl. the "Customers" section) stays `admin`.
3. `Retriever::preferSurface` → penalizes cross-surface passages at retrieval (the surface-guard fix).

**The PDF's value for surface safety:** it gives the *authoritative `category`→surface label for every article*, because the PDF is cleanly segmented by app. Recommendation (§20): audit every snapshot record's `category` against the PDF's surface segmentation so `categorySurface` never mislabels. That is the single highest-leverage surface improvement — and it's a data audit, not new code.

Surface classification table (article `category` → surface, from PDF segmentation):

| PDF segment | `category` values | `categorySurface` → |
|---|---|---|
| Backoffice/Dashboard/Catalogue/Orders/Delivery/Promotions/Reports/Settings/Activities/My Account | (all admin sections; incl. "Customers", "Feedback") | `admin` |
| Customer App / Customer Website | `Customer App`, `Customer Website`, `Customer Portal` | `customer` |
| Driver App | `Driver App` | `driver` |

---

## 4. Journey Catalogue (existing 21 — verified)

All admin-surface, all launch inside the dashboard. Columns: name · title · `permission` (ACL node) · start page · step count · shape.

| Journey | Title | permission | start page | steps | shape |
|---|---|---|---|---|---|
| `add_customer` | Add a customer | Users/view | Users/view | 10 | linear form |
| `add_brand` | Add a brand | Brands/add | Brands/add | 3 | linear |
| `add_unit` | Add a unit | Units/add | Units/add | 2 | linear |
| `add_category` | Add a category | Categories/index | Categories/index | 6 | list→form, 2 mandatory gates (area+schedule) |
| `edit_category` | Modify a category | Categories/edit | Categories/index | 4 | list→form |
| `toggle_category` | Enable/disable category | Categories/index | Categories/index | 1 | single control, `action:none` |
| `delete_category` | Delete a category | Categories/delete1 | Categories/index | 2 | destructive + confirm |
| `add_subcategory` | Add sub-category | SubCategories/index | SubCategories/index | 5 | cross-route (`cat_type=sub`→Categories/add) |
| `edit_subcategory` | Modify sub-category | SubCategories/edit | SubCategories/index | 4 | list→form |
| `toggle_subcategory` | Enable/disable sub-category | SubCategories/index | SubCategories/index | 1 | single control |
| `delete_subcategory` | Delete sub-category | SubCategories/delete1 | SubCategories/index | 2 | destructive + confirm |
| `sequence_subcategory` | Reorder sub-categories | SubCategories/index | SubCategories/index | 2 | drag (both `action:none`) |
| `add_product` | Add a product | Products/index | Products/index | 11 | list→form, many mandatory |
| `add_subscription_package` | Add subscription package | Durations/index | Durations/index | 4 | list→form |
| `add_coupon` | Add discount coupon | Coupons/index | Coupons/index | 11 | list→form (checkout-coupon variant only) |
| `add_time_slot` | Add delivery time slot | DeliverySchdules/add | DeliverySchdules/add | 5 | linear |
| `add_route` | Add delivery route | Routes/lists | Routes/lists | 5 | list→form |
| `add_vehicle` | Add delivery vehicle | Vehicles/lists | Vehicles/lists | 5 | list→form |
| `add_driver` | Add a driver | Users/driver | Users/driver | 10 | list→form |
| `add_banner` | Add promotional banner | Banners/index | Banners/index | 4 | list→form + upload |
| `create_order` | Create an order | Orders/addManualOrder | (variant, via `gotoHref`) | 3 | **flag-variant**, uses `gotoHref` to open whichever of 3 order screens exists |

**Engine capabilities observed (relevant to §10-13):** step fields `page`, `target` (CSS, comma-fallbacks supported), `text`, `action` (`click|input|none`), `required`, and `gotoHref` (navigate to a live menu link's URL — the flag-variant escape hatch). Resume-across-reload and auto-minimize exist (per the walkthrough system). No explicit per-step validation/branch/recovery primitives yet (see §10-13 gaps).

---

## 5. Slug → Journey Mapping (the cross-map; SDD Task 3)

The runtime link is **journey → KB slug** (a tour points at its explaining article) and the reverse **slug → journey** (an article offers its tour). Exact slugs must be resolved against the snapshot NDJSON at authoring time; the PDF confirms the article exists and its surface. Proposed map (topic-level; `?` = confirm slug against snapshot):

| Journey | KB article topic | Likely slug | Confidence |
|---|---|---|---|
| `add_customer` | Customers module / add customer | `customers` ? | high |
| `add_category` / `edit_` / `toggle_` / `delete_category` | Categories (add/modify/enable-disable/delete) | `categories` ? | high |
| `add_subcategory` / `edit_` / `toggle_` / `delete_` / `sequence_subcategory` | Sub-categories | `sub-categories` ? | high |
| `add_brand` | Brands | `brands` ? | high |
| `add_unit` | Units | `units` ? | high |
| `add_product` | Products | `products` ? | high |
| `add_subscription_package` | Subscription packages | `subscription-packages` ? | med |
| `add_coupon` | Discount coupons | `discount-coupons` ? | high |
| `add_time_slot` | Delivery time slots | `delivery-time-slot` ? | med |
| `add_route` | Delivery routes | `delivery-routes` ? / `routes` ? | med |
| `add_vehicle` | Delivery vehicles | `delivery-vehicles` ? | med |
| `add_driver` | Delivery drivers (create driver) | `delivery-drivers` ? / `creating-a-driver` ? | med |
| `add_banner` | Promotional banners | `promotional-banners` ? | high |
| `create_order` | One-time orders / create order / take-away | `one-time-orders` ? | **low (3 candidate articles)** |

**Cross-map rules (design):** (1) one journey may map to exactly one *canonical* slug (the article whose tour it is) but many articles may *reference* the journey via `related_intents`; (2) the map is hand-authored in `WalkthroughIndexer` and validated at reindex — a journey pointing at a non-existent slug, or a slug claiming a non-existent journey, must fail the build loudly; (3) `create_order`'s low confidence is a real ambiguity to resolve with the vendor's flag (§16/§18).

---

## 6. Related Intents (retrieval recall — feeds `synonyms`/`related_intents`/`question_variants`)

Per canonical journey, the natural-language variants to seed enrichment (merged, not replaced, by `EnrichmentMerger`). Sample (full set generated per-article in Task 7 rollout):

- **add_customer:** create customer, add client, new customer, register customer, onboard customer, customer registration, add a buyer, set up a customer, enroll customer, add customer account.
- **add_category:** create category, new category, add product category, set up a category, make a category, add a group of products.
- **add_product:** create product, add item, new product, list a product, add SKU, put up a product, add single/configurable/combo product.
- **add_coupon:** create coupon, add discount, promo code, discount code, recharge coupon, checkout coupon, subscription coupon, cashback code.
- **create_order:** place an order, make an order, add manual order, new order, book an order, create order for a customer, take-away order.
- **add_driver:** create driver, onboard driver, add delivery boy, register rider, new delivery agent, set up a driver login.

**Synonyms vs related_intents (schema discipline, per the enrichment pilot):** `synonyms` = surface lexical variants of the *same* action (they widen recall for the same slug). `related_intents` = *adjacent* actions that point to *other* slugs/journeys (they power follow-ups and graph edges). Keeping these two fields distinct is what prevents the retriever from collapsing "add a customer" into "add a customer address."

---

## 7. Follow-up Questions (chips — feeds `follow_up_questions`; SDD Tasks 4/5)

Ordered, ≤3 shown, drawn from the feature graph (§8). Sample:

- **After add_customer:** "How do I add a customer address?" · "How do I create the first order?" · "How do I set a credit limit?" (then: edit customer, add to a group, add a payment card).
- **After add_category:** "How do I add a sub-category?" · "How do I add a product?" · "How do I set delivery areas for a category?"
- **After add_product:** "How do I set min/max quantity?" · "How do I make a product a subscription?" · "How do I feature a product?"
- **After create_order:** "How do I create a subscription order?" · "How do I assign a driver?" · "How do I reschedule an order?"
- **After add_driver:** "How do I add a vehicle?" · "How do I create a route?" · "How do I set driver shifts?"

Confirmed with the user (this session): chips refresh on **every** answer — KB `follow_up_questions` on grounded how-to answers, existing client-generated chips on data answers. Design here only supplies the how-to set.

---

## 8. Feature Relationship Graph (enables intelligent follow-ups + "what next")

The onboarding spine from the PDF's own "Getting Started" flow, plus the entity graph:

```
Serviceable Area ─┬─ Category ── Sub-category ── Brand ── Unit ── Product ─┬─ (min/max, days, cut-off, area-wise)
                  │                                                        │
                  └─ Delivery Schedule (time slot) ── Route ── Driver ── Vehicle
Customer ── Address ─┬─ One-time Order ─┐
                     ├─ Subscription ───┼── Delivery (sheet/map) ── Container ── Invoice ── Payment ── Wallet
                     └─ Group ──────────┘
Coupon / Package / Banner / Notification  (promotions, attach to Customer/Order)
```

Graph edges become `related_intents` and follow-up ordering. Onboarding order (Area→Category→Sub→Brand→Unit→Product→Driver→Route) is a *guided-sequence* opportunity (§13/§18).

---

## 9. Walkthrough Suitability (classification + rationale)

**Suitable (Y):** deterministic form/flow with stable selectors and a clear success state — all 21 current journeys, plus gaps A2/A7/A11/A46/A48/A55/A57/A67/A75/A79/A80/A89/A90/A93/A94/A96/A98/A99/A101/A103/A104.

**Partial (needs branching or a decision step):** configurable/combo product (A31/A32), coupon-type branch (A76), notification-target branch (A80), subscription-type branch (A67), premium-flag features (A34-36, A50, A53, A106-107), and anything with an async job mid-flow.

**Never a walkthrough (N) — with rationale:**
- **Map/polygon/drag interactions:** delivery areas (A42-44), master-route sequencing (A49), hubs (A61), unallocated→area (A14). The engine spotlights DOM elements; it cannot meaningfully guide freehand polygon drawing or drag-reorder to a *correct* result. Documentation-only.
- **Pure view/report screens:** all Reports (A82-86), Purchase Orders (A72), Service Route (A51), negative-balance report (A52), device details (A58), attendance (A60), delivery map (A62). No actionable step; a tour would spotlight a table. Answer with KB text, no Show Me.
- **External account setup:** Play Store / Apple / Gmail-SMTP / DLT / payment-gateway account creation. These happen on third-party sites outside any Trakop DOM. Documentation-only, and the answer should link out.
- **File-upload / bulk jobs:** bulk product update/import (A38), bulk invoice download (A13). The meaningful work is off-screen (spreadsheet); guiding "click browse" adds little.
- **Customer App / Driver App / Website (all of §1b-1d):** engine cannot reach the DOM. **Documentation-only, forever.** Show Me must be suppressed for these even if a matching journey name were ever coined.

**Rule:** `WT? = N` articles must **never** surface a Show Me button. This is a property of the article (`walkthrough_suitable: false` enrichment flag) *and* enforced by the absence of a journey + surface guard.

---

## 10. UI Interaction Vocabulary → engine actions

PDF verbs map to a small closed action set:

| PDF verb(s) | Engine `action` | Notes |
|---|---|---|
| Click, Select (button/link), Submit, Save, Add, Update, Delete, Confirm | `click` | selector must resolve to the actionable control |
| Enter, Type, Fill, Search, Add (a value), Choose (dropdown), Pick, Upload | `input` | `required:true` for mandatory fields |
| View, See, Check, Observe, "the page appears", swipe/toggle explained-not-driven | `none` | narrate, do not act (e.g. `toggle_category`, `sequence_subcategory`) |

**Gap:** the engine has no `select-option`, `hover`, `wait-for`, or `assert` action distinct from the three above. Toggles and drags are modeled as `none` (narration). This is adequate today but is the ceiling on branchy/validated journeys (§13).

---

## 11. Decision Points / Branching (where journeys must fork)

The PDF exposes explicit forks the current linear model cannot express:

- **create_order:** 3 screen variants by feature flag → *already handled* via `gotoHref` (open whichever menu link exists). This is the reference pattern for flag-variance.
- **add_coupon:** recharge vs order vs checkout vs subscription coupon → different field sets. Current journey covers the checkout variant only.
- **subscription (A67):** daily vs alternate vs custom vs alternate-recurring vs multiple-product → materially different steps.
- **product (A30-32):** single vs configurable vs combo.
- **notifications (A80):** area vs customer vs group vs route target.
- **customer exists?** edit vs create (the user's own example): if the customer is already present → `edit_customer`; else → `add_customer`.

**Design:** introduce an optional `branch` step type — `{ branch: [{when: <selector-or-flag-present>, goto: <step-index|journey>}], else: … }`. Until then, model forks as *separate journeys* (e.g. `add_coupon_recharge`) mapped from the same article via `related_intents`, and let the retriever/answer disambiguate in prose. Prefer separate journeys over engine changes for the first rollout (YAGNI).

---

## 12. Validation Opportunities (never blindly advance)

Each step should confirm its precondition before narrating. From the PDF's "the page/list/popup appears" cues, the validations are:

| After step | Validate | Current behavior |
|---|---|---|
| open list→form (`click` add) | target form page loaded (`page` matches, form selector present) | engine waits for `page`/`target` presence (implicit) |
| mandatory input | field non-empty before advancing on user's own submit | **not enforced** — `required` is descriptive only |
| destructive `click` | confirmation dialog visible (`#delete_Button` present) | modeled as a `none` step that *describes* the dialog |
| save/submit | success toast / redirect to list / new row present | **not validated** — tour ends at the submit step |

**Design:** add a `waitFor` (selector appears) and `expect` (selector/text present after action) to each step; the engine polls with a timeout and shows a recovery hint on failure instead of advancing. This is the single biggest *accuracy* upgrade and directly answers the user's "validate every step before continuing / never rely on fixed delays."

---

## 13. Recovery Rules

Failure modes and prescribed recovery (design targets — most not yet implemented):

| Condition | Detection | Recovery |
|---|---|---|
| Selector missing (DOM changed) | `waitFor` timeout | try comma-fallback selectors (supported today) → else show "the screen looks different than expected; here are the written steps" + link to KB, end gracefully |
| Popup/modal closed by user | expected modal selector absent | re-narrate the trigger step (don't advance) |
| Page navigated away mid-tour | `page` no longer matches | offer "resume from here" (resume-across-reload exists) or restart |
| Permission denied / feature disabled | menu link absent (`allowedByMenu` false) | **never start** the tour; answer text-only |
| Flag-variant screen differs | `gotoHref` target absent | fall back to nearest available variant or documentation |
| Wrong surface (customer/driver question) | `querySurface != admin` | suppress Show Me; answer with same-surface KB text only |

**Principle:** prefer waiting for a UI condition over a fixed delay (matches condition-based-waiting); every unrecoverable step degrades to the grounded KB answer, never a dead spotlight.

---

## 14. Duplicated Knowledge (merge to one canonical article/journey)

The PDF repeats procedures across contexts — these must **not** become parallel sources:

- **Subscription create/edit** is documented ~4× (admin subscriptions, driver create-order, customer app, website) with near-identical steps. Canonical admin article + one journey; the customer/driver/website copies are surface-tagged documentation only.
- **Add money to wallet / recharge** appears in customer app, website, and admin (recharge). One article per surface; do not cross-wire follow-ups across surfaces.
- **Refer & earn** appears as admin config + customer app usage + website + banner. Canonical = admin config article; the rest reference it.
- **Delivery charges / area-wise / per-order** documented as three procedures on one screen → one article, one journey (A101), variants as prose.
- **Create order** appears as admin one-time, admin take-away, dashboard create, Beta, driver create, customer/website. Admin canonical = `create_order` (flag-variant). **This is the most duplicated flow and the `create_order` slug ambiguity in §5.**

**Rule:** dedupe by `(surface, canonical action)`. `EnrichmentMerger` already unions variant lists order-stably — extend the authoring guidance so duplicates fold into one slug's `question_variants` rather than spawning new slugs.

---

## 15. Missing Documentation (PDF gaps that hurt walkthrough accuracy)

- **No exact field IDs / selectors anywhere.** The PDF is prose; every selector in `journeys.js` was hand-verified against the live DOM. The PDF cannot author or repair selectors — a permanent limitation.
- **Mandatory-field lists are incomplete.** e.g. category add: the PDF omits that *area + schedule* are both mandatory (the form JS enforces "Please select area and schedule"); the journey captured it from the DOM, not the PDF. Assume the PDF under-specifies required fields.
- **Feature-flag / premium gating is described narratively** ("premium feature, email support@…") but never as a machine-readable precondition.
- **Version/variant coverage** (which of 3 create-order screens, weekly-frequency availability) is not tied to a flag name.
- **No success-state description** for most flows (what confirms the save worked).

**Implication:** the PDF is excellent for *content, intents, follow-ups, surface, prerequisites-in-prose*; it is useless for *selectors, exact required fields, success assertions*. Author those from the DOM.

---

## 16. Ambiguous Features (need a human/flag decision — do not guess)

1. **create_order canonical slug** — 3+ candidate articles and 3 screen variants. Resolve which article is canonical and confirm the flag that selects each screen.
2. **"Customers" naming** — admin section vs the customer *app*. `categorySurface` already special-cases this (stays `admin`), but authoring must not tag admin customer articles as `customer` surface.
3. **Coupon/subscription/product variants** — one journey with branches vs several journeys? (Recommendation §11: several journeys first.)
4. **Apartment vs Delivery-Area model** — two mutually-exclusive serviceable-area models (polygon areas vs society/apartment). A vendor has one or the other by flag; a tour must detect which before guiding.
5. **Multi-branch / multi-store** — changes the nav and some flows; premium+flag. Out of scope for first rollout unless the vendor has it.

---

## 17. Features that should NEVER become walkthroughs (hard list)

Consolidated from §9, stated as an enforcement list (article flag `walkthrough_suitable:false`, no journey, Show Me suppressed):

1. All Customer App articles (§1b) — engine cannot reach.
2. All Driver App articles (§1c) — engine cannot reach.
3. All Website articles (§1d) — engine cannot reach.
4. All Reports/statement/summary/view-only screens (A51-52, A58, A60, A62, A72, A82-88).
5. Map/polygon/drag flows (A42-44, A49, A61, A14).
6. External third-party setup (Play/Apple/Gmail-SMTP/DLT/payment-gateway account creation).
7. Bulk file-upload/download jobs (A13, A38).

---

## 18. Risks

| # | Risk | Severity | Mitigation |
|---|---|---|---|
| R1 | Selector drift — DOM changes silently break tours | **high** | comma-fallback selectors (have) + `waitFor`/`expect` + graceful degrade to KB text (§12-13); add a periodic selector-smoke test |
| R2 | `create_order` slug/variant ambiguity → wrong tour or wrong answer | high | resolve canonical slug + flag (§16.1); `gotoHref` already de-risks the screen choice |
| R3 | Cross-surface answer (driver steps for an admin question) | med | preferSurface + `categorySurface` audit against PDF segmentation (§3/§20) |
| R4 | PDF treated as source of truth → duplicate/contradictory knowledge | high | §0 rule enforced in authoring; `EnrichmentMerger` unions into existing slugs, never creates rogue slugs |
| R5 | Show Me offered on a view-only/customer/driver article | med | `walkthrough_suitable:false` flag + no-journey + surface guard (§9/§17); the analytics-question misfire already fixed via server-routing authority |
| R6 | Enrichment recall over-broadens (synonym bleed) → wrong journey matched | med | keep `synonyms` (same action) vs `related_intents` (adjacent) disciplined (§6); phased-by-category rollout with review (SDD Task 7) |
| R7 | Premium/flag features guided to vendors who lack them | med | `allowedByMenu` menu gate (have) + machine-readable precondition flag (§15/§19) |
| R8 | Maintenance: 108 admin features, hand-authored journeys don't scale | med | keep the catalogue as the coverage tracker; prioritize by traffic (§20 phases), not completeness |

---

## 19. Gaps between documentation and current implementation

- **Coverage:** 21/108 admin actions have journeys. Highest-value *missing* create-flows: **subscription create (A67)**, edit-customer (A2), customer address (A7), customer group (A11), work holidays (A104), delivery charges (A101), taxes (A93), users & permissions (A89), notifications (A80). Edit/delete siblings of existing add-journeys are cheap to add (A27/A29/A46/A48/A55/A57/A75/A79).
- **Engine primitives missing vs PDF needs:** no `branch`, no `waitFor`/`expect`, no `select-option`/`hover`. Toggles/drags degrade to narration.
- **Precondition modeling:** premium/flag/permission preconditions exist in prose (PDF) and as a menu gate (runtime) but not as a per-journey machine-readable `requires` list.
- **Success validation:** journeys end at the submit click; none confirm the record was created.
- **Slug↔journey link:** exists as design (SDD Task 3) but not yet built; §5 map needs slug confirmation against the snapshot.
- **Enrichment fields:** `synonyms`/`related_intents` are new (SDD Task 1/2 shipped the merge + indexer plumbing); content population (Tasks 6/7) pending — this document supplies that content per feature.

**Explicit conflicts to report (not fix here):**
1. PDF nav "Sub Categories › Add" vs actual route `Categories/add?cat_type=sub` — journey is right, PDF label is user-facing. (§2)
2. PDF omits mandatory area+schedule on category add — journey adds them from DOM truth. (§15)
3. PDF documents customer/driver/website flows as if first-class features; runtime can only ever *answer* about them, never *tour* them. (§3/§17)
4. `add_coupon` journey covers only the checkout-coupon variant while the PDF documents four coupon types under one article. (§11)

---

## 20. Phased Implementation Plan (prioritized by impact)

**Design principle for all phases:** everything routes through the *existing* pipeline (snapshot NDJSON → `EnrichmentMerger` → `FaqIndexer`/`WalkthroughIndexer` → pgvector → `Retriever`/`_faqGroundingBlock` → `ask()` → widget). No parallel knowledge store. This dovetails with the in-flight SDD (Tasks 3-7).

**Phase 0 — Foundations (mostly shipped in SDD Tasks 1-2):** enrichment merge + FaqIndexer `synonyms`/`related_intents`/`follow_up_questions`. ✅

**Phase 1 — Surface & suitability data audit (highest safety/lowest effort).** Using this document's §1/§3/§9/§17: (a) verify every snapshot record's `category`→surface against PDF segmentation (kills cross-surface answers), (b) add `walkthrough_suitable` flag so view-only/customer/driver/external articles never show Show Me. *Data-only; no engine code.*

**Phase 2 — Slug↔journey cross-map (SDD Task 3).** Build the bidirectional map for the 21 journeys (§5), confirming slugs against the snapshot; fail the reindex on a broken link. Resolve `create_order` ambiguity (§16.1) with the vendor flag.

**Phase 3 — Enrichment content rollout (SDD Tasks 6/7), per category, reviewed.** Populate `question_variants`/`synonyms`/`related_intents`/`follow_up_questions` from §6/§7/§8 for the covered features first (they have tours to launch), then high-traffic uncovered ones. Follow-up chips (Tasks 4/5) go live here.

**Phase 4 — Journey coverage expansion (by traffic).** Cheap wins first: edit/delete siblings of existing adds (A27/A29/A46/A48/A55/A57/A75/A79) and `edit_customer`/`add_customer_address` (the user's own example flow). Then subscription-create (A67, branchy) and the other §19 create-flows.

**Phase 5 — Engine robustness (accuracy).** Add `waitFor`/`expect` validation and graceful recovery (§12-13). Optional `branch` step type (§11) only if the separate-journey approach proves insufficient. Add a selector-smoke test to catch R1 drift.

**Phase 6 — Guided sequences.** Chain journeys along the onboarding spine (§8) — "set up my store" → area→category→…→product→driver→route — using follow-up chips as the connective tissue.

---

## Appendix — how this PDF should be used, going forward

- **Do:** treat the PDF as the *content and intent* authority — it is the best source for `question_variants`, `synonyms`, `related_intents`, `follow_up_questions`, surface segmentation, and prose prerequisites. Re-scrape it into the snapshot; enrich; reindex.
- **Do:** use it as the *coverage map* (this document's §1 catalogue) to decide what to build next.
- **Don't:** author selectors, exact required-field lists, success assertions, or nav routes from it — author those from the live DOM/controllers.
- **Don't:** let it create new slugs that duplicate existing articles, or tour non-admin surfaces.
- **Maintainability:** one knowledge model, three cross-linked artifacts, PDF as authoring input. Every accuracy gain is either a *data* change (enrichment/surface/suitability) or a *small engine* change (validation/recovery) — never a second source of truth.
