---
phase: 09-admin-panel-rearchitecture
plan: 03
type: execute
wave: 2
depends_on:
  - 09-02
files_modified:
  - frontend/src/views/admin/AdminUsersView.vue
  - frontend/src/views/admin/AdminQuotasView.vue
  - frontend/src/views/admin/AdminAiView.vue
  - frontend/src/views/admin/AdminAuditView.vue
autonomous: true
requirements:
  - ADMIN-08
  - ADMIN-10
user_setup: []

must_haves:
  truths:
    - "Each of the four extracted views (Users, Quotas, AI, Audit) is a self-contained .vue file under frontend/src/views/admin/"
    - "Each extracted view behaves identically to its Phase 8 tab component — same data fetches, same actions, same template DOM"
    - "Top-level template element of each view is a plain <div> with NO p-8, p-6, or max-w- class (AdminLayout owns the content padding)"
  artifacts:
    - path: "frontend/src/views/admin/AdminUsersView.vue"
      provides: "Standalone /admin/users view extracted from AdminUsersTab.vue"
    - path: "frontend/src/views/admin/AdminQuotasView.vue"
      provides: "Standalone /admin/quotas view extracted from AdminQuotasTab.vue"
    - path: "frontend/src/views/admin/AdminAiView.vue"
      provides: "Standalone /admin/ai view extracted from AdminAiConfigTab.vue"
    - path: "frontend/src/views/admin/AdminAuditView.vue"
      provides: "Standalone /admin/audit view extracted from AuditLogTab.vue"
  key_links:
    - from: "frontend/src/views/admin/*View.vue"
      to: "frontend/src/api/admin.js"
      via: "named imports preserved from source tab components"
      pattern: "from '../../api/"
---

<objective>
Promote the four existing admin tab components (`AdminUsersTab.vue`, `AdminQuotasTab.vue`, `AdminAiConfigTab.vue`, `AuditLogTab.vue`) into standalone view files in `frontend/src/views/admin/` (D-11). Extraction is **structural and behavior-preserving** — same template, same script, same data fetches, same emitted actions, with import paths rewritten for the new location and the component renamed in the script setup.

Purpose: D-11 mandates the tab components become views. D-13 mandates AuditLog is promoted as-is (no new features). The Phase 9 architecture (D-09/D-10/D-11) requires each admin section be a standalone deep-linkable view component — `AdminLayout`'s `<router-view />` must render them.

Output: 4 new view files. Original tab components and `AdminView.vue` are deleted in 09-04 (after router rewiring). This plan does NOT delete anything and does NOT touch the router — those land in 09-04 to keep the codebase in a buildable state between waves.
</objective>

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

<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/components/admin/AdminUsersTab.vue
@frontend/src/components/admin/AdminQuotasTab.vue
@frontend/src/components/admin/AdminAiConfigTab.vue
@frontend/src/components/admin/AuditLogTab.vue
@frontend/src/views/AdminView.vue

<interfaces>
From RESEARCH.md §Pattern 4 (codebase audit):
  - `AdminUsersTab.vue` — top element `<div>`, no padding.
  - `AdminQuotasTab.vue` — top element `<div>`, no padding.
  - `AdminAiConfigTab.vue` — top element `<div>`, no padding.
  - `AuditLogTab.vue` — top element `<div>`, no padding.

Tab components currently live at depth `frontend/src/components/admin/` (two levels deep from `src/`). Extracted views live at `frontend/src/views/admin/` (also two levels deep). Therefore relative imports of the form `../../api/...`, `../../stores/...`, `../../utils/...` resolve identically from the new location — **no relative import paths need adjustment**. Any imports that go through `../layout/...` (one level up to `components/`) would break, but these tab components do NOT import any sibling component under `components/`.

