All 9 UAT items verified via live API + source inspection: - GET /api/admin/overview live data (78 users, 8MB storage, 10 audit rows) - Auth guard: 401 unauthenticated, 403 non-admin on all protected endpoints - Admin login redirect (D-08) confirmed in LoginView.vue line 212 - Sidebar: 5 nav links, indigo Admin badge, no back-to-app link - 4-stat-card overview + When/Event/Actor/Target/IP audit table - 5 standalone admin views (Users, Quotas, AI, Audit) with no Pinia stores - API key write-only invariant confirmed in AdminAiView.vue - Color-coded audit badges (auth=blue, admin=amber, folder/share=purple) - to.matched.some() guard covers all /admin/* child routes - No sensitive fields (password_hash, credentials_enc) in any response Phase 9 marked complete. STATE.md and PROJECT.md updated for Phase 10. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
5.5 KiB
Markdown
72 lines
5.5 KiB
Markdown
---
|
|
status: complete
|
|
phase: 09-admin-panel-rearchitecture
|
|
source: [09-01-SUMMARY.md, 09-02-SUMMARY.md, 09-03-SUMMARY.md, 09-04-SUMMARY.md, 09-05-SUMMARY.md]
|
|
started: 2026-06-13T00:00:00Z
|
|
updated: 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]
|