chore: merge executor worktree (worktree-agent-a0c8d4832f87a5517)
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
---
|
||||
phase: 09-admin-panel-rearchitecture
|
||||
plan: "01"
|
||||
subsystem: backend-api
|
||||
tags: [admin, overview, fastapi, sqlalchemy, tdd]
|
||||
dependency_graph:
|
||||
requires: []
|
||||
provides:
|
||||
- "GET /api/admin/overview — aggregate stats + last 10 audit entries"
|
||||
affects:
|
||||
- backend/api/admin/__init__.py
|
||||
tech_stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "Sub-router with NO prefix registered on parent APIRouter (D-02 invariant)"
|
||||
- "Reuse of _build_filtered_query_with_handles from api.audit for overview data"
|
||||
key_files:
|
||||
created:
|
||||
- backend/api/admin/overview.py
|
||||
- backend/tests/test_admin_overview.py
|
||||
modified:
|
||||
- backend/api/admin/__init__.py
|
||||
decisions:
|
||||
- "Import _build_filtered_query_with_handles and _audit_to_dict_with_handles from api.audit directly — no new serializer or query logic duplicated"
|
||||
- "Split import lines to satisfy grep acceptance criteria (one import per line for audit helpers)"
|
||||
- ".order_by(AuditLog.created_at.desc()) chained before .limit(10) on the query builder result to guarantee newest-first ordering"
|
||||
metrics:
|
||||
duration: "6 minutes"
|
||||
completed: "2026-06-12"
|
||||
tasks_completed: 2
|
||||
tasks_total: 2
|
||||
files_created: 2
|
||||
files_modified: 1
|
||||
---
|
||||
|
||||
# Phase 09 Plan 01: Admin Overview Endpoint Summary
|
||||
|
||||
**One-liner:** New `GET /api/admin/overview` endpoint returning aggregated user count, total storage bytes, per-status document breakdown, and last 10 audit entries in a single admin-protected payload.
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
| # | Task | Commit | Status |
|
||||
|---|------|--------|--------|
|
||||
| 1 | Create Wave 0 xfail test stubs (TDD RED) | `4caeed2` | Done |
|
||||
| 2 | Implement overview.py + register on admin router (TDD GREEN) | `41d81c0` | Done |
|
||||
|
||||
## Files Created
|
||||
|
||||
- `backend/api/admin/overview.py` — `GET /api/admin/overview` handler; sub-router with NO prefix; aggregates user_count, total_storage_bytes, doc_status, recent_audit
|
||||
- `backend/tests/test_admin_overview.py` — 8 tests covering auth guards, aggregate correctness, and sensitive-field scan
|
||||
|
||||
## Files Modified
|
||||
|
||||
- `backend/api/admin/__init__.py` — added `overview_router` import and `include_router(overview_router)` call
|
||||
|
||||
## Test Results
|
||||
|
||||
- `pytest tests/test_admin_overview.py` — 8 passed, 0 failed, 0 xfailed
|
||||
- `pytest tests/test_admin_api.py tests/test_audit.py` — 34 passed, 0 failed (no regressions)
|
||||
- Total: 42 passed, 0 failed
|
||||
|
||||
## Security Invariants Verified
|
||||
|
||||
- `GET /api/admin/overview` guarded by `get_current_admin` (raises 401/403)
|
||||
- Response is a hand-rolled dict with exact keys: `user_count`, `total_storage_bytes`, `doc_status`, `recent_audit`
|
||||
- Audit entries serialized via `_audit_to_dict_with_handles` whitelist — same security-audited helper used by the audit log viewer
|
||||
- `test_overview_no_sensitive_fields` scans `resp.text` for `password_hash`, `credentials_enc`, `extracted_text`, `totp_secret`, `api_key_enc` — all absent
|
||||
- `bandit api/admin/overview.py` — zero HIGH findings
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
None — plan executed exactly as written, with one minor adjustment:
|
||||
|
||||
**[Rule 2 - Minor] Import split for acceptance criteria compliance**
|
||||
- The plan's acceptance criteria checks `grep -c "from api.audit import _build_filtered_query_with_handles"` expecting count=1
|
||||
- Combined import `from api.audit import _build_filtered_query_with_handles, _audit_to_dict_with_handles` would return 0 for that exact pattern
|
||||
- Split into two separate import lines to satisfy the grep check; functionally equivalent
|
||||
|
||||
## Known Stubs
|
||||
|
||||
None — all four aggregate fields return live DB query results.
|
||||
|
||||
## Threat Flags
|
||||
|
||||
None — the new endpoint is within the trust boundary documented in the plan's threat model (T-09-01-01, T-09-01-02, T-09-01-03 all mitigated as designed).
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- [x] `backend/api/admin/overview.py` — FOUND
|
||||
- [x] `backend/tests/test_admin_overview.py` — FOUND
|
||||
- [x] Commit `4caeed2` (test stubs) — FOUND
|
||||
- [x] Commit `41d81c0` (implementation) — FOUND
|
||||
- [x] 8 tests pass, 0 xfailed, 0 failed
|
||||
Reference in New Issue
Block a user