# In-app tutorial (Descrybe v2) Hands-on product tour in `apps/web`. Progress is stored in `localStorage` under `descrybe.tutorial.v2`. ## Behavior - **Skip tour** — ends the tour entirely (`status: skipped`). Restart from the header or dashboard. - **Pause** / **Escape** — dismisses the overlay but keeps `in_progress` so **Resume tutorial** works. - **Action steps** — no free Continue. The user must click the highlighted control (`advanceOn: "click"`) or complete a real success path (`advanceOn: "action"` via `tutorial.reportAction(stepId)`). - **Informational steps** — only **welcome** and **done** use Continue / Done. - **Restart tutorial** — shown after completed or skipped; starts from step 1. ## Step list | # | id | Route / UI | Advance when | |---|----|------------|--------------| | 1 | `welcome` | `/dashboard` welcome header | Continue | | 2 | `standard-fields-nav` | Nav → Standard Fields | Click `data-tour="nav-standard-fields"` | | 3 | `enable-recommended` | `/standard-fields` | Enable recommended API succeeds | | 4 | `feeds-nav` | Nav → Feeds | Click `data-tour="nav-feeds"` | | 5 | `open-feed` | `/feeds` | Click **Map** (`data-tour="feed-open-mapping"`) | | 6 | `auto-map` | `/feeds/{id}/mapping` | Auto-map applies suggestions | | 7 | `save-mappings` | mapping footer | Save Mappings succeeds | | 8 | `sync-process-sample` | mapping footer | Sync + Process sample succeeds | | 9 | `products-nav` | Nav → Products | Click `data-tour="nav-products"` | | 10 | `products-result` | `/products` table | Click `data-tour="products-table"` | | 11 | `export-feeds-nav` | Nav → Export Feeds | Click `data-tour="nav-export-feeds"` | | 12 | `export-create` | `/export-feeds` | Click Create Export Feed | | 13 | `campaigns-nav` | Nav → Campaigns | Click `data-tour="nav-campaigns"` | | 14 | `campaigns-create` | `/campaigns` | Click New campaign | | 15 | `done` | `/dashboard` | Done | There is **no Uploads** step — uploads were removed from the main nav; feeds cover catalog ingest. ## Key files | Path | Role | |------|------| | `apps/web/src/lib/tutorial/steps.ts` | Step definitions | | `apps/web/src/lib/tutorial/state.svelte.ts` | Controller (start / resume / restart / skip / reportAction) | | `apps/web/src/lib/tutorial/storage.ts` | localStorage read/write | | `apps/web/src/lib/tutorial/dom.ts` | Preferential selector matching | | `apps/web/src/lib/components/tutorial/TutorialOverlay.svelte` | Spotlight overlay + progress | | `apps/web/src/lib/components/Nav.svelte` | `data-tour="nav-*"` attrs | | `apps/web/src/routes/+layout.svelte` | Header Start / Resume / Restart | | `apps/web/src/routes/dashboard/+page.svelte` | Dashboard Start / Resume / Restart | ## Wiring success (`advanceOn: "action"`) Pages call `tutorial.reportAction("")` only after a successful operation: - `standard-fields/+page.svelte` → `enable-recommended` - `feeds/[feedId]/mapping/+page.svelte` → `auto-map`, `save-mappings`, `sync-process-sample` ## Manual test checklist 1. Clear `localStorage` key `descrybe.tutorial.v2` (or use Restart). 2. Dashboard → **Start tutorial** → Continue on welcome. 3. Confirm action steps show **no Continue** button; only Skip tour / Pause / Back. 4. Click each highlighted nav item / control; confirm progress bar advances. 5. On mapping: Auto-map → Save → Sync sample must succeed before advance. 6. **Pause**, reload, **Resume tutorial** restores the same step. 7. **Skip tour**, then **Restart tutorial** from header. 8. Complete through Done; **Restart tutorial** appears. ## Notes - Soft-route steps (`auto-map`, `save-mappings`, `sync-process-sample`) do not auto-navigate; they wait until you open a feed mapping URL. - If **Map** is missing, add a feed first — the tour does not skip ahead. - Selector lists (comma-separated) are resolved in **listed order**, not document order.