44 lines
2.5 KiB
Markdown
44 lines
2.5 KiB
Markdown
# engineer — RBAC + Token page + Filtered Excel export + full-width + donut fix
|
|
|
|
**Date:** 2026-08-27 · From: [principal-20260827-175448](principal-20260827-175448.md)
|
|
|
|
## What changed
|
|
|
|
### 1. Roles / RBAC
|
|
- `server/db.ts`: `app_users.role TEXT NOT NULL DEFAULT 'viewer'` (additive `ALTER … ADD COLUMN IF NOT EXISTS`).
|
|
`seedUser` forces the bootstrap `AUTH_USER` to `admin` (and repairs pre-role rows). Added
|
|
`Role`/`ROLES`/`isRole`, `listUsers`, `createUser` (23505 → 'exists'), `deleteUser`.
|
|
- `server/auth.ts`: session `user = {username, role}`; `verifyLogin` returns the role;
|
|
`requireRole(min)` — 401 unauth, **403** under-privileged.
|
|
- `index.ts` route gates:
|
|
- viewer: `/api/tickets`, `/api/tickets/:number`, `/api/stats`, `/api/config`
|
|
- pm: `/api/analytics/*`, `/api/insights`
|
|
- lead: `GET/POST /api/users`, `DELETE /api/users/:username`
|
|
- admin: `GET/POST /api/tokens`, `POST /api/tokens/:id/revoke`
|
|
- **Only admin may create an admin** (server 403 + client dropdown limits leadership to ≤lead).
|
|
- Client: `roleAtLeast`/`ROLE_LABELS`; App route guards (reports→pm, /admin→lead);
|
|
Sidebar shows Analytics only for pm+, Admin only for lead+; TopBar shows role.
|
|
|
|
### 2. API token page — `pages/Admin` (Tokens tab, admin only)
|
|
List (label/id/last-used/expires/revoked) + create (raw `fg_…` shown once, copy) + revoke.
|
|
Replaces the `x-admin-key` HTTP gate with the admin session role. `mint-token` CLI unchanged.
|
|
|
|
### 3. Filtered Excel export
|
|
`utils/excel.utils.ts` (`write-excel-file` dep, as in Husky) → exports the board's **currently
|
|
filtered** rows. Button in the board header. 17 columns incl. lifetime, days-in-state, cost, PO, link.
|
|
|
|
### 4. Also
|
|
- Overall verifier REDO fixed: donut now fed `byRequesterShare` (full 966-ticket distribution),
|
|
not the top-20 nested `byRequester` → center total 966, correct %.
|
|
- All analytics pages `max-width: none` (charts span the full container width).
|
|
|
|
## Verification (live, role forge_app DB)
|
|
- server tsc / client tsc clean; client vite build OK; `npm test` 9 pass.
|
|
- Gating matrix reproduced end-to-end: viewer → tickets/config 200, analytics/insights/users/tokens **403**;
|
|
pm → analytics/insights 200, users/tokens **403**; admin → all 200. viewer POST /api/users **403**.
|
|
- Bootstrap `admin` row correctly migrated to role `admin` (not the 'viewer' default).
|
|
|
|
## Next
|
|
security — audit the authz (public domain): privilege escalation, self-delete/last-admin, token exposure.
|
|
verifier — gate the full change.
|