docs(09): capture phase context
This commit is contained in:
@@ -0,0 +1,151 @@
|
|||||||
|
# Phase 9: Admin Panel Rearchitecture - Context
|
||||||
|
|
||||||
|
**Gathered:** 2026-06-12
|
||||||
|
**Status:** Ready for planning
|
||||||
|
|
||||||
|
<domain>
|
||||||
|
## Phase Boundary
|
||||||
|
|
||||||
|
Phase 9 delivers: (1) `AdminLayout.vue` registered as the `/admin` route component with its own sidebar and `<router-view />`; (2) each admin section extracted as a deep-linkable child route (`/admin`, `/admin/users`, `/admin/quotas`, `/admin/ai`, `/admin/audit`); (3) a new admin overview page at `/admin` showing platform stats + last 10 audit entries; (4) the `requiresAdmin` guard updated to protect all `/admin/*` children; (5) strict admin role separation — admin accounts are redirected to `/admin` on all user routes; (6) Tailwind safelist configured for dynamic `providerColor`/`providerBg`/`providerLabel` class patterns; (7) `AdminView.vue` and the original `AdminXxxTab.vue` components deleted; (8) CODE-09 comment purge pass over all Phase 9 files and retroactively over Phase 8 backend sub-packages.
|
||||||
|
|
||||||
|
</domain>
|
||||||
|
|
||||||
|
<decisions>
|
||||||
|
## Implementation Decisions
|
||||||
|
|
||||||
|
### Admin Overview Page (ADMIN-11)
|
||||||
|
|
||||||
|
- **D-01:** Layout: 3–4 stat cards in a top row (total users, total storage, document status breakdown: processing/ready/failed), followed by a table of the last 10 audit log entries below.
|
||||||
|
- **D-02:** Backend: new `overview.py` sub-module in `backend/api/admin/` alongside the existing `users.py`, `quotas.py`, `ai.py`. Single `GET /api/admin/overview` endpoint returning all four stats in one payload.
|
||||||
|
- **D-03:** Audit entries are inline in the aggregate response — the overview call returns stats + last 10 entries in one HTTP request. No separate `/api/audit` call from the overview component.
|
||||||
|
|
||||||
|
### Admin Sidebar Design (ADMIN-09 — PARTIAL OVERRIDE)
|
||||||
|
|
||||||
|
- **D-04:** SVG icons for each sidebar nav item — consistent with `AppSidebar.vue` pattern.
|
||||||
|
- **D-05:** Visual identity: subtle "Admin" label or badge below the DocuVault logo in the sidebar header. Same indigo brand color. No accent color change.
|
||||||
|
- **D-06:** **No "Back to app" link.** Admin role is administration-only. If an admin user needs to use the document app, they must have a separate normal user account. This overrides the ADMIN-09 requirement text that specified "Back to app link at bottom returns to /".
|
||||||
|
- **D-07:** Nav items (in order): Overview, Users, Quotas, AI Config, Audit Log. No "Back to app".
|
||||||
|
|
||||||
|
### Admin Role Strict Separation (NEW — not in original requirements)
|
||||||
|
|
||||||
|
- **D-08:** After login, if `user.role === 'admin'`, the router redirects to `/admin` instead of `/`.
|
||||||
|
- **D-09:** The `beforeEach` guard detects admin role on non-admin routes and redirects to `/admin`. Admin accounts cannot navigate to user routes (`/`, `/topics`, `/settings`, `/cloud`, etc.).
|
||||||
|
- **D-10:** Two guards in `beforeEach`: (a) non-admin attempting `/admin/*` → redirect to `/`; (b) admin attempting non-admin route → redirect to `/admin`. Both must use `to.matched.some(r => r.meta.requiresAdmin)` for the admin check (Vue Router 4 does not inherit meta to children).
|
||||||
|
|
||||||
|
### Tab Component Extraction (ADMIN-08, ADMIN-10)
|
||||||
|
|
||||||
|
- **D-11:** The four existing tab components (`AdminUsersTab.vue`, `AdminQuotasTab.vue`, `AdminAiConfigTab.vue`, `AuditLogTab.vue`) become standalone view files (`AdminUsersView.vue`, `AdminQuotasView.vue`, `AdminAiView.vue`, `AdminAuditView.vue`) in `frontend/src/views/admin/`. Extraction is structural only: strip top-level padding (owned by `AdminLayout`), rename, wire as router children.
|
||||||
|
- **D-12:** Original `components/admin/AdminXxxTab.vue` files are deleted after extraction — they become dead code. `AdminView.vue` is deleted.
|
||||||
|
- **D-13:** `AuditLogTab.vue` is promoted as-is. No new features, filters, or backend changes for the audit log view in Phase 9.
|
||||||
|
|
||||||
|
### Tailwind Safelist (CODE-06)
|
||||||
|
|
||||||
|
- **D-14:** Add `safelist` in `tailwind.config.js` covering `providerColor`, `providerBg`, `providerLabel` dynamic class patterns from `formatters.js`. Pattern from PITFALLS.md §14:
|
||||||
|
```js
|
||||||
|
safelist: [
|
||||||
|
{ pattern: /bg-(blue|green|purple|orange|gray|indigo|red)-(50|100|500|600)/ },
|
||||||
|
{ pattern: /text-(blue|green|purple|orange|gray|indigo|red)-(500|600|700)/ },
|
||||||
|
]
|
||||||
|
```
|
||||||
|
Researcher verifies which color families `formatters.js` actually uses and adjusts the pattern if needed.
|
||||||
|
|
||||||
|
### CODE-09 Comment Purge
|
||||||
|
|
||||||
|
- **D-15:** One dedicated plan at the end of Phase 9 covers all files touched in Phase 9 plus retroactive purge of Phase 8 backend sub-packages (`api/admin/`, `api/documents/`, `api/auth/`).
|
||||||
|
- **D-16:** Purge criterion: remove comments that describe WHAT code does (generic function docstrings, inline "this does X" comments). Keep comments that explain WHY: constraints, pitfall notes, non-obvious invariants (e.g., `api/admin/__init__.py`'s "sub-routers carry NO prefix" constraint stays; generic "Returns user list" docstrings go).
|
||||||
|
|
||||||
|
### Claude's Discretion
|
||||||
|
|
||||||
|
- Exact SVG icon choices for each admin sidebar nav item (researcher picks appropriate icons from the same icon family used in AppSidebar.vue)
|
||||||
|
- Exact Python queries for the overview aggregate endpoint (researcher reads `db/models.py` and determines the most efficient async query pattern)
|
||||||
|
- Naming of the new view files if `views/admin/` directory structure is adopted (researcher confirms directory convention)
|
||||||
|
|
||||||
|
</decisions>
|
||||||
|
|
||||||
|
<canonical_refs>
|
||||||
|
## Canonical References
|
||||||
|
|
||||||
|
**Downstream agents MUST read these before planning or implementing.**
|
||||||
|
|
||||||
|
### Phase Goals and Requirements
|
||||||
|
- `.planning/ROADMAP.md` §"Phase 9: Admin Panel Rearchitecture" — goal, implementation notes, success criteria, pitfall references
|
||||||
|
- `.planning/REQUIREMENTS.md` §ADMIN-08, ADMIN-09, ADMIN-10, ADMIN-11, ADMIN-12, CODE-06, CODE-09 — formal requirement definitions
|
||||||
|
- **Note:** ADMIN-09 "Back to app link" is overridden by D-06 and D-08 above. CONTEXT.md decisions take precedence.
|
||||||
|
|
||||||
|
### Vue Router 4 Admin Architecture
|
||||||
|
- `.planning/research/PITFALLS.md` §Pitfall 3 — `to.matched.some()` guard fix (security regression risk with flat `to.meta.requiresAdmin`)
|
||||||
|
- `.planning/research/PITFALLS.md` §Pitfall 4 — AdminLayout as route component, not App.vue v-else-if branch (double-render risk)
|
||||||
|
- `.planning/research/PITFALLS.md` §Pitfall 9 — double padding risk when extracting tab content into views with AdminLayout wrapper
|
||||||
|
- `.planning/research/PITFALLS.md` §Pitfall 14 — Tailwind purge of dynamic class names; safelist pattern
|
||||||
|
|
||||||
|
### Frontend Architecture
|
||||||
|
- `.planning/codebase/ARCHITECTURE.md` — component responsibilities, router guard, layout resolution pattern
|
||||||
|
- `frontend/src/App.vue` — current AuthLayout switch pattern (AdminLayout must NOT be added as a third branch here)
|
||||||
|
- `frontend/src/layouts/AuthLayout.vue` — reference pattern for a standalone layout component with `<router-view />`
|
||||||
|
- `frontend/src/router/index.js` — current guard and route structure being rearchitected
|
||||||
|
- `CLAUDE.md` §"Frontend: shared module map" — `formatters.js` is the single source for `providerColor`/`providerBg`/`providerLabel`
|
||||||
|
- `CLAUDE.md` §"Component architecture" — View → Smart → Presentational layering (admin views follow this)
|
||||||
|
|
||||||
|
### Backend Architecture
|
||||||
|
- `backend/api/admin/__init__.py` — existing admin package aggregator pattern; `overview.py` is added alongside existing sub-modules
|
||||||
|
- `backend/api/admin/users.py`, `quotas.py`, `ai.py` — reference for sub-module structure (overview.py follows same pattern)
|
||||||
|
- `backend/api/audit.py` — existing audit log implementation; overview endpoint reuses its query logic for last 10 entries
|
||||||
|
- `backend/db/models.py` — ORM models for users, quotas, documents (needed for aggregate queries)
|
||||||
|
- `CLAUDE.md` §"Key Architectural Rules" — admin endpoints never return document content or credentials_enc
|
||||||
|
|
||||||
|
### Existing Admin Components
|
||||||
|
- `frontend/src/views/AdminView.vue` — being deleted; contains current tab structure
|
||||||
|
- `frontend/src/components/admin/AdminUsersTab.vue` — being promoted to view
|
||||||
|
- `frontend/src/components/admin/AdminQuotasTab.vue` — being promoted to view
|
||||||
|
- `frontend/src/components/admin/AdminAiConfigTab.vue` — being promoted to view
|
||||||
|
- `frontend/src/components/admin/AuditLogTab.vue` — being promoted to view
|
||||||
|
- `frontend/src/utils/formatters.js` — dynamic class names that need safelist coverage
|
||||||
|
|
||||||
|
</canonical_refs>
|
||||||
|
|
||||||
|
<code_context>
|
||||||
|
## Existing Code Insights
|
||||||
|
|
||||||
|
### Reusable Assets
|
||||||
|
- `frontend/src/layouts/AuthLayout.vue` — exact pattern for a standalone layout: a plain `<template>` wrapper with `<router-view />` inside. `AdminLayout.vue` follows this same structure.
|
||||||
|
- `frontend/src/components/layout/AppSidebar.vue` — reference for SVG icon style, nav-link classes (`nav-link`, `nav-link-active`), logo/header structure, and sidebar dimensions (`w-64 bg-white border-r`). Admin sidebar reuses these classes.
|
||||||
|
- `backend/api/admin/__init__.py` — aggregator pattern: import sub-routers, register with parent. `overview.py` adds one more import line here.
|
||||||
|
- `backend/api/audit.py` — already has the paginated audit log query; `overview.py` reuses its query logic (limit=10) rather than duplicating it.
|
||||||
|
|
||||||
|
### Established Patterns
|
||||||
|
- `AdminLayout.vue` is the `/admin` route's `component:` — NOT a branch in `App.vue`. `App.vue` renders whatever the router resolves; it doesn't need to know about AdminLayout.
|
||||||
|
- `beforeEach` guard in `router/index.js` uses `to.matched.some(r => r.meta.requiresAdmin)` — the ONLY correct Vue Router 4 idiom for parent-meta inheritance on child routes. A plain `to.meta.requiresAdmin` check silently breaks for all child routes.
|
||||||
|
- Sub-routers in `api/admin/` carry NO `prefix` on `APIRouter()` — the parent carries `prefix="/api/admin"`. This constraint applies to `overview.py`.
|
||||||
|
- `api/admin/__init__.py` does ONLY router aggregation — no helpers, no models. `overview.py` houses the endpoint logic.
|
||||||
|
|
||||||
|
### Integration Points
|
||||||
|
- `frontend/src/router/index.js` — add `/admin` as a nested route with `AdminLayout` as component; add five children (`''`, `users`, `quotas`, `ai`, `audit`); update `beforeEach` guard with D-09/D-10 admin redirect logic; update login-redirect to send admin role to `/admin`.
|
||||||
|
- `frontend/src/App.vue` — no changes needed (AdminLayout handles its own layout; App.vue only needs the existing AuthLayout branch).
|
||||||
|
- `backend/api/admin/__init__.py` — add `from api.admin.overview import router as overview_router` and register it.
|
||||||
|
- `backend/main.py` — no changes needed (admin router registration unchanged).
|
||||||
|
- `frontend/src/stores/auth.js` — login action may need to check `user.role === 'admin'` and set redirect target to `/admin`.
|
||||||
|
- `frontend/tailwind.config.js` — add `safelist` array covering dynamic color patterns.
|
||||||
|
|
||||||
|
</code_context>
|
||||||
|
|
||||||
|
<specifics>
|
||||||
|
## Specific Ideas
|
||||||
|
|
||||||
|
- Admin overview layout: cards + table, not a full dashboard. Keep it simple — it's an operator utility page.
|
||||||
|
- Admin sidebar: "Admin" label/badge below "DocuVault" in header signals admin context without heavy visual changes.
|
||||||
|
- Strict role separation is a product decision: admin accounts are platform operators, not users. This is philosophically consistent with the privacy-first admin model already established in v0.1 (admin cannot read user documents or credentials).
|
||||||
|
- The overview endpoint returns everything in one payload — makes the AdminOverviewView.vue a single-fetch component with no coordination logic.
|
||||||
|
|
||||||
|
</specifics>
|
||||||
|
|
||||||
|
<deferred>
|
||||||
|
## Deferred Ideas
|
||||||
|
|
||||||
|
None — discussion stayed within phase scope.
|
||||||
|
|
||||||
|
</deferred>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Phase: 9-Admin-Panel-Rearchitecture*
|
||||||
|
*Context gathered: 2026-06-12*
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
# Phase 9: Admin Panel Rearchitecture - Discussion Log
|
||||||
|
|
||||||
|
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
|
||||||
|
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
|
||||||
|
|
||||||
|
**Date:** 2026-06-12
|
||||||
|
**Phase:** 09-admin-panel-rearchitecture
|
||||||
|
**Areas discussed:** Admin overview page, Admin sidebar design, AuditLog + existing tab components, CODE-09 comment purge scope
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Admin Overview Page
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Stat cards + table | Top row: 3-4 stat cards; below: last 10 audit entries as table | ✓ |
|
||||||
|
| Single scrollable page | All data in a simple vertical stack | |
|
||||||
|
| You decide | Researcher/planner picks | |
|
||||||
|
|
||||||
|
**User's choice:** Stat cards + table
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| New overview.py in api/admin/ | Single GET /api/admin/overview endpoint | ✓ |
|
||||||
|
| Separate endpoints per stat | One endpoint per stat | |
|
||||||
|
| Inline in __init__.py | Against Phase 8 aggregator-only rule | |
|
||||||
|
|
||||||
|
**User's choice:** New overview.py in api/admin/
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Inline in aggregate response | Single HTTP request, stats + last 10 entries | ✓ |
|
||||||
|
| Separate /api/audit call | Two requests from overview component | |
|
||||||
|
| You decide | Researcher/planner picks | |
|
||||||
|
|
||||||
|
**User's choice:** Inline in aggregate response
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Admin Sidebar Design
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Yes, SVG icons for each nav item | Consistent with AppSidebar | ✓ |
|
||||||
|
| Text-only nav | Simpler, operator-only context | |
|
||||||
|
| You decide | Researcher/planner picks | |
|
||||||
|
|
||||||
|
**User's choice:** Yes, SVG icons
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Subtle — 'Admin' badge in header | Same indigo brand color, low noise | ✓ |
|
||||||
|
| Accent color change | Different background or accent | |
|
||||||
|
| No special signaling | Identical to user sidebar | |
|
||||||
|
|
||||||
|
**User's choice:** Subtle — 'Admin' badge/label below DocuVault logo
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Muted link with left-arrow icon | Secondary styling | |
|
||||||
|
| Standard nav item | Same as Overview/Users/etc. | |
|
||||||
|
|
||||||
|
**User's choice:** Free text — "I don't want the admin user to have the app at all. I want the admins sole purpose to be administration. If the admin wants to use the app he/she needs a normal user account. So please just create the admin controls for the admin user and no user view for the admin user."
|
||||||
|
|
||||||
|
**Notes:** Major product decision — admin role is administration-only. No "Back to app" link. Admin users are redirected to /admin if they attempt to access user routes. After login, admin role lands on /admin. This overrides ADMIN-09's "Back to app link" requirement.
|
||||||
|
|
||||||
|
Confirmed strict separation: admin accounts cannot access user routes, redirected to /admin.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AuditLog + Existing Tab Components
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Structural extraction only | Strip padding, rename, wire as router children | ✓ |
|
||||||
|
| Light refactor during extraction | Strip padding + clean tab-context artifacts | |
|
||||||
|
|
||||||
|
**User's choice:** Structural extraction only
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Promoted as-is — no new features | Existing filters and CSV export sufficient | ✓ |
|
||||||
|
| Add missing filters | Add any missing features during promotion | |
|
||||||
|
|
||||||
|
**User's choice:** Promoted as-is
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Yes, delete the tab components | Dead code after views exist | ✓ |
|
||||||
|
| Keep as wrappers | Old Tab files re-exported by views | |
|
||||||
|
|
||||||
|
**User's choice:** Yes, delete original AdminXxxTab.vue files
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CODE-09 Comment Purge Scope
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| One dedicated plan at the end | All Phase 9 files + Phase 8 retroactive in one pass | ✓ |
|
||||||
|
| Applied per-file as each plan touches files | Inline + separate retroactive plan | |
|
||||||
|
|
||||||
|
**User's choice:** One dedicated plan at the end
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Remove what-code-does; keep constraint/pitfall comments | Generic docstrings gone; non-obvious constraints stay | ✓ |
|
||||||
|
| Remove everything except TODO-style notes | Aggressive purge | |
|
||||||
|
|
||||||
|
**User's choice:** Remove what-the-code-does comments; keep constraint/pitfall/non-obvious comments
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Claude's Discretion
|
||||||
|
|
||||||
|
- Exact SVG icon choices for admin sidebar nav items
|
||||||
|
- Exact Python query patterns for the overview aggregate endpoint
|
||||||
|
- Whether to use `views/admin/` directory structure for new admin views
|
||||||
|
|
||||||
|
## Deferred Ideas
|
||||||
|
|
||||||
|
None — discussion stayed within phase scope.
|
||||||
Reference in New Issue
Block a user