Files
descrybe/docs/design-gaps.md
T

352 lines
20 KiB
Markdown
Raw Normal View History

# 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 `<h1 class="text-3xl…">Categories</h1>` in `categories/+page.svelte` → duplicated heading and extra vertical space vs legacy single header pattern.
17. **Plans / Structured Descriptions / Vector Categories shells**
- Routes exist with legacy-looking UI but API banners (`plans/+page.svelte`, `structured-descriptions/+page.svelte`, `vector-categories/+page.svelte`).
- Not in nav (same as legacy for structured), but deep-links look “done” while disabled.
18. **Admin bootstrap is instructional only**
- `admin/bootstrap/+page.svelte`: *“Bootstrap is not available via API… set is_platform_admin in DB.”*
19. **WooCommerce rich mapping UI**
- `/woocommerce` has config + auto-map buttons, but no legacy-depth mapping table/editor for overrides (status-and-gaps also notes this).
20. **Auth marketing chrome incomplete**
- Legacy login: sticky header + **Book a Demo** CTA + privacy/terms links.
- v2 auth layout (`+layout.svelte`): logo header + simple footer copyright; no Demo CTA, no privacy/terms routes wired in footer.
21. **Onboarding tour / NavigationProgress missing**
- Legacy dashboard layout wraps `TourProvider` + `NavigationProgress`.
- v2 layout has neither.
22. **Job/export dialogs from products**
- Legacy `job-export-dialog.tsx` for exporting job results.
- v2: not found under products components.
23. **Attribute edit: unit & example disabled**
- `attributes/+page.svelte` Edit dialog: `editUnit` / `editExample` inputs `disabled` — looks editable in legacy.
24. **NewsFeed “More updates coming soon”**
- `NewsFeed.svelte` ends with static “coming soon” — fine as content, but weaker than legacy news richness if operators expect changelog parity.
---
### P2 — polish / low traffic
25. **Path / naming deltas** (`/register` vs `/signup`, `/accept-invite` vs `/accept-invitation`, `/processing` vs `/tasks`) — redirects/docs only.
26. **Admin migrate-orgs / tasks-cleanup** — pages exist; confirm copy and empty states match legacy density.
27. **Description/title formula:** drag reorder exists (`FormulaBuilder.svelte` HTML5 DnD); still may lack legacy `@hello-pangea/dnd` polish / edge cases — verify against `title-formula` client before calling pixel-complete.
28. **Auth card-only main** vs Clerk multi-step branding (intentional first-party auth; visual tone differs).
29. **No dark-theme admin shell** — legacy admin forces `defaultTheme="dark"`; v2 admin uses same light customer tokens.
30. **Sign-out placement** — v2 Nav has Sign out under items; legacy relied more on Clerk user button in header (v2 has avatar → settings only).
---
## 6. Known stubs / demo markers (code pointers)
| Location | Marker |
|----------|--------|
| `routes/categories/+page.svelte` | Bulk Formula Builder not wired |
| `routes/products/+page.svelte` | Reset to unprocessed not available |
| `routes/plans/+page.svelte` | Plans API not available |
| `routes/structured-descriptions/+page.svelte` | Structured descriptions API not available |
| `routes/vector-categories/+page.svelte` | Vector categories API not available |
| `routes/admin/settings/+page.svelte` | `saveDemo()` — UI demo |
| `routes/admin/+page.svelte` | UI demo save |
| `routes/admin/logs/+page.svelte` | Logs API not available |
| `routes/admin/bootstrap/+page.svelte` | Bootstrap not available via API |
| `lib/components/NewsFeed.svelte` | “More updates coming soon” |
~~Removed as closed:~~ mapping XML tree placeholder; standard-fields “API not available” (API mounted).
---
## 7. Suggested fix order (UI-only)
1. ~~Feed mapping preview + schema extract UX~~ **DONE**.
2. ~~ExportFeedBuilder dedicated routes~~ **WAIVED** (`DESIGN-P0-EXPORT-BUILDER-2026-08-08`) — dialog covers daily ops.
3. Export Selection dialog on products; implement Reset to Unprocessed.
4. ~~Product edit attribute editing~~ **DONE (MVP)**; Add Category Attribute remains P1.
5. Attributes Manage Categories (reuse `TreeSelectDialog`).
6. Gate Admin (and optionally Woo) in `Nav.svelte`.
7. Replace admin `saveDemo` with real endpoints or disable Save.
8. Re-enable Bulk Formula Builder dialog.
9. ~~Port TaskStatusIndicator into `+layout.svelte`~~ **DONE**.
10. Auth footer links + Demo CTA if marketing parity required.
11. ~~Standard Fields API~~ **DONE** (handlers mounted).
---
## 8. Out of scope for this audit
Backend/migrator/CI gaps already tracked in [status-and-gaps.md](status-and-gaps.md). This document only covers what users see and click in the web app versus the legacy Next.js UI.