Expand the API v2 plan to account for consumers beyond the browser and
insulate the Android app from version churn before the v2 work begins.
- Inventory the three v1 API consumers (browser, Android app, Discord bot)
and map the cross-component contracts (site<->link, site<->mobile).
- Fix two concrete plan bugs: the public shard SSE stream must stay
anonymous (logged-out browsers and the app's ShardStreamClient send no
auth header), and the useShardFeed fetch-rewrite is admin-stream-only.
- Add "Phase 0 - the mobile facade": a version-agnostic /api/mobile
namespace (a thin BFF delegating to current controllers behind pinned
wire shapes), landed before v2 so the auth merge never touches the app.
- Note link/ is essentially out of scope (no PROTOCOL_VERSION bump), with
the admin-stream allowlist split as the only shared seam.
- Resequence PRs (Phase 0 first) and gate v1 retirement on the pre-facade
app fleet aging out via an app-version floor, not the web client.
- Add M11 to docs/android/PLAN.md: migrate the app to /api/mobile + ship
the app-version floor, cross-referenced with the website plan's Phase 0.
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
Companion doc to API_V2_PLAN.md describing PR 1: stand up router/v2/ empty but
wired next to a frozen /api/v1, with a trivial GET /api/v2/version to make the
mount testable and no behavior change. Includes the file tree, the api.router.js
/ v2.router.js wiring, empty capability-router stubs, and acceptance criteria.
Adds a forward link from the plan's PR-1 line to the skeleton doc.
Co-Authored-By: Claude <noreply@anthropic.com>
Plan for website API v2, sequenced in two phases behind a parallel /api/v2:
- Phase 1: retire httpOnly session cookies; unify web + mobile on the existing
bearer access + rotating/revocable refresh model. Separates removable session
cookies from the SSO/email transaction cookies that must stay. SSE moves to
fetch-based streaming with Authorization: Bearer.
- Phase 1b: tighten the shipped CSP for the now-JS-held token (add form-action
'self', frame-ancestors 'none'); self-host fonts + Trusted Types as follow-ups.
- Phase 2: break the monolithic route wiring (admin.routes.js, ~100 routes) into
one router per business capability so the URL predicts the file.
Co-Authored-By: Claude <noreply@anthropic.com>