10 KiB
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/roadmapand/api/dev-logroutesclient/api.js— addroadmap()anddevLog()functions
Acceptance criteria
GET /api/roadmapreturns JSON with structured items and countsGET /api/dev-logreturns parsed log entriesGET /api/about-adminstill 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/roadmapon mount - Lazy-fetch
/api/dev-logonly when Activity Log tab is selected - Page-level scroll only (no nested scroll containers)
- Page header: "🗺️ Roadmap" title + version badge (from
/api/roadmapresponse orAPP_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
Tabscomponent 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→ shadcnCollapsible(Collapsible,CollapsibleTrigger,CollapsibleContent)Tabs,TabsList,TabsTrigger,TabsContentfor the tab switcher- Keep existing
Card,Badge,Buttonusage - Use shadcn
Accordionfor mobile lane fallback if needed
Files
- NEW:
client/pages/RoadmapPage.jsx— the entire new page - MODIFY:
client/App.jsx— update/admin/roadmaproute to render<RoadmapPage />instead of<AboutPage admin />; add lazy import - MODIFY:
client/pages/AboutPage.jsx— removeadminprop, removeAdminDashboardimport, revert to public-only about page - DELETE:
client/components/AdminDashboard.jsx— replaced entirely by RoadmapPage - Check if shadcn
CollapsibleandTabsare already installed; if not, add vianpx shadcn@latest add collapsible
Acceptance criteria
/admin/roadmaprenders RoadmapPage with kanban lanes/adminand/aboutno 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
SimpleCollapsibleusage — all shadcnCollapsible - 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 bycsrfTokenProvidermiddleware on every response) - Header: Frontend reads token from
document.cookieand sends it asx-csrf-tokenheader on all state-changing requests (POST, PUT, DELETE, PATCH) - Validation:
csrfMiddlewarecompares 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 tofalse(SPA needs JS to read cookie for double-submit)CSRF_SAME_SITE— defaults tostrictCSRF_SECURE— defaults totrue(HTTPS only)CSRF_COOKIE_NAME— defaults tobt_csrf_token
CSRF-exempt routes (via req.csrfSkip):
POST /api/auth/login— no session exists yet, nothing to hijackPOST /api/auth/logout-all— uses session cookie directly
All other state-changing routes have CSRF enforced, including:
POST /api/auth/change-password— covered bycsrfMiddlewareon/api/authmountPOST /api/profile/change-password— covered bycsrfMiddlewareon/api/profilemount- 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/roadmapand/api/dev-logare 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
redactSensitiveContentfunction fromaboutAdmin.jsis applied) /api/roadmapdoesn't expose implementation details that could aid an attacker (file paths, internal IPs, etc.)/api/dev-logdoesn'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/roadmapis behind<RequireAuth role="admin"> - Fix stale comment in
routes/auth.jsline 120 (remove or correct the "Exempt from CSRF" note)
Files
routes/aboutAdmin.js— review new routesclient/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
- Run
scripts/docker-test.sh— fresh build on port 3036 - Test: admin login → navigate to
/admin/roadmap - Verify: 5 priority lanes render on desktop
- Verify: lanes stack on mobile viewport
- Verify: click item card → expands to show Description/Rationale/Notes
- Verify: Activity Log tab loads data on click (not on page load)
- Verify:
/aboutand/adminno longer show admin dashboard - Verify:
/admin/roadmaprequires admin auth (non-admin gets redirect) - Verify: dark mode + light mode both look correct
- Verify: keyboard navigation works (Tab, Enter/Space to expand)
- Update
client/lib/version.js— bump patch version - Update
STRUCTURE.md— add RoadmapPage, remove AdminDashboard, update AboutPage description - Update Engineering Reference Manual — grep headings, update relevant sections only
Files
client/lib/version.js— version bumppackage.json— version bumpSTRUCTURE.md— add RoadmapPage, remove AdminDashboarddocs/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
- Review all changes
git add -A && git commit -m "feat: redesign roadmap page as kanban-style priority lanes"git push origin devscripts/docker-test.sh— rebuild and redeploy- Update HISTORY.md with the change
- 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.jsxroute to<AboutPage admin /> - Restore
AdminDashboard.jsxfrom git - Roadmap page works again in the old format
- New
/api/roadmapand/api/dev-logendpoints are additive — no data loss