Verify before extracting each file: `grep -E "^import" frontend/src/components/admin/<TabFile>.vue` — every import path should already start with `../../` (relative to `components/admin/`). If any import uses a different depth, document the rewrite in the SUMMARY.
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: Extract AdminUsersTab.vue and AdminQuotasTab.vue to views/admin/</name>
  <files>frontend/src/views/admin/AdminUsersView.vue, frontend/src/views/admin/AdminQuotasView.vue</files>
  <read_first>
    - frontend/src/components/admin/AdminUsersTab.vue (entire file — this is the source being promoted)
    - frontend/src/components/admin/AdminQuotasTab.vue (entire file — this is the source being promoted)
    - frontend/src/views/AdminView.vue (current parent — confirm which props/events these tab components rely on so the standalone views can drop the prop-passing layer)
  </read_first>
  <behavior>
    - `AdminUsersView.vue` template + script behave identically to `AdminUsersTab.vue` for the user CRUD flows (create user, deactivate user, set quota, set AI provider, etc.).
    - `AdminQuotasView.vue` template + script behave identically to `AdminQuotasTab.vue` for the quota management flows.
    - Both files compile under Vite with no warnings about unused imports or unresolved paths.
    - No prop is required to mount either view (AdminLayout passes nothing to its children).
  </behavior>
  <action>Copy the entire contents of `frontend/src/components/admin/AdminUsersTab.vue` into a new file `frontend/src/views/admin/AdminUsersView.vue`. Rename the component if the script defines a `name:` field (Options-API style) or sets `defineOptions({ name: 'AdminUsersTab' })` (Composition-API) — change `'AdminUsersTab'` to `'AdminUsersView'`. If neither convention is used, no rename is needed. Verify every import line resolves from the new path (use the rule in `<interfaces>`: `../../<segment>` resolves identically). If `AdminUsersTab.vue` declares props that were used to receive data from `AdminView.vue` and they are no longer relevant (e.g. a `currentUser` prop), remove the `defineProps` block AND audit where those props were referenced — if a prop was only used as a passthrough, replace its template references with direct store reads (`useAuthStore().user`). Do NOT change template DOM, do NOT change `onMounted` fetches, do NOT change emitted events (emitted events are dropped at the view boundary — they no longer have a parent listening; check whether any emit was the sole trigger of a fetch on the parent — if so, replace the emit with a direct re-fetch inside the view). Repeat the same extraction for `AdminQuotasTab.vue` → `frontend/src/views/admin/AdminQuotasView.vue`.</action>
  <verify>
    <automated>cd frontend && [ -f src/views/admin/AdminUsersView.vue ] && [ -f src/views/admin/AdminQuotasView.vue ] && diff <(sed -n '/<template>/,/<\/template>/p' src/components/admin/AdminUsersTab.vue | wc -l) <(sed -n '/<template>/,/<\/template>/p' src/views/admin/AdminUsersView.vue | wc -l) && npm run build 2>&1 | grep -E "AdminUsersView|AdminQuotasView" | grep -i error | wc -l</automated>
  </verify>
  <acceptance_criteria>
    - `frontend/src/views/admin/AdminUsersView.vue` exists.
    - `frontend/src/views/admin/AdminQuotasView.vue` exists.
    - First non-comment template element of each is `<div>` (no `p-8`, `p-6`, `max-w-` class on the root).
    - Line count of each new view is within ±10% of its source tab (no large unintended changes).
    - `cd frontend && npm run build` succeeds with no Vite errors referencing the new view files.
    - `grep -E "defineProps|props:" frontend/src/views/admin/AdminUsersView.vue` either returns no match OR every declared prop is also USED inside the template (no dead prop declarations).
    - Same check for `AdminQuotasView.vue`.
    - All existing API client calls in the source files appear identically in the new files (`grep -E "from '../../api/" frontend/src/views/admin/AdminUsersView.vue` returns the same count as the source).
  </acceptance_criteria>
  <done>AdminUsersView and AdminQuotasView are standalone views that build cleanly; behavior preserved; no top-level padding.</done>
</task>

