# 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 `<RoadmapPage />` instead of `<AboutPage admin />`; 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 `<RequireAuth role="admin">`
- 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 `<AboutPage admin />`
- 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