241 lines
10 KiB
Markdown
241 lines
10 KiB
Markdown
# 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 |