# Roadmap Page Redesign — Execution Plan **Created:** 2026-05-11 **Scope:** Replace AdminDashboard with a standalone RoadmapPage using kanban-style priority lanes **Reference:** `docs/ROADMAP_UI_AUDIT.md` --- ## Task 1 — Neo: Backend API Split & Parsing Fix **Agent:** Neo **Priority:** Must complete before Task 2 **Estimated time:** 2-3 hours ### What Split `/api/about-admin` into two endpoints so the dev log (54KB) isn't shipped on page load, and add structured FUTURE.md parsing on the backend. ### Changes **1. New endpoint: `GET /api/roadmap`** - Reads `FUTURE.md` - Returns parsed JSON array of roadmap items (not raw markdown) - Each item: `{ id, priority, priorityLabel, title, description, rationale, implementationNotes, effort, added, addedBy, status }` - Parse `**Description:**`, `**Rationale:**`, `**Implementation Notes:**` into separate fields - Extract effort estimate from Implementation Notes (regex: `Estimated effort: X-Y hours` → `effort: "X-Yh"`) - Filter out strikethrough/completed items server-side - Group counts by priority tier in response: `{ items: [...], counts: { critical: 1, high: 3, medium: 4, low: 3, niceToHave: 1 } }` **2. New endpoint: `GET /api/dev-log`** - Reads `DEVELOPMENT_LOG.md` - Returns parsed JSON array of log entries (not raw markdown) - Each entry: `{ version, date, status, agents: [{name, status, time, notes}], filesModified: [...] }` - Called lazily — frontend only fetches when Activity Log tab is selected **3. Keep `/api/about-admin` unchanged** - Still returns `version`, `future` (raw), `developmentLog` (raw) for backward compatibility - AdminDashboard continues to work until we swap it out ### Files - `routes/aboutAdmin.js` — add `/api/roadmap` and `/api/dev-log` routes - `client/api.js` — add `roadmap()` and `devLog()` functions ### Acceptance criteria - `GET /api/roadmap` returns JSON with structured items and counts - `GET /api/dev-log` returns parsed log entries - `GET /api/about-admin` still works unchanged - Completed/strikethrough items are excluded from `/api/roadmap` --- ## Task 2 — Scarlett: RoadmapPage UI (Kanban Lanes + Tabs) **Agent:** Scarlett **Priority:** Depends on Task 1 **Estimated time:** 6-8 hours **Stack mandate:** Vite + React (NOT Next.js). All UI components must use shadcn/ui primitives. Styling via Tailwind CSS only. ### What Build a standalone `RoadmapPage.jsx` with kanban-style priority lanes and a tab for the Activity Log. Replace the current AdminDashboard component. ### Changes **1. New file: `client/pages/RoadmapPage.jsx`** - Fetch data from `/api/roadmap` on mount - Lazy-fetch `/api/dev-log` only when Activity Log tab is selected - Page-level scroll only (no nested scroll containers) - Page header: "🗺️ Roadmap" title + version badge (from `/api/roadmap` response or `APP_VERSION`) **2. Kanban lane layout (Roadmap tab)** - Desktop (`lg+`): 5-column grid — one lane per priority (CRITICAL, HIGH, MEDIUM, LOW, NICE TO HAVE) - Tablet (`sm–lg`): 2-column grid (CRITICAL+HIGH | MEDIUM+LOW+NICE TO HAVE) - Mobile (`< sm`): single column, lanes stack vertically as collapsible sections - Each lane header: priority emoji + label + item count badge (e.g., "🔴 Critical (1)") - Lane header has colored top border from PRIORITY_COLORS map **3. Roadmap item cards** - Compact card: priority badge, title (bold, 2-3 line clamp), date added, effort estimate - Click to expand via shadcn `Collapsible` (Radix-based, accessible, `aria-expanded`) - Expanded view shows three labeled sections: Description, Rationale, Implementation Notes — properly styled, not raw markdown - "Expand All / Collapse All" toggle button above the lane grid **4. Activity Log tab** - shadcn `Tabs` component with two tabs: "Roadmap" | "Activity Log" - Activity Log shows parsed dev log entries in vertical timeline format - Each entry: version, date, agent badges with status icons, files modified count - Expandable details (click to see full entry content) - Lazy-loaded — only fetch when tab is selected **5. Replace shadcn/ui components (not custom)** - `SimpleCollapsible` → shadcn `Collapsible` (`Collapsible`, `CollapsibleTrigger`, `CollapsibleContent`) - `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` for the tab switcher - Keep existing `Card`, `Badge`, `Button` usage - Use shadcn `Accordion` for mobile lane fallback if needed ### Files - **NEW:** `client/pages/RoadmapPage.jsx` — the entire new page - **MODIFY:** `client/App.jsx` — update `/admin/roadmap` route to render `` instead of ``; add lazy import - **MODIFY:** `client/pages/AboutPage.jsx` — remove `admin` prop, remove `AdminDashboard` import, revert to public-only about page - **DELETE:** `client/components/AdminDashboard.jsx` — replaced entirely by RoadmapPage - Check if shadcn `Collapsible` and `Tabs` are already installed; if not, add via `npx shadcn@latest add collapsible` ### Acceptance criteria - `/admin/roadmap` renders RoadmapPage with kanban lanes - `/admin` and `/about` no longer show the admin dashboard - Desktop: 5 priority lanes side by side - Mobile: lanes stack vertically - Each item card expands to show Description/Rationale/Notes as separate styled sections - Activity Log tab lazy-loads dev log data - No `SimpleCollapsible` usage — all shadcn `Collapsible` - All interactive elements keyboard-focusable with `aria-expanded` - Dark mode and light mode both render correctly --- ## Task 3 — Private_Hudson: Security Review **Agent:** Private_Hudson **Priority:** After Task 2 **Estimated time:** 1-2 hours ### What Review the new endpoints and page for security issues. ### Current CSRF Security Context Bill Tracker uses a **double-submit cookie pattern** for CSRF protection: - **Cookie:** `bt_csrf_token` (set by `csrfTokenProvider` middleware on every response) - **Header:** Frontend reads token from `document.cookie` and sends it as `x-csrf-token` header on all state-changing requests (POST, PUT, DELETE, PATCH) - **Validation:** `csrfMiddleware` compares cookie value to header/query/body value — must match exactly - **Token generation:** `crypto.randomBytes(32).toString('hex')` (256-bit) **Configuration (env vars):** - `CSRF_HTTP_ONLY` — defaults to `false` (SPA needs JS to read cookie for double-submit) - `CSRF_SAME_SITE` — defaults to `strict` - `CSRF_SECURE` — defaults to `true` (HTTPS only) - `CSRF_COOKIE_NAME` — defaults to `bt_csrf_token` **CSRF-exempt routes (via `req.csrfSkip`):** - `POST /api/auth/login` — no session exists yet, nothing to hijack - `POST /api/auth/logout-all` — uses session cookie directly **All other state-changing routes have CSRF enforced**, including: - `POST /api/auth/change-password` — covered by `csrfMiddleware` on `/api/auth` mount - `POST /api/profile/change-password` — covered by `csrfMiddleware` on `/api/profile` mount - All `/api/bills`, `/api/payments`, `/api/categories`, `/api/tracker`, `/api/analytics`, etc. ⚠️ **Known stale comment:** `routes/auth.js` line 120 has a comment saying "Exempt from CSRF" on the change-password route, but there is NO `req.csrfSkip` set — the route IS protected. The comment is wrong and should be removed. ### Checks for New Endpoints - `/api/roadmap` and `/api/dev-log` are GET routes — CSRF middleware only validates POST/PUT/DELETE/PATCH, so they're safe by default. But confirm they still require admin auth. - No FUTURE.md internal file paths leak through the API (the `redactSensitiveContent` function from `aboutAdmin.js` is applied) - `/api/roadmap` doesn't expose implementation details that could aid an attacker (file paths, internal IPs, etc.) - `/api/dev-log` doesn't expose agent names/tokens that shouldn't be visible - XSS check: all parsed content rendered through React's JSX (auto-escaped) or sanitized - Route: confirm `/admin/roadmap` is behind `` - Fix stale comment in `routes/auth.js` line 120 (remove or correct the "Exempt from CSRF" note) ### Files - `routes/aboutAdmin.js` — review new routes - `client/pages/RoadmapPage.jsx` — review rendering --- ## Task 4 — Bishop: Verification + Docs Update **Agent:** Bishop **Priority:** After Tasks 2 and 3 **Estimated time:** 2-3 hours ### What Build, test, verify the redesign works, update docs. ### Steps 1. Run `scripts/docker-test.sh` — fresh build on port 3036 2. Test: admin login → navigate to `/admin/roadmap` 3. Verify: 5 priority lanes render on desktop 4. Verify: lanes stack on mobile viewport 5. Verify: click item card → expands to show Description/Rationale/Notes 6. Verify: Activity Log tab loads data on click (not on page load) 7. Verify: `/about` and `/admin` no longer show admin dashboard 8. Verify: `/admin/roadmap` requires admin auth (non-admin gets redirect) 9. Verify: dark mode + light mode both look correct 10. Verify: keyboard navigation works (Tab, Enter/Space to expand) 11. Update `client/lib/version.js` — bump patch version 12. Update `STRUCTURE.md` — add RoadmapPage, remove AdminDashboard, update AboutPage description 13. Update Engineering Reference Manual — grep headings, update relevant sections only ### Files - `client/lib/version.js` — version bump - `package.json` — version bump - `STRUCTURE.md` — add RoadmapPage, remove AdminDashboard - `docs/Engineering_Reference_Manual.md` — targeted section updates --- ## Task 5 — Ripley: Final Commit & Push **Agent:** Ripley **Priority:** After Task 4 ### What Final review, commit, push, deploy. ### Steps 1. Review all changes 2. `git add -A && git commit -m "feat: redesign roadmap page as kanban-style priority lanes"` 3. `git push origin dev` 4. `scripts/docker-test.sh` — rebuild and redeploy 5. Update HISTORY.md with the change 6. Update FUTURE.md — add "Roadmap page redesign" if not already there, or reference this work --- ## Dependency Graph ``` Task 1 (Neo: API split) └──→ Task 2 (Scarlett: UI) ──→ Task 3 (Hudson: Security) ──→ Task 4 (Bishop: Verify) ──→ Task 5 (Ripley: Commit) ``` Tasks 1 and 2 are sequential. Tasks 3 and 4 are sequential after 2. Task 5 is final. ## Estimated Total Time | Task | Agent | Time | |------|-------|------| | 1 | Neo | 2-3h | | 2 | Scarlett | 6-8h | | 3 | Hudson | 1-2h | | 4 | Bishop | 2-3h | | 5 | Ripley | 30m | | **Total** | | **12-17h** | ## Rollback Plan If the redesign has issues in production: - Revert `App.jsx` route to `` - Restore `AdminDashboard.jsx` from git - Roadmap page works again in the old format - New `/api/roadmap` and `/api/dev-log` endpoints are additive — no data loss