<task type="auto">
  <name>Task 2: Extract AdminAiConfigTab.vue and AuditLogTab.vue to views/admin/</name>
  <files>frontend/src/views/admin/AdminAiView.vue, frontend/src/views/admin/AdminAuditView.vue</files>
  <read_first>
    - frontend/src/components/admin/AdminAiConfigTab.vue (entire file)
    - frontend/src/components/admin/AuditLogTab.vue (entire file — D-13: promote as-is, no feature changes)
    - frontend/src/views/AdminView.vue (confirm prop-passing pattern)
  </read_first>
  <behavior>
    - `AdminAiView.vue` template + script behave identically to `AdminAiConfigTab.vue` for the AI provider configuration flows (global system AI providers section + per-user AI assignment table, both preserved exactly per Phase 7 plan-05 pitfall 6).
    - `AdminAuditView.vue` template + script behave identically to `AuditLogTab.vue` for the audit log view: filter bar, paginated table, CSV download, daily-export list (all Phase 6.2 features preserved exactly).
    - Both files compile under Vite with no warnings.
    - Dynamic color classes used in `AuditLogTab.vue` (`bg-blue-50 text-blue-600`, `bg-purple-50 text-purple-600`, `bg-amber-50 text-amber-700`, `bg-gray-100 text-gray-600`) continue to be generated via the same `actionTypeClass()` helper in the new view — DO NOT inline these classes or hardcode them.
  </behavior>
  <action>Copy `frontend/src/components/admin/AdminAiConfigTab.vue` to `frontend/src/views/admin/AdminAiView.vue`. Apply the same rules as Task 1: rename component name if explicit, drop dead `defineProps`, replace orphaned `emit` calls with direct re-fetch where the emit was the only refresh trigger. Note: the cross-cutting constraint from Phase 7 (AdminAiConfigTab.vue per-user assignment table is preserved untouched; global system section is ABOVE it) must remain — do not reorder sections. Copy `frontend/src/components/admin/AuditLogTab.vue` to `frontend/src/views/admin/AdminAuditView.vue`. D-13 mandates **as-is** promotion — no new features, no template tweaks. The `actionTypeClass()` function MUST be preserved verbatim (its `bg-amber-50 text-amber-700` etc. drive the safelist requirement closed in 09-04). Verify the import paths still resolve from `views/admin/` (the depth is unchanged from `components/admin/`).</action>
  <verify>
    <automated>cd frontend && [ -f src/views/admin/AdminAiView.vue ] && [ -f src/views/admin/AdminAuditView.vue ] && grep -c "actionTypeClass" src/views/admin/AdminAuditView.vue && npm run build 2>&1 | grep -E "AdminAiView|AdminAuditView" | grep -i error | wc -l</automated>
  </verify>
  <acceptance_criteria>
    - `frontend/src/views/admin/AdminAiView.vue` exists.
    - `frontend/src/views/admin/AdminAuditView.vue` exists.
    - First non-comment template element of each is `<div>` (no top-level padding).
    - `grep -c "actionTypeClass" frontend/src/views/admin/AdminAuditView.vue` returns at least 1 (helper preserved).
    - `grep -c "bg-amber-50" frontend/src/views/admin/AdminAuditView.vue` returns at least 1 (D-13 as-is preservation).
    - `grep -c "bg-purple-50" frontend/src/views/admin/AdminAuditView.vue` returns at least 1.
    - `grep -c "System AI" frontend/src/views/admin/AdminAiView.vue` returns at least 1 (global system section title preserved from Phase 7).
    - `cd frontend && npm run build` succeeds.
    - Line counts within ±10% of source tab components.
  </acceptance_criteria>
  <done>AdminAiView + AdminAuditView are standalone, build cleanly, preserve all Phase 6.2/7 behavior; dynamic color classes still produced through `actionTypeClass()`.</done>
</task>

</tasks>

<threat_model>
## Trust Boundaries

| Boundary | Description |
|----------|-------------|
| (none new) | Behavior-preserving extraction; no new ingress, egress, or trust transitions |

## STRIDE Threat Register

| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-09-03-01 | Tampering | Tab-to-view extraction | mitigate | Verbatim copy of template + script preserves behavior; line-count check ±10% catches accidental edits; `npm run build` catches resolution errors |
| T-09-03-02 | Information Disclosure | Orphaned emit handlers | mitigate | Action step audits every `emit(...)` for orphaned parent listeners and replaces them with direct re-fetches so no admin action silently no-ops (e.g., user creation modal closing without triggering list refresh) |
</threat_model>

<verification>
- `cd frontend && npm run build` → succeeds.
- All four new view files exist under `frontend/src/views/admin/`.
- Each view's first template element is `<div>` with no top-level padding class.
- Original tab components in `frontend/src/components/admin/` are untouched (deletion happens in 09-04).
</verification>

<success_criteria>
- ADMIN-08: Four standalone admin view files exist under `frontend/src/views/admin/`.
- ADMIN-10: Each view is a self-contained component that the router can mount as a child of `/admin` (router wiring lands in 09-04).
- Behavior preserved: every admin CRUD/filter/download interaction continues to work after wiring in 09-04.
</success_criteria>

<output>
Create `.planning/phases/09-admin-panel-rearchitecture/09-03-SUMMARY.md` when done. List the four new files, any dead-prop removals, and any orphaned-emit-to-fetch replacements made during extraction.
</output>
