10 KiB
10 KiB
DocuVault v0.2 — Requirements
Milestone: v0.2 — UI Overhaul and Optimization Created: 2026-06-07 Total requirements: 40
Quality Mandate (applies to all phases)
Every line of code written or modified in v0.2 must be:
- Minimal: smallest amount of code that correctly solves the problem. No speculative abstractions.
- DRY: if the same logic exists twice, extract it. Duplication is a defect.
- Readable: names things accurately. A reader should understand intent without comments.
- No redundant comments: comments exist only where the why is non-obvious. Never explain what the code does.
- No dead code: unreferenced files, components, or functions are deleted — not commented out.
CODE — Codebase Quality
- CODE-01: Backend
api/admin.py(934L) decomposed intoapi/admin/package withusers.py,quotas.py,ai.py;__init__.pyaggregates sub-routers under the existing/api/adminprefix. No URL changes, no behavior changes, all tests stay green. - CODE-02:
api/documents.py(852L) decomposed into focused sub-modules (upload flow, content proxy, document CRUD, search/listing) withinapi/documents/package. Prefix and behavior unchanged. - CODE-03:
api/auth.py(825L) decomposed into focused sub-modules (login/tokens, TOTP, password management, session management) withinapi/auth/package. Prefix and behavior unchanged. - CODE-04: Frontend
api/client.js(635L) decomposed into domain modules (documents.js,auth.js,admin.js,folders.js,shares.js,cloud.js,topics.js);client.jsbecomes the HTTP transport layer and re-export barrel. Zero changes to any of the 35+ consumer files. - CODE-05: All inline SVG blocks (~66 instances) replaced with
<AppIcon name="..." class="..." />; all icon path data centralized incomponents/ui/AppIcon.vue. No duplicated path strings. - CODE-06: Tailwind
safelistconfigured for all dynamic class name patterns informatters.js(provider colors, backgrounds, badge text). Production builds render topic and provider colors correctly. - CODE-07: All unreferenced files, components, stores, and unused imports deleted. No dead code retained.
- CODE-08: No duplicated Pydantic model definitions or shared validators across router files. Shared schemas extracted to dedicated modules.
- CODE-09: No comment in any file describes what the code does. Comments exist only where intent or constraint would not be obvious to a competent reader.
ADMIN — Admin Panel
- ADMIN-08: Admin panel moved to
/admin/*route subtree withAdminLayout.vueas the route component.AdminLayouthas its own sidebar with admin-specific nav only — no user quota bar, no folder tree, no topic list.AdminView.vueis deleted. - ADMIN-09: Admin sidebar nav links (in order): Overview, Users, Quotas, AI Config, Audit Log. Per Phase 09 decision D-06, admin accounts are administration-only and no "Back to app" link is rendered.
- ADMIN-10: Each admin section is its own deep-linkable URL (
/admin/users,/admin/quotas,/admin/ai,/admin/audit). Browser back button works within the admin section. - ADMIN-11: Admin overview page (
/admin) shows: total registered user count, total platform storage in use, document status breakdown (processing/ready/failed), last 10 audit log entries. Requires new backend aggregate query endpoints. - ADMIN-12:
requiresAdminguard enforced for all/admin/*child routes viato.matched.some(r => r.meta.requiresAdmin). No admin child route is accessible to non-admin users.
UX — UX and Interaction
- UX-01: Every zero-content context shows a contextually distinct empty state using a shared
EmptyState.vuecomponent (headline, subtext, optional CTA). Applied to: root file list, individual folder, search with no results, shared-with-me, topics list, audit log, cloud connections. No plain "No items" text remains. - UX-02: Document list (
StorageBrowser) displays 5-col skeleton grid rows during loading (matching actual grid layout,animate-pulse). "Loading..." text removed. - UX-03: Sidebar folder tree and topics list display skeleton placeholder items during loading. "Loading..." text removed.
- UX-04: Admin user table and audit log table display skeleton table rows during loading.
- UX-05: Pressing
/when no input is focused moves keyboard focus to the search bar. - UX-06: Pressing
Escapecloses any open modal (ShareModal,FolderDeleteModal,DocumentPreviewModal) and clears active search. Handled at the overlay level, not only inside inputs. - UX-07: Pressing
Uwhen no input is focused triggers the file upload picker. - UX-08: Pressing
Nwhen no input is focused starts the new folder inline input in the file manager. - UX-09: Dragging files from the OS anywhere onto the browser window shows a full-screen drop overlay. Releasing uploads the files via the existing upload flow. Only activates when
dataTransfer.typesincludes'Files'. - UX-10: Toast notification system shows transient messages (auto-dismiss 4 seconds, manual dismiss on click) for: upload complete, upload error, document deleted, share revoked, rename successful. Toasts stack vertically and do not block interaction.
- UX-11: Drag-to-move a document onto a folder row in
StorageBrowserworks correctly end-to-end. Drop highlight (ring-2 ring-inset ring-amber-300) renders on valid folder targets. "Move to folder" button remains as non-drag alternative. - UX-12: All views display a breadcrumb reflecting the full current navigation path. Examples:
Folders › Reports › Q1,Cloud › Google Drive › Projects,Admin › Users,Settings › Account,Folders › Reports › document.pdf. Breadcrumb updates on navigation. A single shared breadcrumb component is used across all view types — no per-view implementations. - UX-13: All dropdown menus and modal dialogs render their full content within the viewport. No text or interactive element is clipped by a viewport edge or sibling element. Dropdowns that risk edge-clipping use fixed positioning computed from
getBoundingClientRect()or<Teleport to="body">. - UX-14: The inline "New" button next to the Folders section header in
AppSidebar.vueis removed. Folder creation accessible only from within the file manager view.
VISUAL — Visual Design
- VISUAL-01: Consistent spacing scale across all components using Tailwind utilities only. No arbitrary
px-[13px]values or inlinestylemargins. - VISUAL-02: All form elements (inputs, selects, textareas, checkboxes, radio buttons) have consistent cross-browser baseline styling via
@tailwindcss/formsplugin. - VISUAL-03: All interactive elements (buttons, links, card rows) have consistent hover states,
focus-visible:rings, and active states. - VISUAL-04: Typography scale is consistent: one heading size per level, one body size, one label/caption size. No per-component font-size overrides.
RESP — Responsive Layout
- RESP-01: Sidebar hidden below
lg(1024px). Hamburger button in mobile-only header toggles a slide-in overlay drawer. Overlay closes on nav tap or backdrop tap. - RESP-02: Document list hides Size column below
md(768px) and Modified column belowsm(640px). Icon, name, and actions always visible. - RESP-03: Inline icon action buttons have minimum 36×36px touch target on viewports below
md. - RESP-04: All modal dialogs are scrollable on viewports below 640px. No modal content overflows the screen.
- RESP-05: Admin layout has the same responsive behavior as the user layout: admin sidebar hidden on mobile, hamburger shows admin nav drawer.
PERF — Performance and Stack
- PERF-01: Frontend dependencies bumped/added:
vue@^3.5.0,vite@^8.0.16,@vueuse/core@^14.3.0,@vueuse/integrations@^14.3.0,sortablejs@^1.15.7,@tailwindcss/forms@^0.5.11. Dev:rollup-plugin-visualizer@^7.0.1,@types/sortablejs. - PERF-02: Bundle baseline measured with
rollup-plugin-visualizerbefore optimizations begin. Second measurement taken after all refactoring is complete. Both reports committed to.planning/. - PERF-03: All non-initial-render route components are lazy-loaded. Admin views explicitly lazy-loaded. No synchronous import for routes not on the critical render path.
Future (deferred)
- Virtual scrolling — quota cap (100 MB/user) limits lists to hundreds of items;
v-foris sufficient. Revisit with server-side pagination. - Dark mode — coherent color token system must exist first.
- Folder reordering by drag — requires persistent
positioncolumn in DB. - Multi-select with batch operations — low frequency in a personal vault.
Out of Scope
- Composition API migration — refactor within Options API; Composition API is a separate milestone.
- Component library switch (shadcn-vue, PrimeVue) — stay with Tailwind.
- SSO, billing, group roles — v0.x exclusions unchanged from v0.1.
- Document annotation or in-app editing — not planned.
Traceability
| REQ-ID | Phase | Plan |
|---|---|---|
| PERF-01 | Phase 8 | Complete |
| CODE-01 | Phase 8 | Complete |
| CODE-02 | Phase 8 | Complete |
| CODE-03 | Phase 8 | Complete |
| CODE-04 | Phase 8 | Complete |
| CODE-08 | Phase 8 | Complete |
| ADMIN-08 | Phase 9 | Complete |
| ADMIN-09 | Phase 9 | Complete |
| ADMIN-10 | Phase 9 | Complete |
| ADMIN-11 | Phase 9 | Complete |
| ADMIN-12 | Phase 9 | Complete |
| CODE-06 | Phase 9 | Complete |
| CODE-09 | Phase 9 | Complete |
| UX-01 | Phase 10 | Complete |
| UX-02 | Phase 10 | Complete |
| UX-03 | Phase 10 | Complete |
| UX-04 | Phase 10 | Complete |
| UX-05 | Phase 10 | Complete |
| UX-06 | Phase 10 | Complete |
| UX-07 | Phase 10 | Complete |
| UX-08 | Phase 10 | Complete |
| UX-09 | Phase 10 | Complete |
| UX-10 | Phase 10 | Complete |
| UX-11 | Phase 10 | Complete |
| UX-12 | Phase 10 | Complete |
| UX-13 | Phase 10 | Complete |
| UX-14 | Phase 10 | Complete |
| CODE-05 | Phase 10 | Complete |
| VISUAL-01 | Phase 11 | Complete |
| VISUAL-02 | Phase 11 | Complete |
| VISUAL-03 | Phase 11 | Complete |
| VISUAL-04 | Phase 11 | Complete |
| RESP-01 | Phase 11 | Complete |
| RESP-02 | Phase 11 | Complete |
| RESP-03 | Phase 11 | Complete |
| RESP-04 | Phase 11 | Complete |
| RESP-05 | Phase 11 | Complete |
| CODE-07 | Phase 11 | Complete |
| PERF-02 | Phase 11 | Complete |
| PERF-03 | Phase 11 | Complete |