diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 8149cd2..9b74ac8 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -2,7 +2,7 @@ **Milestone:** v0.2 — UI Overhaul and Optimization **Created:** 2026-06-07 -**Total requirements:** 36 +**Total requirements:** 40 --- @@ -106,8 +106,45 @@ Every line of code written or modified in v0.2 must be: ## Traceability -*Filled by roadmapper after phases are defined.* - | REQ-ID | Phase | Plan | |--------|-------|------| -| — | — | — | +| PERF-01 | Phase 8 | Pending | +| CODE-01 | Phase 8 | Pending | +| CODE-02 | Phase 8 | Pending | +| CODE-03 | Phase 8 | Pending | +| CODE-04 | Phase 8 | Pending | +| CODE-08 | Phase 8 | Pending | +| ADMIN-08 | Phase 9 | Pending | +| ADMIN-09 | Phase 9 | Pending | +| ADMIN-10 | Phase 9 | Pending | +| ADMIN-11 | Phase 9 | Pending | +| ADMIN-12 | Phase 9 | Pending | +| CODE-06 | Phase 9 | Pending | +| CODE-09 | Phase 9 | Pending | +| UX-01 | Phase 10 | Pending | +| UX-02 | Phase 10 | Pending | +| UX-03 | Phase 10 | Pending | +| UX-04 | Phase 10 | Pending | +| UX-05 | Phase 10 | Pending | +| UX-06 | Phase 10 | Pending | +| UX-07 | Phase 10 | Pending | +| UX-08 | Phase 10 | Pending | +| UX-09 | Phase 10 | Pending | +| UX-10 | Phase 10 | Pending | +| UX-11 | Phase 10 | Pending | +| UX-12 | Phase 10 | Pending | +| UX-13 | Phase 10 | Pending | +| UX-14 | Phase 10 | Pending | +| CODE-05 | Phase 10 | Pending | +| VISUAL-01 | Phase 11 | Pending | +| VISUAL-02 | Phase 11 | Pending | +| VISUAL-03 | Phase 11 | Pending | +| VISUAL-04 | Phase 11 | Pending | +| RESP-01 | Phase 11 | Pending | +| RESP-02 | Phase 11 | Pending | +| RESP-03 | Phase 11 | Pending | +| RESP-04 | Phase 11 | Pending | +| RESP-05 | Phase 11 | Pending | +| CODE-07 | Phase 11 | Pending | +| PERF-02 | Phase 11 | Pending | +| PERF-03 | Phase 11 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 18e6ef6..a40150a 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -520,6 +520,134 @@ Before any phase is marked complete, all three gates must pass: --- +--- + +# DocuVault — v0.2 Roadmap + +_Milestone: v0.2 — UI Overhaul and Optimization_ +_Started: 2026-06-07_ + +## v0.2 Phases + +- [ ] **Phase 8: Stack Upgrade & Backend Decomposition** — Dependency bumps land; all three backend router monoliths split into focused sub-packages; frontend API client decomposed into domain modules; shared Pydantic schemas extracted +- [ ] **Phase 9: Admin Panel Rearchitecture** — Admin panel moves to `/admin/*` route subtree with its own layout, sidebar, and deep-linkable child routes; Tailwind safelist configured; redundant comments purged +- [ ] **Phase 10: UX & Interaction** — Empty states, loading skeletons, keyboard shortcuts, drag-and-drop upload, toast notifications, breadcrumbs, and icon centralization land across the full UI +- [ ] **Phase 11: Visual Design, Responsive Layout & Cleanup** — Consistent spacing, form styling, hover/focus states, and typography applied; mobile-responsive sidebar and layouts ship; dead code deleted; bundle measured + +## Phase Details + +### Phase 8: Stack Upgrade & Backend Decomposition + +**Goal**: The dependency stack is current, all three backend router monoliths are split into focused sub-packages with zero URL or behavior changes, and the frontend API client is decomposed into domain modules behind a re-export barrel — the entire change is invisible to consumers and tests. +**Depends on**: Phase 7.4 (last v0.1 phase) +**Requirements**: PERF-01, CODE-01, CODE-02, CODE-03, CODE-04, CODE-08 + +**Implementation notes:** +- Sub-routers in `api/admin/`, `api/documents/`, `api/auth/` must have NO prefix on their `APIRouter()` — the parent prefix propagates. Adding a prefix doubles the URL path. (PITFALLS.md §Pitfall 1) +- Shared Pydantic models, constants, and helpers that span sub-modules go in a `shared.py` within each package — never duplicated across sub-routers. (PITFALLS.md §Pitfall 2 — prevents circular imports) +- `client.js` decomposition uses the re-export barrel pattern: `client.js` re-exports everything from domain sub-files; zero changes to the 35+ consumer files. `request()` and `noRefreshPaths` stay in `client.js`; the three blob-download 401-retry duplicates are consolidated into a single `fetchWithRetry()` helper. (PITFALLS.md §Pitfall 5) +- CODE-01, CODE-02, CODE-03 are independent (touch different files) and can be executed in parallel. CODE-04 is also independent of the backend work. + +**Success Criteria** (what must be TRUE): +1. `pytest -v` passes with zero failures immediately after the backend split — every existing API endpoint continues to respond on the same URL path +2. `import * as api from '../api/client.js'` in any existing consumer file resolves all previously-exported names without modification to that consumer file +3. No Pydantic model definition appears more than once across `api/admin/`, `api/documents/`, and `api/auth/` sub-packages — shared types live in a dedicated module +4. `PERF-01` packages are installed and `npm list` confirms `vue@^3.5.x`, `vite@^6.x`, `@vueuse/core@^14.x`, `sortablejs`, `@tailwindcss/forms`, `rollup-plugin-visualizer` are present +**Plans**: TBD + +--- + +### Phase 9: Admin Panel Rearchitecture + +**Goal**: The admin interface is a standalone route subtree (`/admin/*`) with its own layout component and sidebar; each admin section is deep-linkable and browser-back-button works; the `requiresAdmin` navigation guard correctly protects all child routes; and the Tailwind safelist is configured so dynamic color classes render correctly in production builds. +**Depends on**: Phase 8 +**Requirements**: ADMIN-08, ADMIN-09, ADMIN-10, ADMIN-11, ADMIN-12, CODE-06, CODE-09 + +**Implementation notes:** +- `AdminLayout.vue` is registered as the `/admin` route's component; its `` renders child views. `App.vue` does NOT need a third `v-else-if` branch — it renders whatever component the router resolves to. (PITFALLS.md §Pitfall 4) +- The `beforeEach` guard must change from `to.meta.requiresAdmin` to `to.matched.some(r => r.meta.requiresAdmin)`. Vue Router 4 does not inherit `meta` from parent to children automatically. (PITFALLS.md §Pitfall 3) +- `App.vue` layout resolution reads `route.matched.find(r => r.meta.layout)?.meta.layout` — same `matched` walk as the guard. (ARCHITECTURE.md §Integration Point 2) +- `AdminLayout.vue` owns the `p-8 max-w-5xl mx-auto` content wrapper. Extracted tab-component-turned-views (`AdminUsersView.vue` etc.) must strip any top-level padding they inherited from `AdminView.vue` — double padding is the risk. (PITFALLS.md §Pitfall 9) +- Tailwind safelist covers `providerColor`, `providerBg`, `providerLabel` dynamic pattern families from `formatters.js`. (PITFALLS.md §Pitfall 14) +- CODE-09 (comment purge) applies to every file touched in this phase and retroactively to the backend sub-packages created in Phase 8. + +**Success Criteria** (what must be TRUE): +1. Navigating directly to `/admin/users`, `/admin/quotas`, `/admin/ai`, and `/admin/audit` in a fresh browser tab loads the correct admin view with the admin sidebar — not the user app sidebar +2. A logged-in non-admin user who navigates to `/admin/users` is redirected to `/` by the `beforeEach` guard; the redirect happens even when the URL is entered directly +3. The browser back button moves from `/admin/audit` to `/admin/users` (or whichever path was previous) without a full page reload +4. `AdminView.vue` is deleted from the repository; no file imports it +5. A production build (`npm run build`) renders topic badge and provider chip colors correctly — no gray/invisible badges caused by purged dynamic Tailwind classes +**Plans**: TBD +**UI hint**: yes + +--- + +### Phase 10: UX & Interaction + +**Goal**: The application communicates state clearly at every moment — empty contexts have purposeful empty states, loading transitions show structured skeletons, power users can operate keyboard-first, files can be dragged from the OS directly onto the browser, and every action produces an immediate toast confirmation. +**Depends on**: Phase 9 +**Requirements**: UX-01, UX-02, UX-03, UX-04, UX-05, UX-06, UX-07, UX-08, UX-09, UX-10, UX-11, UX-12, UX-13, UX-14, CODE-05 + +**Implementation notes:** +- Global `keydown` listener must guard against active input elements before firing any shortcut. The check pattern is: `['INPUT','TEXTAREA','SELECT'].includes(document.activeElement?.tagName) || document.activeElement?.isContentEditable` → early return. Register in `mounted()`, remove in `beforeUnmount()`. (PITFALLS.md §Pitfall 12) +- Drag-and-drop upload (`UX-09`) detects `dataTransfer.types.includes('Files')` to distinguish file drags from element drags. The full-screen overlay must be attached at the `window`/`document` level, not inside `StorageBrowser`. (UX-09 requirement) +- Drag-to-move (`UX-11`) is already partially implemented in `StorageBrowser.vue`. This phase wires it end-to-end and adds the `ring-2 ring-inset ring-amber-300` drop highlight on valid folder targets. +- `DocumentCard.vue` drag must track `dragging` state to prevent the browser's `dragend`-then-`click` fire from navigating after a drag. Use a dedicated drag handle element where possible. (PITFALLS.md §Pitfall 6) +- All dropdown menus that risk viewport-edge clipping must use fixed positioning from `getBoundingClientRect()` or ``. This is a prerequisite for virtual scrolling adoption if pursued later. (UX-13, PITFALLS.md §Pitfall 7) +- `AppIcon.vue` centralizes all SVG path data. Inline `` blocks are replaced with ``. No duplicated path strings remain. (CODE-05) +- `UX-14`: the inline "New" folder button in `AppSidebar.vue` is removed; folder creation is accessible only from the file manager. +- A single shared `BreadcrumbBar.vue` component serves all view types — no per-view breadcrumb implementations. (UX-12) + +**Success Criteria** (what must be TRUE): +1. Every zero-content context (root file list, folder, search with no results, shared-with-me, topics, audit log, cloud connections) shows a distinct `EmptyState.vue` — no plain "No items" text remains anywhere in the app +2. Pressing `/` focuses the search bar, `Escape` closes any open modal and clears active search, `U` triggers the file upload picker, and `N` starts the new-folder input — none of these fire when a text input has focus +3. Dragging files from the OS onto any part of the browser window (not just a drop zone) shows a full-screen overlay and uploads them on drop +4. Every upload, delete, share, revoke, and rename action produces a toast notification that auto-dismisses after 4 seconds and does not block interaction with the page +5. All views display a breadcrumb rendered by a single shared component; the breadcrumb reflects the full navigation path and updates on every route change +**Plans**: TBD +**UI hint**: yes + +--- + +### Phase 11: Visual Design, Responsive Layout & Cleanup + +**Goal**: Every component uses the Tailwind spacing scale and typography system consistently, form elements have cross-browser baseline styling, interactive elements have consistent hover/focus states, the layout adapts cleanly to mobile viewports with a hamburger-toggled sidebar drawer, dead code is deleted, and bundle size is measured before and after. +**Depends on**: Phase 10 +**Requirements**: VISUAL-01, VISUAL-02, VISUAL-03, VISUAL-04, RESP-01, RESP-02, RESP-03, RESP-04, RESP-05, CODE-07, PERF-02, PERF-03 + +**Implementation notes:** +- Sidebar responsive behavior: below `lg` (1024px) the sidebar is hidden; a hamburger button in a mobile-only header toggles a slide-in overlay drawer with `translate-x-0 / -translate-x-full` transition. Sidebar open/closed state lives in a Pinia store or `App.vue` ref — not in `AppSidebar`'s own `data()`. (PITFALLS.md §Pitfall 8) +- The admin layout needs the same responsive treatment as the user layout — admin sidebar hidden on mobile, hamburger shows the admin nav drawer. (RESP-05) +- All route components not on the critical render path must be lazy-loaded with `() => import(...)`. Admin views are explicitly lazy-loaded. (PERF-03) +- `PERF-02` requires two Vite bundle reports committed to `.planning/`: one measured before optimizations (taken at start of this phase) and one after all work is complete (taken at end). +- `CODE-07` dead-code deletion sweeps all unreferenced files, components, stores, and unused imports. Deletion happens after all other changes in this phase are complete — delete only what is confirmed unreferenced after all additions. +- `VISUAL-02` requires the `@tailwindcss/forms` plugin (already listed in PERF-01) to be configured in `tailwind.config.js`. +- `RESP-02`: `StorageBrowser`'s grid hides the Size column below `md` and Modified below `sm`. Icon, name, and actions are always visible. +- `RESP-03`: inline icon action buttons have minimum 36×36px touch target below `md`. +- `RESP-04`: all modal dialogs are scrollable on viewports below 640px. + +**Success Criteria** (what must be TRUE): +1. At 375px viewport width, the app is fully usable: the sidebar is hidden, the hamburger opens an overlay drawer, the document list shows only icon/name/actions columns, and all touch targets are at least 36×36px +2. All form inputs, selects, textareas, checkboxes, and radio buttons have consistent cross-browser styling with no browser-default rendering differences visible between Chrome, Firefox, and Safari +3. Every button, card row, and interactive link has a visible `focus-visible:` ring and a distinct hover state; no interactive element is style-identical in focused and unfocused states +4. No arbitrary pixel value (`px-[13px]`, `style="margin: 5px"`, etc.) appears in any template; all spacing is from the Tailwind scale +5. Two bundle analysis reports are committed to `.planning/` — one baseline and one post-optimization; all non-initial-render routes are lazy-loaded and appear as separate chunks in the report +**Plans**: TBD +**UI hint**: yes + +--- + +## v0.2 Progress Table + +| Phase | Plans Complete | Status | Completed | +|-------|----------------|--------|-----------| +| 8. Stack Upgrade & Backend Decomposition | 0/TBD | Not started | — | +| 9. Admin Panel Rearchitecture | 0/TBD | Not started | — | +| 10. UX & Interaction | 0/TBD | Not started | — | +| 11. Visual Design, Responsive Layout & Cleanup | 0/TBD | Not started | — | + +--- + ## Progress Table | Phase | Plans Complete | Status | Completed | diff --git a/.planning/STATE.md b/.planning/STATE.md index 73384a6..4765029 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -6,7 +6,7 @@ current_phase: none status: planning last_updated: "2026-06-07T00:00:00.000Z" progress: - total_phases: 0 + total_phases: 4 completed_phases: 0 total_plans: 0 completed_plans: 0 @@ -16,29 +16,34 @@ progress: # Project State **Project:** DocuVault -**Status:** Milestone v0.2 started — defining requirements -**Current Phase:** None (requirements phase) +**Status:** Milestone v0.2 roadmap defined — ready to plan Phase 8 +**Current Phase:** None (roadmap approved, planning begins) **Last Updated:** 2026-06-07 ## Current Position -Phase: Not started (defining requirements) +Phase: Not started Plan: — -Status: Defining requirements -Last activity: 2026-06-07 — Milestone v0.2 started +Status: Roadmap created — 4 phases defined, 40 requirements mapped +Last activity: 2026-06-07 — v0.2 roadmap created ## Phase Status -*Phases will be added after roadmap is approved.* +| Phase | Requirements | Status | +|-------|-------------|--------| +| 8. Stack Upgrade & Backend Decomposition | PERF-01, CODE-01, CODE-02, CODE-03, CODE-04, CODE-08 | Not started | +| 9. Admin Panel Rearchitecture | ADMIN-08..12, CODE-06, CODE-09 | Not started | +| 10. UX & Interaction | UX-01..14, CODE-05 | Not started | +| 11. Visual Design, Responsive Layout & Cleanup | VISUAL-01..04, RESP-01..05, CODE-07, PERF-02, PERF-03 | Not started | ## Performance Metrics | Metric | Value | |---|---| -| Phases complete | — | -| Requirements mapped | — | -| Plans written | — | -| Plans complete | — | +| Phases complete | 0 / 4 | +| Requirements mapped | 40 / 40 | +| Plans written | 0 | +| Plans complete | 0 | ## Accumulated Context @@ -51,11 +56,16 @@ Last activity: 2026-06-07 — Milestone v0.2 started | Options API preserved in v0.2 refactor | Composition API migration is scope-creep; refactor within Options API | | Admin panel as standalone route subtree | AdminView as tabs-on-user-layout is architecturally wrong; v0.2 fixes this | | No rewrites — refactor only | Preserve existing tests and behavior; change internal structure, not contracts | +| client.js barrel re-export pattern | Zero consumer churn; all 35+ import sites stay unchanged; mocks still work | +| Sub-routers carry NO prefix | Parent APIRouter prefix propagates — sub-routers with prefix cause double-segment URLs | +| AdminLayout as route component, not App.vue branch | Router resolves AdminLayout as the /admin component; its router-view renders children | +| to.matched.some() for requiresAdmin guard | Vue Router 4 does not inherit meta to children; direct to.meta check is a security regression | ### Roadmap Evolution - v0.1 completed: all 7 foundation phases + security hardening (2026-06-06) - v0.2 started: UI overhaul, code quality, admin panel rearchitecture (2026-06-07) +- v0.2 roadmap defined: 4 phases, 40 requirements, phases 8–11 (2026-06-07) ### Open Questions @@ -71,7 +81,7 @@ _Updated at each phase transition._ | Field | Value | |---|---| -| Last session | 2026-06-07 — Milestone v0.2 started; requirements definition in progress | -| Next action | Approve requirements, then roadmap | +| Last session | 2026-06-07 — v0.2 roadmap created; 4 phases defined | +| Next action | /gsd:plan-phase 8 | | Pending decisions | None | -| Resume file | None | +| Resume file | .planning/ROADMAP.md — Phase 8 detail section |