docs(website): finalize the API plan — in-place router split, no /api/v2

The API v2 plan is revised down to the work that is actually justified: a CSP
hardening pass and an in-place domain split of the monolithic route wiring.

- Auth merge (httpOnly cookies -> bearer + rotating refresh for every client) is
  removed and re-filed as deferred behind trigger conditions. httpOnly+SameSite
  is the stronger model, session.service.js already unifies cookie and bearer,
  the SSO/PKCE transaction cookies survive any merge, and it dragged the admin
  SSE fetch/ReadableStream rewrite along as a dependency for no user-visible
  payoff. A revival must first spec refresh-token reuse detection and a rollback
  procedure.
- No parallel /api/v2. The URL surface is already grouped by capability, so each
  new router file mounts at the prefix it already owns and every URL stays
  byte-identical. No dual mount, no per-route migration, no v1 retirement; the
  SPA, Discord bot, and Android app are all untouched. API_V2_SKELETON.md is
  marked superseded (kept as the recipe if a versioned API is ever forced).
- The /api/mobile facade and app-version floor are deferred with the revival note
  that it starts as a one-line alias mount, not ~70 hand-written delegates. The
  M11 milestone is dropped from android/PLAN.md.
- Adds PR 0: a generated route manifest, so "every URL is unchanged" is proved by
  a zero-line diff rather than asserted in review. The baseline
  api-route-inventory.json (199 API routes + 2 internal) is committed here and is
  what PR 0's generator must reproduce byte-for-byte.
- Split sequenced as five grouped PRs; CSP fixed to report-only first, then
  enforce (the old plan contradicted itself), with the verified delta being just
  form-action 'self' and frame-ancestors 'none'.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-27 14:31:26 -05:00
parent 81f7d58fbe
commit 5de5e19445
5 changed files with 1127 additions and 330 deletions

View File

@@ -648,10 +648,9 @@ Guidelines:
## 6. Screen ↔ endpoint map
> **Path note (M11):** endpoints below are written with their current `/api/v1`-relative paths. Under
> **M11** the app moves onto the version-agnostic **`/api/mobile`** facade (a pure rename — same
> shapes, same auth); these references update to `/api/mobile/**` when that migration executes. See
> [`../website/API_V2_PLAN.md`](../website/API_V2_PLAN.md) § Phase 0.
> **Path note:** endpoints below are `/api/v1`-relative and stay that way. The website's router
> refactor preserves every URL, and the `/api/mobile` facade that would have renamed them is deferred —
> see [`../website/API_V2_PLAN.md`](../website/API_V2_PLAN.md) § Deferred: the `/api/mobile` facade.
### 6.1 Public content
- **Home/Status** — `GET /public/status`, `GET /public/settings` (branding + maintenance banner).
@@ -883,34 +882,16 @@ push, and Play (M6M8) follow the designed app.
under `/admin/wiki/*`). No backend routes added (they already accept bearer + re-check role);
shard-write actions degrade gracefully when the sidecar is offline. Excluded: hero/CMS block
editor, Discord-bot config, uo-link config, OAuth-provider setup.
12. **M11 — Migrate to the version-agnostic `/api/mobile` facade** (post-v1; decided 2026-07-22).
Prerequisite for the website's API v2 work — see
[`../website/API_V2_PLAN.md`](../website/API_V2_PLAN.md) § Phase 0. Today the app hardcodes ~70
`api/v1/…` endpoints, the SSE stream path, and the SSO URLs, has **no version negotiation and no
force-update**, and calls a mix of mobile-only (`/auth/mobile/*`) and *shared* web routes
(`/auth/me/*`, `/public/*`, `/player/*`, `/admin/*`) — so it is directly coupled to v1 and would
break the day v1 is retired. The website introduces a stable, version-agnostic `/api/mobile`
facade (a thin BFF that delegates to the current controllers behind pinned wire shapes); this
milestone moves the app onto it **once**, after which the app is insulated from all internal
v1→v2→vN churn.
- **App repoint (this milestone's core):** drop the `api/v1/` and `auth/mobile/` prefixes and
re-point everything to `/api/mobile` — the ~70 Retrofit endpoints in `data/api/*.kt`, the
`STREAM_PATH` in `core/net/ShardStreamClient.kt`, and the SSO start/exchange URLs in
`core/auth/sso/SsoAuthManager.kt`. Pure rename; no behavior, auth-model, or token-shape change
(the app is already bearer). The public shard stream stays **anonymous** (no `Authorization`
header) under its `/api/mobile` path.
- **App-version floor (ships in this milestone):** the app sends an app-version header on every
request, and the website gains a server-side min-supported-version gate that can return a
"please update" response. Its first job is to let the shard **sunset the pre-facade app** so the
website can finally delete `/api/v1`; thereafter it is the in-band mechanism for any breaking
`/api/mobile` change (URL-path versioning is deliberately absent on the facade).
- **Rollout & ordering:** the facade + app must be **released and adopted before the website
begins its v2 auth-merge / domain-split work** (website PR 0a = facade + telemetry; PR 0b =
this app repoint + the version floor). The old, un-updated app keeps working against frozen
`/api/v1` until the version floor ages it out — at which point v1 is deletable.
- **Not in scope:** any new screen, any auth-flow change, any UI work. This is a networking-layer
rename plus the version-floor plumbing. Once landed, the endpoint paths throughout §6 read
`/api/mobile/**`; update this doc's references when the migration executes.
### Deferred (not a milestone)
- **`/api/mobile` facade migration + app-version floor** — briefly planned as M11 (2026-07-22), now
**deferred with no app work scheduled**. The website's router refactor is being done in place with
every URL byte-identical and `/api/v1` is not being retired, so the app's ~70 hardcoded `api/v1/…`
endpoints, its SSE path, and its SSO URLs keep working untouched. If the mobile contract ever needs
to diverge from web, the migration comes back — starting from a one-line alias mount on the server,
not a hand-written delegate layer. Reasoning and revival triggers:
[`../website/API_V2_PLAN.md`](../website/API_V2_PLAN.md) § Deferred: the `/api/mobile` facade.
---