Files
kite/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-02-PLAN.md
T
curo1305andClaude Sonnet 4.6 123ae5b29b chore: archive v0.2 phase directories to milestones/v0.2-phases/
Moves phases 08–11 execution artifacts from .planning/phases/ to
.planning/milestones/v0.2-phases/ to keep .planning/phases/ clean
for the next milestone.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:34:52 +02:00

21 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, user_setup, must_haves
phase plan type wave depends_on files_modified autonomous requirements user_setup must_haves
09-admin-panel-rearchitecture 02 execute 1
frontend/src/layouts/AdminLayout.vue
frontend/src/components/admin/AdminSidebar.vue
frontend/src/views/admin/AdminOverviewView.vue
frontend/src/api/admin.js
true
ADMIN-08
ADMIN-09
ADMIN-11
truths artifacts key_links
AdminLayout.vue renders an aside (AdminSidebar) and a main content area containing a router-view
AdminSidebar shows the DocuVault logo with an 'Admin' subtitle and five nav links: Overview, Users, Quotas, AI Config, Audit Log — no Back to app link
AdminOverviewView fetches GET /api/admin/overview on mount and renders four stat cards + a 10-row audit table
frontend/src/api/admin.js exports getAdminOverview()
path provides contains
frontend/src/layouts/AdminLayout.vue Admin route shell (sidebar + router-view) router-view
path provides contains
frontend/src/components/admin/AdminSidebar.vue Admin-only sidebar nav with 5 router-links, no Back to app to="/admin/audit"
path provides contains
frontend/src/views/admin/AdminOverviewView.vue Stats cards + recent audit table at /admin getAdminOverview
path provides contains
frontend/src/api/admin.js getAdminOverview() API client function export async function getAdminOverview
from to via pattern
frontend/src/layouts/AdminLayout.vue frontend/src/components/admin/AdminSidebar.vue import AdminSidebar import AdminSidebar from '../components/admin/AdminSidebar.vue'
from to via pattern
frontend/src/views/admin/AdminOverviewView.vue frontend/src/api/admin.js getAdminOverview() getAdminOverview(
from to via pattern
frontend/src/api/admin.js /api/admin/overview request() /api/admin/overview
Create the admin route shell — `AdminLayout.vue` (the route component at `/admin`), `AdminSidebar.vue` (the admin-only sidebar with five nav links per D-07 and no Back-to-app per D-06), and `AdminOverviewView.vue` (the new overview view at `/admin` showing stats cards + last-10 audit table per D-01, D-03). Extend the frontend `api/admin.js` module with `getAdminOverview()` so the view can fetch the new backend endpoint.

Purpose: ADMIN-08 requires AdminLayout.vue as the /admin route component with its own sidebar; ADMIN-09 defines the nav set (D-06 overrides the Back-to-app link); ADMIN-11 requires the overview UI. This plan builds the shell + new view; routing is wired in 09-04.

Output: 4 new/modified frontend files. The shell renders correctly when manually mounted; the overview view single-fetches the backend endpoint built in 09-01.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/phases/09-admin-panel-rearchitecture/09-CONTEXT.md @.planning/phases/09-admin-panel-rearchitecture/09-RESEARCH.md @.planning/phases/09-admin-panel-rearchitecture/09-PATTERNS.md @CLAUDE.md @frontend/src/layouts/AuthLayout.vue @frontend/src/components/layout/AppSidebar.vue @frontend/src/components/admin/AuditLogTab.vue @frontend/src/api/admin.js @frontend/src/stores/auth.js @frontend/src/utils/formatters.js From frontend/src/api/client.js (re-export barrel from Phase 8): - `request(path, options)` — the canonical fetch helper with 401-refresh handling. New API helpers MUST call `request()` and not roll their own `fetch`. Import via `./utils.js` in the domain module: `import { request } from './utils.js'`.

From frontend/src/api/admin.js (existing domain module — Phase 8 CODE-04 output):

  • Already exports listAdminUsers, createAdminUser, setAdminUserQuota, getAiConfig, etc. via request(). Add getAdminOverview alongside these.

From frontend/src/stores/auth.js:

  • useAuthStore() exposes user (ref with { email, role, ... }) and logout() action. AdminSidebar imports the store for the user footer + sign-out.

From frontend/src/components/layout/AppSidebar.vue (reference pattern):

  • Container: <aside class="w-64 bg-white border-r border-gray-200 flex flex-col h-full shrink-0">
  • Logo block: <div class="px-6 py-5 border-b border-gray-100"><h1 class="text-lg font-bold text-indigo-600 tracking-tight">DocuVault</h1><p class="text-xs text-gray-400 mt-0.5">Document Manager</p></div>
  • Nav: <nav class="flex-1 px-3 py-4 overflow-y-auto">…</nav>
  • Scoped CSS: .nav-link { @apply flex items-center px-3 py-2 rounded-lg text-gray-600 hover:bg-gray-100 hover:text-gray-900 transition-colors text-sm font-medium; } and .nav-link-active { @apply bg-indigo-50 text-indigo-700; }
  • SVG attrs: class="w-4 h-4 mr-2 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" with stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
  • User footer block exists at the bottom with avatar initial + email + sign-out button.

From frontend/src/layouts/AuthLayout.vue (reference pattern):

  • Simple template-only layout shell hosting <router-view />. AdminLayout follows the same "layout-as-route-component" pattern; App.vue requires NO changes.
Task 1: Add getAdminOverview() to api/admin.js frontend/src/api/admin.js - frontend/src/api/admin.js (current exports — Phase 8 CODE-04 file; find the existing `request` import and the pattern other GET helpers use, e.g. `listAdminUsers`) - frontend/src/api/utils.js (confirm `request` is exported here per Phase 8 CODE-04) - frontend/src/api/client.js (verify `getAdminOverview` re-export is automatic via the barrel) - `getAdminOverview()` returns a Promise resolving to `{ user_count, total_storage_bytes, doc_status, recent_audit }`. - On 401 the underlying `request()` triggers a silent refresh; on non-401 errors the rejected Promise carries the server message. - Function is exported as a named export and re-exported automatically from `client.js` via the existing barrel. Open `frontend/src/api/admin.js`. Add a new named export `getAdminOverview` that calls `request('/api/admin/overview')` and returns its result (no extra wrapping). Follow the exact style of the existing GET helpers in the same file (likely `export async function getAdminOverview() { return request('/api/admin/overview') }`). Do NOT define a duplicate `request` import; reuse whatever import line already exists in `admin.js`. Do NOT touch `client.js` — Phase 8 CODE-04 made it a re-export barrel that picks up every named export from `admin.js` automatically. cd frontend && grep -c "export async function getAdminOverview" src/api/admin.js && grep -c "/api/admin/overview" src/api/admin.js - `grep -c "export async function getAdminOverview" frontend/src/api/admin.js` returns 1. - `grep -c "'/api/admin/overview'" frontend/src/api/admin.js` returns 1. - No new `import` line for `request` is added; existing import is reused. - `cd frontend && node -e "import('./src/api/admin.js').then(m => { if (typeof m.getAdminOverview !== 'function') process.exit(1) })"` exits 0 (function is exported). `getAdminOverview()` exists in `api/admin.js` and resolves via the standard `request()` helper. Task 2: Create AdminLayout.vue + AdminSidebar.vue frontend/src/layouts/AdminLayout.vue, frontend/src/components/admin/AdminSidebar.vue - frontend/src/layouts/AuthLayout.vue (template-only layout pattern; confirms the "no App.vue branch" idiom) - frontend/src/components/layout/AppSidebar.vue (CSS classes, scoped style block, SVG family, user footer, sign-out function — copy these verbatim) - frontend/src/stores/auth.js (signature of `useAuthStore()` and `logout()`) - PATTERNS.md §AdminSidebar.vue (SVG path strings for the five nav icons) - `AdminLayout.vue` template: `
` with `` then `
`. Uses `<script setup>` with `import AdminSidebar from '../components/admin/AdminSidebar.vue'`. - `AdminSidebar.vue` renders an `