This commit is contained in:
Dmytro Tkachenko
2026-08-29 11:59:28 +03:00
commit 28d817ebe9
147 changed files with 17534 additions and 0 deletions
@@ -0,0 +1,43 @@
# 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.