Files
descrybe/docs/status-and-gaps.md
greeneclipse 8580c996c3 Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
2026-08-09 22:47:43 +02:00

293 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Descrybe v2 — status, gaps, and next work
Last updated: 2026-08-08
Location: `f:/laragon/www/_MY/descrybe-v2`
Legacy app (still live until cutover): `f:/laragon/www/_MY/descrybe`
This document is the honest gap analysis vs the rewrite plan and the legacy product. Use it to prioritize work. Related docs:
- [features.md](features.md) — phase checklist (kept in sync with this status)
- [schema-map.md](schema-map.md) — MySQL → Postgres ID/field mapping
- [migration-readiness.md](migration-readiness.md) — ETL status + post-import set-password
- [migration-run-log.md](migration-run-log.md) — live MySQL→PG dry-run + load evidence (2026-08-03 **SUCCESS**)
- [go-live-checklist.md](go-live-checklist.md) — staging GO / production NO-GO
- [cutover.md](cutover.md) — production cutover runbook (not yet executed)
- [forgot-password.md](forgot-password.md) — self-serve reset gap + recommended design (deferred)
- [ux-backlog.md](ux-backlog.md) — UX P0/P1; **P0-8 / P0-9 signed cutover waivers** (2026-08-08)
- [production-readiness.md](production-readiness.md) — Wave 8 verdict + remaining blockers
---
## Summary
| Area | Status | Notes |
|------|--------|--------|
| Scaffold / monorepo | **Done** | Go API + SvelteKit + Docker Postgres |
| Auth (no Clerk) | **Mostly done** | Register/login/invite/session/CSRF; **no self-serve forgot-password** — see [forgot-password.md](forgot-password.md) |
| Platform (team, settings, keys, billing) | **Mostly done** | `/readyz`, profile PATCH, invites, SMTP + `cmd/mailhooks`, admin UI, plans/credits; see [ops-runtime.md](ops-runtime.md) |
| Catalog API | **Mostly done** | ListFilter pagination, search/edit, CSV, tree/attr links/formulas; leftovers: drag-drop formula UI, S3 (`UPLOAD_DIR` only), merge-by-GTIN beyond CSV, trees >2000 |
| Feeds / export | **Partial** | URL CSV/XML sync + export streaming; FTP/Excel/schedule/disk leftovers |
| AI processing | **Mostly done** | OpenAI + optional Pinecone; heuristic fallback; DB claim queue; Needs Review MVP (P0-8 [w] — proposal API waived) |
| WooCommerce | **Partial MVP** | REST + worker claim + 15m `EnqueueDueScheduled`; set `CREDENTIALS_ENCRYPTION_KEY` in prod; leftovers: rich maps UI, live E2E |
| Migrator | **Live load succeeded** | Staging PG loaded 2026-08-03 (orphans 16/16); follow-ups: synthetic emails, all `member` roles, `plan_id=6` skipped — see [migration-run-log.md](migration-run-log.md) |
| Public `/api/v1` | **Mounted** | Bearer/`X-API-Key`; CSRF skipped on `/api/v1` only; OpenAPI YAML |
| Admin ops | **Mostly done** | Platform-admin APIs + `/admin` UI + stuck cleanup; polish leftovers |
| Cutover | **Not started** | Data on staging ≠ production ready; **blocked** on emails/roles/SMTP login proof + phase gates in [cutover.md](cutover.md) |
| CI / tests | **Partial** | `go test` unit suite + Makefile; no GitHub Actions |
**Bottom line:** Major workstreams (WS1WS9) are Done or Partial. **Live MySQL→Postgres migration succeeded on staging** (27 companies, 21 users, 15 memberships, 8278 categories, 57630 attributes, 118784 raw products, 7219 processed, 31 feeds, 8 export feeds). Production cutover remains **blocked** until Clerk emails, membership roles, SMTP/set-password login, and [cutover.md](cutover.md) gates are green.
---
## What is done
### Infrastructure
- [x] Sibling monorepo (`apps/api`, `apps/web`, `docs`, `scripts`)
- [x] `docker-compose.yml` — Postgres 16 on host port `5433`
- [x] Goose migrations `001``007` applied on staging PG (platform, catalog, feeds, processing, WooCommerce, feed_sync, …)
- [x] sqlc config + generated queries (handlers often still use raw pgx)
- [x] `cmd/api`, `cmd/worker`, `cmd/migrator`, `cmd/mailhooks` build and run
- [x] Root `Makefile`, `scripts/migrate.sh` / `migrate.ps1`
- [x] SvelteKit 2 + Svelte 5 + Tailwind shell with CSRF-aware `api()` helper
### UI / design
- Visual shell now aligned to legacy design tokens (seasalt / russian-violet / majorelle-blue) across Nav, auth, catalog, and settings; shared `$lib/components/ui` kit + `layout.css`. Not pixel-perfect feature parity with the legacy Next.js UI.
#### Pixel-clone pass (2026-08-03)
Screens cloned into SvelteKit (layout/Nav + page shells against live APIs):
- Dashboard (`/`), Products, Feeds (+ mapping), Export Feeds
- Categories (+ title/description formula builders)
- Attributes, Standard Fields
- Background Tasks (`/processing`; `/tasks` redirects)
- Billing, Settings, WooCommerce, Admin (+ subpages: users, billing/plans, analytics, logs, stuck-products, settings, bootstrap, migrate-orgs, tasks-cleanup)
- Auth: login, register, accept-invite
- `/plans` (customer plans page — admin plans live under `/admin/billing`)
- `/structured-descriptions` (UI cloned; backend APIs still gap)
- `/vector-categories` (UI cloned; backend APIs still gap)
Nav order (legacy-aligned + v2 extras): Products → Feeds → Export Feeds → Categories → Attributes → Standard Fields → Background Tasks → Usage & Billing → Settings → WooCommerce → Admin.
Still missing vs legacy UI (no v2 routes yet): none of the leftover screens above — UI shells exist. Backend gaps remain for structured-descriptions and vector-categories.
### Auth & platform (Phase A — largely working)
- [x] Email/password with argon2id
- [x] Session cookies via `alexedwards/scs` + Postgres `sessions` table
- [x] CSRF double-submit cookie (`descrybe_csrf` + `X-CSRF-Token`)
- [x] Register (creates company + admin membership + credit_balances row)
- [x] Login / logout / `/api/auth/me` / select company / set password
- [ ] Self-serve forgot / reset password (accounts with password already set) — **gap**; design in [forgot-password.md](forgot-password.md). Existing set-password tokens/mail are `must_set_password` / admin-only (P0-10), not reusable safely.
- [x] Accept invite flow (API + Svelte page)
- [x] Team list, create invite, remove member
- [x] Company get/patch + JSON settings
- [x] API keys create/list/revoke (hashed)
- [x] Billing credits overview + `ConsumeCredits` used by processing stub
- [x] `/healthz` + `/readyz` (DB ping; exempt from maintenance gate)
- [x] Profile `PATCH /api/auth/me`; invite list + revoke
- [x] Svelte: login, register, accept-invite, settings (profile/company/team/keys), billing
### Catalog (Phase B — mostly done)
- [x] Categories CRUD + title/description formula PATCH + tree/CSV + attr links
- [x] Attributes CRUD + `ListFilter` SQL pagination/search (shared with products; `ProductFilter` alias)
- [x] Custom variables CRUD
- [x] Products list/search/edit + CSV import (local `UPLOAD_DIR`; merge-by-GTIN in CSV path)
- [x] Migrator paths for categories, attributes, variables, products, feeds (best-effort)
### Feeds / export (Phase C — partial)
- [x] Input feed CRUD + mapping get/put
- [x] Export feed create/list + generate + public XML/CSV streaming
- [x] Real URL sync (CSV/XML) → `raw_products` (FTP/Excel leftover; `SyncStub` aliases `Sync`)
### Processing (Phase D — mostly done)
- [x] Processing jobs create/list/get/cancel + start → `/api/processing/jobs`
- [x] Worker claims pending jobs; OpenAI/heuristic pipeline + optional Pinecone
- [x] Credit consumption hook on processed items
### WooCommerce (Phase E — Partial MVP)
- [x] Config get/put (URL validated; credentials AES-GCM encrypted at rest)
- [x] Real REST connection test (Basic Auth over HTTPS)
- [x] Queued product sync (batch create/update; SKU / product_ids map idempotency)
- [x] Worker claim hook for pending Woo syncs
- [x] Worker 15m cron: billing cycles, stuck jobs, `EnqueueDueScheduled`
- [~] Category/attribute map APIs exist; rich mapping UI / live E2E still open
- **Prod:** set `CREDENTIALS_ENCRYPTION_KEY` (falls back to derived material — prefer explicit key)
- See [ops-runtime.md](ops-runtime.md) for SMTP, mailhooks, encryption, billing
### Docs
- [x] Schema map, cutover runbook, features checklist
---
## What is missing or incomplete
### Critical for any real use (P0)
1. **Feed sync leftovers** (URL+CSV/XML done; not full parity)
- [x] Download URL, parse CSV/XML, mappings -> upsert `raw_products`, chunked progress
- [ ] FTP|FTPS / Excel / uploaded-file paths as in legacy
2. **Export generation****mostly done** (`internal/feeds/export.go`)
- [x] Build XML/CSV from processed products + export template (streamed)
- [x] On-demand generate; public XML/CSV stream real rows
- [ ] Schedule/cron generation; persist files to object storage
3. **AI processing pipeline****mostly done**
- [x] Categorize -> attributes -> enhance; OpenAI + optional Pinecone; credits/retries
- [~] River client deferred (DB claim + NOTIFY); tune prompts / enable Pinecone index
4. **Public `/api/v1` surface****mounted**
- [x] Bearer / `X-API-Key`; products/categories/attributes/feeds/export-feeds/process
- [x] OpenAPI YAML at `/api/v1/openapi.yaml` (Redoc/Scalar UI optional)
- [ ] Live DB integration test for API-key round-trip (**BLOCKER:** needs `DATABASE_URL` harness)
5. **Migrator production readiness****live dry-run + staging load done; cutover follow-ups open**
- [x] Fixture offline path (`-dry-run -fixture ./cmd/migrator/testdata/fixture.json`); id-map + validation artifacts gitignored
- [x] `admin_users` -> `is_platform_admin`; feed mappings; count/orphan report; set-password hooks
- [x] Live MySQL dry-run + staging PG load (2026-08-03) — orphans **16/16 pass**; evidence in [migration-run-log.md](migration-run-log.md)
- [ ] **BLOCKER (cutover):** synthetic `@legacy.local` emails — export Clerk emails and patch before invites
- [ ] **BLOCKER (cutover):** all memberships imported as `role=member` — promote company admins
- [ ] **BLOCKER (cutover):** SMTP + set-password login smoke (this load used `-skip-post-import`)
- [ ] Data: 2 `company_plans` skipped (`plan_id=6`); api_keys / blobs / full company_settings still not migrated
- Ops: local PG on host port **5433**; see [cutover.md](cutover.md) / [go-live-checklist.md](go-live-checklist.md)
### Important product gaps (P1)
6. **Catalog leftovers** (WS6 API largely done)
- [x] Category tree API/CSV + attr links + formula JSON; product search/edit/CSV; ListFilter pagination
- [ ] Drag-drop formula builder UI (legacy editors)
- [ ] S3/object storage (local `UPLOAD_DIR` only today)
- [ ] Merge-by-GTIN beyond CSV import path; category trees >2000 rows
7. **Feeds UX / advanced**
- Mapping UI (schema extraction, XPath, transforms)
- Preview APIs (input + export)
- River (or real queue) instead of poll stub in `jobs/river.go`
- Schema extraction tasks worker
- Feed tags, templates, priorities, vendor IDs as in legacy
8. **Billing / usage completeness**
- [x] Plans / assign / add-credits admin APIs + token packs + billing cycles cron (WS7)
- [ ] Usage metrics / daily stats APIs polish
- [ ] Low-credits UX polish
- Stripe still out of scope unless requested
9. **Platform polish**
- [x] `/readyz` (DB ping)
- [x] Profile name update (`PATCH /api/auth/me`)
- [x] Invite revoke + list pending invites
- [x] SMTP + `cmd/mailhooks` (operator: `SMTP_ENABLED` + host; run mailhooks after migrator)
- Session idle policy documented in [ops-runtime.md](ops-runtime.md)
10. **Admin**
- [x] Platform admin gate on routes (`is_platform_admin`)
- [x] Admin APIs + `/admin` UI (WS7); polish leftovers
- [x] Migrate `admin_users` in migrator
11. **WooCommerce**
- [x] Real REST client + connection test + batched product push (MVP)
- [x] Worker sync claim hook + 15m `EnqueueDueScheduled`
- [ ] Rich category/attribute mapping UI / auto-map
- [ ] Live E2E against a real store
- **Prod:** set `CREDENTIALS_ENCRYPTION_KEY`
### Engineering / ops gaps (P2)
12. **`packages/migrator` layout** — migrator lives in `apps/api/cmd/migrator` (fine); plan mentioned `packages/migrator` (optional move)
13. **Handlers still raw pgx** — sqlc generated but not fully wired
14. **CI** — [~] Makefile test/vet/check-web + go test ./...; no GitHub Actions yet
15. **Automated tests** — [~] unit auth/CSRF/v1/tenant/migrator; live API-key DB round-trip blocked
16. **Object storage** — uploads/exports files on disk/S3
17. **Observability** — structured logs, request IDs (chi has RequestID), metrics
18. **Deploy** — reverse proxy, TLS, env secrets, worker process supervision
19. **WebSocket / live feed updates** — legacy had WS; not in v2
20. **Cron equivalents** — worker 15m: billing cycles, stuck reset, Woo `EnqueueDueScheduled`; feed sync schedule still open
---
## Stubs to replace (code pointers)
| Stub | File | Replace with |
|------|------|----------------|
| Feed sync | `internal/feeds` `Sync` (was SyncStub) | Done for URL+CSV/XML; FTP/Excel leftover |
| Export XML/CSV | `internal/feeds/export.go` public generators | Done: template XML/CSV stream + generate hook; schedule/disk still open |
| Processing | `internal/processing` pipeline (OpenAI/heuristic + optional Pinecone) | Tune prompts / enable Pinecone index; River client optional later |
| Job queue | `internal/jobs/river.go` | Real River client or keep DB claim + document |
| Woo test/sync | `internal/woocommerce` | Partial MVP done; rich maps UI / live E2E leftover |
---
## Recommended work order
Do not start cutover until P0 items for the phases you actually use in production are green.
```text
1. P0 Clerk email patch + set-password invites + SMTP login smoke (staging data already loaded)
2. P0 promote membership roles; fix skipped plan_id=6 company_plans
3. P0 feed sync leftovers (FTP/Excel) if required for cutover tenants
4. P0 export schedule/disk if required; AI prompt/index tuning
5. P0 /api/v1 API-key re-issue runbook for customers
6. P1 catalog formula UI + S3 leftovers
7. P1 billing / Woo polish if required for cutover
8. P2 CI/tests/deploy
9. Execute cutover.md only after gates green
```
### Phase “done when” (practical gates)
- **Phase A done for cutover:** invites email, `/readyz`, admin flag migrated, API keys work with `/api/v1`
- **Phase B done:** CSV import + product edit/search parity for daily ops
- **Phase C done:** sync + export non-stub for all active feed types
- **Phase D done:** processing quality acceptable vs legacy sample set; credits match expectations
- **Phase E done:** Woo sync if used; admin stuck-job tools; cutover checklist executed
---
## Parity snapshot vs legacy Descrybe
| Legacy capability | v2 today |
|-------------------|----------|
| Clerk auth / orgs | Replaced by first-party auth |
| Dashboard products table + filters | List + ListFilter SQL pagination/search |
| Title/description formula builders | API formulas; no drag-drop UI |
| XML/CSV/Excel/FTP ingest | URL CSV/XML sync done; FTP/Excel open |
| Field mapping + schema extract | Mapping JSON store; no extractor |
| Export feeds builder | Streaming generate + public XML/CSV |
| AI pipeline + queue/cron | OpenAI/heuristic + DB claim worker |
| Pinecone auto-categorize | Optional; needs index config |
| WooCommerce sync | Partial MVP (REST + worker + schedule enqueue) |
| Billing plans/cycles/admin | Plans/credits/token packs + 15m cycles |
| Public v1 API + OpenAPI docs | Mounted + OpenAPI YAML |
| Admin analytics / stuck cleanup | APIs + `/admin` UI (polish open) |
| Org export/import | Missing |
| WebSocket live updates | Missing |
---
## How to run what exists
```bash
cd f:/laragon/www/_MY/descrybe-v2
docker compose up -d
cd apps/api && go run ./cmd/api
# optional worker
go run ./cmd/worker
# web
cd ../web && npm install && npm run dev
```
Migrator: live staging load already done — see [migration-run-log.md](migration-run-log.md). For login rehearsal:
```bash
cd apps/api
export DATABASE_URL="postgres://descrybe:descrybe@localhost:5433/descrybe?sslmode=disable"
go run ./cmd/migrator -issue-set-password-invites -postgres "$DATABASE_URL" -maps-dir ../../artifacts
# Dev-only bootstrap one user:
go run ./cmd/migrator -set-password "email@example.com:YourPass123" -postgres "$DATABASE_URL"
```
---
## Tracking
Update this file when a gap closes. Keep [features.md](features.md) checkboxes aligned. Do not mark cutover complete until emails/roles/SMTP login and P0 for in-use phases are verified on staging.