# Descrybe v2 — UI / UX design gaps vs legacy **Audit date:** 2026-08-03 **Legacy:** `f:/laragon/www/_MY/descrybe` **v2 web:** `f:/laragon/www/_MY/descrybe-v2/apps/web` **Scope:** Visual and UX parity only (routes, nav, dialogs, stubs, layout). No fixes in this pass. **Related:** [status-and-gaps.md](status-and-gaps.md) (backend/product gaps), [features.md](features.md) Priority legend: | Priority | Meaning | |----------|---------| | **P0** | Blocks daily-ops parity or presents a broken/misleading UI for a core path | | **P1** | Important feature parity / polish; workaround exists or path is secondary | | **P2** | Nice-to-have chrome, marketing, or low-traffic screens | --- ## 1. Legacy dashboard + auth routes ### Auth / entry (`app/(auth)` + related) | Route | File | |-------|------| | `/login` | `app/(auth)/login/[[...login]]/page.tsx` | | `/signup` | `app/(auth)/signup/[[...signup]]/page.tsx` | | `/accept-invitation` | `app/accept-invitation/page.tsx` | | `/onboarding` | `app/onboarding/page.tsx` | Auth layout: `app/(auth)/layout.tsx` (Clerk SignIn/SignUp, branded header with **Book a Demo**, privacy/terms footer). ### Dashboard (`app/dashboard`) | Route | File / notes | |-------|----------------| | `/dashboard` | `page.tsx` → news + stats home | | `/dashboard/products` | `products/page.tsx` | | `/dashboard/feeds` | `feeds/page.tsx` | | `/dashboard/feeds/[feedId]/mapping` | `feeds/[feedId]/mapping/page.tsx` (older mapping) | | `/dashboard/feeds/[feedId]/mapping-v2` | `feeds/[feedId]/mapping-v2/page.tsx` (**current** entry from feed actions) | | `/dashboard/export-feeds` | `export-feeds/page.tsx` | | `/dashboard/export-feeds/new` | `export-feeds/new/page.tsx` (`?format=xml\|csv` → full `ExportFeedBuilder`) | | `/dashboard/export-feeds/[feedId]` | exists as edit path used by table “Edit” | | `/dashboard/categories` | `categories/page.tsx` | | `/dashboard/categories/[categoryId]/title-formula` | formula builder | | `/dashboard/categories/[categoryId]/description-formula` | description formula builder | | `/dashboard/attributes` | `attributes/page.tsx` | | `/dashboard/standard-fields` | `standard-fields/page.tsx` | | `/dashboard/tasks` | `tasks/page.tsx` (background tasks) | | `/dashboard/billing` | `billing/page.tsx` | | `/dashboard/settings` | `settings/page.tsx` | | `/dashboard/plans` | `plans/page.tsx` | | `/dashboard/process/new` | `process/new/page.tsx` (dedicated process wizard) | | `/dashboard/structured-descriptions` | present; **commented out of sidebar** | | `/dashboard/vector-categories` | present; not in sidebar | ### Admin (outside dashboard, gated) | Route | File | |-------|------| | `/admin` | `app/admin/page.tsx` | | `/admin/users` | `app/admin/users/page.tsx` | | `/admin/analytics` | `app/admin/analytics/page.tsx` | | `/admin/billing` | `app/admin/billing/page.tsx` | | `/admin/logs` | `app/admin/logs/page.tsx` | | `/admin/stuck-products` | `app/admin/stuck-products/page.tsx` | | `/admin/settings` | `app/admin/settings/page.tsx` | | `/admin/bootstrap` | `app/admin/bootstrap/page.tsx` | | `/admin/migrate-organizations` | `app/admin/migrate-organizations/page.tsx` | | `/admin/tasks-cleanup` | `app/admin/tasks-cleanup/page.tsx` | WooCommerce in legacy is **not** a top-level dashboard nav item; it lives under export-feed actions (`components/export-feeds/woocommerce-*.tsx`). ### Legacy sidebar nav (`components/utilities/sidebar.tsx`) Order: Dashboard → Products → Feeds → Export Feeds → Categories → Attributes → Standard Fields → Background Tasks → Usage & Billing → Settings. (Structured Fields / WooCommerce / Admin are **not** in this customer sidebar.) --- ## 2. v2 routes (`apps/web/src/routes`) ### Auth | Route | File | |-------|------| | `/login` | `login/+page.svelte` | | `/register` | `register/+page.svelte` (legacy `/signup`) | | `/accept-invite` | `accept-invite/+page.svelte` (legacy `/accept-invitation`) | ### App shell | Route | File | |-------|------| | `/` | `+page.svelte` (dashboard home; legacy `/dashboard`) | | `/products` | `products/+page.svelte` | | `/feeds` | `feeds/+page.svelte` | | `/feeds/[feedId]/mapping` | `feeds/[feedId]/mapping/+page.svelte` | | `/export-feeds` | `export-feeds/+page.svelte` (list **and** create/edit dialog — no `/new` or `/[id]` routes) | | `/categories` | `categories/+page.svelte` | | `/categories/[categoryId]/title-formula` | `…/title-formula/+page.svelte` | | `/categories/[categoryId]/description-formula` | `…/description-formula/+page.svelte` | | `/attributes` | `attributes/+page.svelte` | | `/standard-fields` | `standard-fields/+page.svelte` | | `/processing` | `processing/+page.svelte` | | `/tasks` | `tasks/+page.ts` only — **307 redirect** → `/processing` | | `/billing` | `billing/+page.svelte` | | `/settings` | `settings/+page.svelte` | | `/woocommerce` | `woocommerce/+page.svelte` (**v2-only** top-level page) | | `/plans` | `plans/+page.svelte` (not in nav) | | `/structured-descriptions` | `structured-descriptions/+page.svelte` (not in nav) | | `/vector-categories` | `vector-categories/+page.svelte` (not in nav) | ### Admin | Route | File | |-------|------| | `/admin` | `admin/+page.svelte` | | `/admin/users` | `admin/users/+page.svelte` | | `/admin/analytics` | `admin/analytics/+page.svelte` | | `/admin/billing` | `admin/billing/+page.svelte` | | `/admin/logs` | `admin/logs/+page.svelte` | | `/admin/stuck-products` | `admin/stuck-products/+page.svelte` | | `/admin/settings` | `admin/settings/+page.svelte` | | `/admin/bootstrap` | `admin/bootstrap/+page.svelte` | | `/admin/migrate-organizations` | `admin/migrate-organizations/+page.svelte` | | `/admin/tasks-cleanup` | `admin/tasks-cleanup/+page.svelte` | ### v2 sidebar nav (`src/lib/components/Nav.svelte`) Order: Dashboard → Products → Feeds → Export Feeds → Categories → Attributes → Standard Fields → Background Tasks → Usage & Billing → Settings → **WooCommerce** → **Admin**. Admin link is **always rendered** (not gated by `is_platform_admin`); page gate is client-side via `requirePlatformAdmin()`. --- ## 3. Route / nav comparison matrix | Capability | Legacy | v2 | Gap | |------------|--------|----|-----| | Dashboard home | `/dashboard` | `/` | Path rename only | | Products | `/dashboard/products` | `/products` | Feature gaps (see P0) | | Feeds list | `/dashboard/feeds` | `/feeds` | Mostly present | | Feed mapping (rich) | `/feeds/.../mapping-v2` | `/feeds/.../mapping` | **No mapping-v2 / schema extract / live XML tree** | | Export list | `/export-feeds` | `/export-feeds` | OK shell | | Export create/edit | `/export-feeds/new`, `/[feedId]` + `ExportFeedBuilder` | Single-page dialog | **Missing full builder route** | | Categories + formulas | yes | yes | Bulk Formula stub; double title chrome | | Attributes | yes | yes | Missing per-attr Manage Categories | | Standard Fields | yes (live) | shell + “API not available” banner | **Non-functional nav item** | | Background Tasks | `/tasks` | `/processing` (+ `/tasks` redirect) | Floating task indicator missing | | Billing / Settings | yes | yes | Close | | Plans | `/plans` | `/plans` | Shell; API banner | | Process wizard | `/process/new` | — | **Missing dedicated route** | | Structured descriptions | route (nav commented out) | route, no nav | Shell; API banner | | Vector categories | route | route, no nav | Shell; API banner | | WooCommerce | export-feed dialogs | `/woocommerce` nav item | Different IA; maps UI thin | | Admin | separate `/admin` layout, not in customer sidebar | always in customer Nav | **IA + visibility gap** | | Signup | Clerk `/signup` | `/register` | Rename OK | | Invite | `/accept-invitation` | `/accept-invite` | Rename OK | | Onboarding tour | `TourProvider` in dashboard layout | — | Missing | --- ## 4. Dialog inventory ### Legacy dialogs (representative) | Dialog | Path | v2 counterpart | |--------|------|----------------| | Export selection (pick export feed) | `components/products/export-selection-dialog.tsx` | **Missing** — CSV download only | | CSV EAN upload | `components/dashboard/csv-ean-upload-dialog.tsx` | `UploadEansDialog.svelte` | | Add category attribute (product edit) | `components/dashboard/add-category-attribute-dialog.tsx` | **Missing** | | Manage categories (per attribute) | `components/attributes/manage-categories-dialog.tsx` + TreeSelect | **Missing** (bulk CSV only) | | Manage list values | `components/attributes/manage-list-values-dialog.tsx` | Inline dialog in `attributes/+page.svelte` | | Bulk category↔attribute CSV | `components/attributes/bulk-category-assignments-dialog.tsx` | Inline bulk dialog | | Bulk formula builder | `components/categories/bulk-formula-builder-dialog.tsx` | **Stub button** (toast message) | | Field mapping / sync history | `components/feeds/*` | Partial (history dialog exists; mapping preview stub) | | Export WooCommerce config | `components/export-feeds/woocommerce-integration-dialog.tsx` | Moved to `/woocommerce`; not on export row | | Standard field / group dialogs | `components/standard-fields/*` | Present in page; **API unavailable** | | Admin assign/create plan | `components/admin/billing/*` | Admin billing page exists; verify depth | | Add credits | `components/dashboard/add-credits-dialog.tsx` | Inline on billing page | ### v2 dialogs present under `$lib/components` Category: `AddCategoryDialog`, `EditCategoryDialog`, `DeleteCategoryDialog`, `TreeSelectDialog`, formula dialogs (`CustomVariableDialog`, `ManageVariablesDialog`, `TextElementDialog`, `ConfirmationDialog`). Products: `UploadEansDialog` only. UI primitive: `Dialog.svelte`. Many “dialogs” are inlined in route `+page.svelte` files rather than shared components. --- ## 5. Findings by priority ### P0 — fix before claiming UI cutover readiness 1. **Feed mapping: live XML/CSV schema preview** — **DONE (2026-08-08)** - **v2 now:** `feeds/[feedId]/mapping/+page.svelte` + `FeedSourcePreview` + `MappingPreviewPanel` + `POST /api/feeds/{id}/extract-schema` (click-to-pick path, extract/refresh, sample preview). - Residual polish (CSV column-click pick, legacy mapping-v2 chrome) is P1 — not a cutover blocker. 2. **Export feed create/edit is a thin dialog, not the full builder** — **WAIVED for cutover** - **WAIVER ID:** `DESIGN-P0-EXPORT-BUILDER-2026-08-08` - **v2:** `export-feeds/+page.svelte` in-dialog create/edit (`formRoot` / `formItem` / flat `fields[]`) covers create, edit, refresh, and download for daily ops. - **Deferred:** dedicated `/export-feeds/new` + `/export-feeds/[id]` `ExportFeedBuilder` (structure editor, custom variables, Woo column actions) — large UI port, not required when dialog template editing works. - Re-open only if a tenant needs legacy builder-only flows. 3. **Products “Export Selected” bypasses export feeds** - **v2:** `products/+page.svelte` `exportSelected()` builds a client-side CSV blob and downloads it. - **Legacy:** `ExportSelectionDialog` → choose configured export feed → server export job. - **Wrong:** Wrong UX contract; no feed picker dialog; cannot export via template XML/CSV. 4. **“Reset to Unprocessed” is a stub** - **v2:** `products/+page.svelte` sets `success = "Reset to unprocessed is not available in v2 yet."` - **Legacy:** mutation in `products-client.tsx` calls reset action and updates selection. - **Wrong:** Button appears in `ProductProcessingActions.svelte` but does nothing useful. 5. **Standard Fields API** — **DONE (2026-08-08)** - **v2:** `GET/POST/PATCH/DELETE /api/standard-fields` + `/api/field-groups` (+ bulk-enable / enable-recommended) mounted in `httpapi/server.go`; `standard-fields/+page.svelte` CRUD wired via `apiAvailable`. - Stale “API not available” copy in older checklists no longer applies when the API is up. 6. **Product edit Attributes tab** — **DONE (MVP, 2026-08-08)** - **v2:** `ProductEditPanel` Attributes tab supports add/edit/remove key-value rows; save/accept PATCH includes `attributes` (`UpdateProcessedProduct`). - **Deferred (P1):** legacy `AddCategoryAttributeDialog` (pick from category attribute catalog) — not required for free-form attribute fix-ups. 7. **Attributes: no per-attribute “Manage Categories” / tree assign dialog** - **v2:** Row menu = Edit Details / Manage Values / Delete; bulk CSV assign only (`showBulkAssign`). Unit/example fields in Edit are **disabled**. - **Legacy:** `ManageCategoriesDialog` + TreeSelect + editable unit/example. - **Wrong:** Operators cannot visually assign one attribute to categories without CSV. 8. **Admin Settings / Admin home are UI demos (non-persisting)** - **v2:** `admin/settings/+page.svelte` — `saveDemo(label)` → *“saved (UI demo — not persisted by API yet)”* for General/Security/API/Pricing/Maintenance. - **v2:** `admin/+page.svelte` — *“Admin configuration saved! (UI demo — not persisted…)”*. - **Wrong:** Controls look real; saves are fake. 9. **Admin Logs page has no data path** - **v2:** `admin/logs/+page.svelte` — *“System logs API is not available in v2 yet.”* Table chrome only. - **Wrong:** Nav item under Admin presents empty operational tooling. 10. **Admin always visible in customer sidebar** - **v2:** `Nav.svelte` hardcodes `{ href: "/admin", label: "Admin" }` for every signed-in user. - **Legacy:** Admin is a separate app shell (`app/admin/layout.tsx` + `AdminSidebar`); **not** in `components/utilities/sidebar.tsx`. - **Wrong:** Clutters IA; non-admins hit a gate/error after navigation (misleading). 11. **Categories Bulk Formula Builder is stubbed** - **v2:** `categories/+page.svelte` button sets success message: *“Bulk Formula Builder … is not wired in v2 yet.”* - **Legacy:** `bulk-formula-builder-dialog.tsx` full CSV → AI titles flow. - **Wrong:** Primary page action is decorative. 12. **Floating TaskStatusIndicator** — **DONE (2026-08-08)** - **v2:** `TaskStatusIndicator` mounted from `+layout.svelte` (signed-in, non-auth/marketing/admin); polls `/api/processing/jobs`, shows active job progress + link to `/processing`. - Scope: processing jobs only (feed sync remains on feed row / history — same as existing feeds UX). --- ### P1 — important parity / incomplete dialogs 13. **Dedicated `/process/new` wizard missing** - Legacy: `app/dashboard/process/new/` selects raw products + kicks processing. - v2: processing starts from Products selection only. Dashboard “Start Processing” just `goto("/products")`. 14. **Export list missing WooCommerce column / row actions** - Legacy table: optional WooCommerce status + Configure/Sync actions (`export-feeds-table.tsx`). - v2 table columns: Name, Format, Feed URL, Last Updated, Status, Actions — no Woo column. 15. **Feed source types UX limited to URL CSV/XML** - v2 Add Feed dialog: name + URL + type select (`feeds/+page.tsx`). - Legacy mapping-v2 supports CSV/Excel paths and richer reset/extract; FTP/file upload remain product gaps (also backend). 16. **Categories page double title / spacing** - `PageShell title="Categories"` **and** inner `