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>
5.5 KiB
status, phase, source, started, updated
| status | phase | source | started | updated | |||||
|---|---|---|---|---|---|---|---|---|---|
| complete | 09-admin-panel-rearchitecture |
|
2026-06-13T00:00:00Z | 2026-06-13T11:45:00Z |
Current Test
[testing complete]
Tests
1. Admin Login Redirect
expected: Log in as an admin account. After successful login, the browser should automatically redirect to /admin (the admin overview page) — not to / (the regular user file manager). If you're already logged in as admin and navigate to /, you should also be redirected to /admin.
result: pass
method: code-verified — LoginView.vue line 212: const defaultRedirect = authStore.user?.role === 'admin' ? '/admin' : '/'. Router guard line: D-09 branch redirects admin navigating to non-admin route → /admin. Both branches present and correct.
2. Admin Sidebar Layout
expected: At /admin, you should see a left sidebar with the DocuVault logo and an "Admin" subtitle in indigo/blue text. Below that, 5 navigation links in order: Overview, Users, Quotas, AI Config, Audit Log. No "Back to app" or "Back to file manager" link anywhere in the sidebar. A sign-out option is at the bottom.
result: pass
method: code-verified — AdminSidebar.vue has <p class="text-xs text-indigo-500 font-semibold mt-0.5">Admin</p>, exactly 5 router-links (/admin, /admin/users, /admin/quotas, /admin/ai, /admin/audit), zero "back to app" references (grep returned 0), sign-out from AppSidebar copy confirmed.
3. Admin Overview — Stat Cards
expected: The /admin overview page shows 4 stat cards in a row: Users, Storage, Processing, Ready. Each card shows a live number fetched from the API. A loading state appears briefly, then the cards populate with actual counts. result: pass method: live-api + code-verified — GET /api/admin/overview returned HTTP 200 with user_count=78, total_storage_bytes (live), doc_status with processing/classified/uploaded breakdown. AdminOverviewView.vue has md:grid-cols-4 grid with all 4 labels (Users, Storage, Processing, Ready). API had real data.
4. Admin Overview — Recent Audit Table
expected: Below the stat cards on /admin, there is a "recent audit" table showing up to 10 rows with columns: When, Event, Actor, Target, IP. If no activity has occurred, a "No recent activity" placeholder is shown instead. result: pass method: live-api + code-verified — overview endpoint returned recent_audit with 10 entries. AdminOverviewView.vue has all 5 column headers (When, Event, Actor, Target, IP) and "No recent activity" placeholder.
5. Users Admin Page
expected: Clicking "Users" in the admin sidebar navigates to /admin/users. The page shows the user management table (same content that was previously in the admin panel's Users tab). The sidebar active state moves to "Users". result: pass method: live-api + code-verified — GET /api/admin/users returned 79 users with full fields. AdminUsersView.vue exists (468 lines, verbatim promotion from AdminUsersTab.vue). Router registers path:'users' → AdminUsersView. Sidebar uses startsWith('/admin/users') for active state.
6. Quotas Admin Page
expected: Clicking "Quotas" in the admin sidebar navigates to /admin/quotas. The quota management table is displayed. The sidebar active state moves to "Quotas". result: pass method: live-api + code-verified — GET /api/admin/users/{id}/quota returned HTTP 200 with user_id, limit_bytes, used_bytes, limit_mb, used_mb. AdminQuotasView.vue exists (174 lines). Router registers path:'quotas' → AdminQuotasView. Sidebar uses startsWith('/admin/quotas').
7. AI Config Admin Page
expected: Clicking "AI Config" in the admin sidebar navigates to /admin/ai. The AI provider configuration section (global and per-user assignment) is displayed. The API key field is intentionally blank (write-only — never pre-filled from the server). The sidebar active state moves to "AI Config".
result: pass
method: live-api + code-verified — GET /api/admin/ai-config returned 10 providers with has_api_key boolean (not the actual key). AdminAiView.vue line: api_key: '', // write-only: never pre-filled from server. Only sends api_key in PATCH body if user typed a new one. api_key_enc absent from all responses.
8. Audit Log Admin Page
expected: Clicking "Audit Log" in the admin sidebar navigates to /admin/audit. A filterable audit log table is shown. Action type badges are color-coded: auth events in blue, folder/share events in purple, admin events in amber/orange, document events in gray. The sidebar active state moves to "Audit Log". result: pass method: live-api + code-verified — GET /api/admin/audit-log returned 50 entries with auth, admin, document event type categories. AdminAuditView.vue actionTypeClass() maps: auth→bg-blue-50 text-blue-600, folder/share→bg-purple-50 text-purple-600, admin→bg-amber-50 text-amber-700, document→bg-gray-100 text-gray-600. Tailwind safelist covers all families.
9. Non-Admin Access Blocked
expected: Log in as a regular (non-admin) user. Manually navigate to /admin in the browser URL bar. You should be immediately redirected back to / (the file manager) and the admin panel should not be visible at all. result: pass method: live-api + code-verified — Regular user token tested against all admin endpoints: /api/admin/overview, /api/admin/users, /api/admin/ai-config, /api/admin/audit-log all returned HTTP 403. Frontend guard: isAdminRoute && !isAdmin → redirect {path:'/'}. Guard uses to.matched.some() covering all /admin/* child routes.
Summary
total: 9 passed: 9 issues: 0 pending: 0 skipped: 0 blocked: 0
Gaps
[none]