Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
20 KiB
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 (backend/product gaps), 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
-
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.
- v2 now:
-
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.sveltein-dialog create/edit (formRoot/formItem/ flatfields[]) 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.
- WAIVER ID:
-
Products “Export Selected” bypasses export feeds
- v2:
products/+page.svelteexportSelected()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.
- v2:
-
“Reset to Unprocessed” is a stub
- v2:
products/+page.sveltesetssuccess = "Reset to unprocessed is not available in v2 yet." - Legacy: mutation in
products-client.tsxcalls reset action and updates selection. - Wrong: Button appears in
ProductProcessingActions.sveltebut does nothing useful.
- v2:
-
Standard Fields API — DONE (2026-08-08)
- v2:
GET/POST/PATCH/DELETE /api/standard-fields+/api/field-groups(+ bulk-enable / enable-recommended) mounted inhttpapi/server.go;standard-fields/+page.svelteCRUD wired viaapiAvailable. - Stale “API not available” copy in older checklists no longer applies when the API is up.
- v2:
-
Product edit Attributes tab — DONE (MVP, 2026-08-08)
- v2:
ProductEditPanelAttributes tab supports add/edit/remove key-value rows; save/accept PATCH includesattributes(UpdateProcessedProduct). - Deferred (P1): legacy
AddCategoryAttributeDialog(pick from category attribute catalog) — not required for free-form attribute fix-ups.
- v2:
-
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.
- v2: Row menu = Edit Details / Manage Values / Delete; bulk CSV assign only (
-
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.
- v2:
-
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.
- v2:
-
Admin always visible in customer sidebar
- v2:
Nav.sveltehardcodes{ href: "/admin", label: "Admin" }for every signed-in user. - Legacy: Admin is a separate app shell (
app/admin/layout.tsx+AdminSidebar); not incomponents/utilities/sidebar.tsx. - Wrong: Clutters IA; non-admins hit a gate/error after navigation (misleading).
- v2:
-
Categories Bulk Formula Builder is stubbed
- v2:
categories/+page.sveltebutton sets success message: “Bulk Formula Builder … is not wired in v2 yet.” - Legacy:
bulk-formula-builder-dialog.tsxfull CSV → AI titles flow. - Wrong: Primary page action is decorative.
- v2:
-
Floating TaskStatusIndicator — DONE (2026-08-08)
- v2:
TaskStatusIndicatormounted 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).
- v2:
P1 — important parity / incomplete dialogs
-
Dedicated
/process/newwizard missing- Legacy:
app/dashboard/process/new/selects raw products + kicks processing. - v2: processing starts from Products selection only. Dashboard “Start Processing” just
goto("/products").
- Legacy:
-
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.
- Legacy table: optional WooCommerce status + Configure/Sync actions (
-
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).
- v2 Add Feed dialog: name + URL + type select (
-
Categories page double title / spacing
PageShell title="Categories"and inner<h1 class="text-3xl…">Categories</h1>incategories/+page.svelte→ duplicated heading and extra vertical space vs legacy single header pattern.
-
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.
- Routes exist with legacy-looking UI but API banners (
-
Admin bootstrap is instructional only
admin/bootstrap/+page.svelte: “Bootstrap is not available via API… set is_platform_admin in DB.”
-
WooCommerce rich mapping UI
/woocommercehas config + auto-map buttons, but no legacy-depth mapping table/editor for overrides (status-and-gaps also notes this).
-
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.
-
Onboarding tour / NavigationProgress missing
- Legacy dashboard layout wraps
TourProvider+NavigationProgress. - v2 layout has neither.
- Legacy dashboard layout wraps
-
Job/export dialogs from products
- Legacy
job-export-dialog.tsxfor exporting job results. - v2: not found under products components.
- Legacy
-
Attribute edit: unit & example disabled
attributes/+page.svelteEdit dialog:editUnit/editExampleinputsdisabled— looks editable in legacy.
-
NewsFeed “More updates coming soon”
NewsFeed.svelteends with static “coming soon” — fine as content, but weaker than legacy news richness if operators expect changelog parity.
P2 — polish / low traffic
- Path / naming deltas (
/registervs/signup,/accept-invitevs/accept-invitation,/processingvs/tasks) — redirects/docs only. - Admin migrate-orgs / tasks-cleanup — pages exist; confirm copy and empty states match legacy density.
- Description/title formula: drag reorder exists (
FormulaBuilder.svelteHTML5 DnD); still may lack legacy@hello-pangea/dndpolish / edge cases — verify againsttitle-formulaclient before calling pixel-complete. - Auth card-only main vs Clerk multi-step branding (intentional first-party auth; visual tone differs).
- No dark-theme admin shell — legacy admin forces
defaultTheme="dark"; v2 admin uses same light customer tokens. - 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)
Feed mapping preview + schema extract UXDONE.ExportFeedBuilder dedicated routesWAIVED (DESIGN-P0-EXPORT-BUILDER-2026-08-08) — dialog covers daily ops.- Export Selection dialog on products; implement Reset to Unprocessed.
Product edit attribute editingDONE (MVP); Add Category Attribute remains P1.- Attributes Manage Categories (reuse
TreeSelectDialog). - Gate Admin (and optionally Woo) in
Nav.svelte. - Replace admin
saveDemowith real endpoints or disable Save. - Re-enable Bulk Formula Builder dialog.
Port TaskStatusIndicator intoDONE.+layout.svelte- Auth footer links + Demo CTA if marketing parity required.
Standard Fields APIDONE (handlers mounted).
8. Out of scope for this audit
Backend/migrator/CI gaps already tracked in status-and-gaps.md. This document only covers what users see and click in the web app versus the legacy Next.js UI.