docs: /public version+brand; mark PLAN §8 items 4 & 6 done #11

Merged
whitlocktech merged 1 commits from docs/public-version-and-brand into main 2026-07-19 17:22:08 +00:00
2 changed files with 22 additions and 10 deletions

View File

@@ -6,10 +6,11 @@ API changes it depends on can be landed in `website/` and `docs/` first. When we
authoritative API reference is the committed OpenAPI spec at authoritative API reference is the committed OpenAPI spec at
`website/server/swagger/swagger-output.json` (regenerated via `npm run swagger`). `website/server/swagger/swagger-output.json` (regenerated via `npm run swagger`).
**Prerequisite progress (§8):** **Password reset** (§8 item 2 — the "build FIRST" prerequisite; **Prerequisite progress (§8):** all v1 prerequisites are **done** (2026-07-19) — ✅ password reset
website#75 + docs#8) and ✅ **role-agnostic `/auth/me/*` self surface** (§8 item 1) are **done** (item 2; website#75 + docs#8), ✅ role-agnostic `/auth/me/*` self surface (item 1; website#76 + docs#10),
(2026-07-19). Still open: version/health for first-run (item 4) and branding confirmation (item 6); version/health surfacing (item 4) and branding for mobile (item 6). **Push notifications (item 3)
push (item 3) is post-v1. is the only remaining §8 work and is post-v1 (M7).** The app's functional Kotlin pass (M0M4) is now
unblocked.
The workspace already holds `website/`, `link/`, `servuo-plugins/`, and `docs/`. `android-app/` is The workspace already holds `website/`, `link/`, `servuo-plugins/`, and `docs/`. `android-app/` is
the fifth repo. It is **purely an API client of the website backend** — it never talks to the the fifth repo. It is **purely an API client of the website backend** — it never talks to the
@@ -317,13 +318,23 @@ maintenance cost. Reserve v2 for a real breaking re-shape if one ever arises.
3. **Push notifications** — see §11. Additive v1 endpoints under `/auth/me/devices*` and 3. **Push notifications** — see §11. Additive v1 endpoints under `/auth/me/devices*` and
`/auth/me/notifications*`, plus a **self-hosted `ntfy` service added to `website/docker-compose.yml`** `/auth/me/notifications*`, plus a **self-hosted `ntfy` service added to `website/docker-compose.yml`**
with fully declarative, zero-interaction config. Not required for the first release (M7, not M1M6). with fully declarative, zero-interaction config. Not required for the first release (M7, not M1M6).
4. **Version/health surfacing** — ensure `/public/status` (or a light `/public/version`) exposes 4. **Version/health surfacing.**
enough for the app's first-run probe and version-mismatch guard. ✅ **DONE (2026-07-19, RunicGateway/website#77 (+ this docs PR)).** A dependency-free
`config/version.js` (`{ service:'runic-gateway', api:'v1', server:<pkg> }`) is surfaced on
`GET /public/status` (so the first-run probe recognizes the backend + reads its version in one call)
and on a new **DB-free `GET /public/version`** (canonical target for the version-mismatch guard +
a cheap liveness check). Swagger: `PublicVersion` schema. `test/publicVersion.test.js` covers both.
5. **Docs** — update `docs/website/BACKEND_DESIGN.md` for any new/changed endpoint; keep this file and 5. **Docs** — update `docs/website/BACKEND_DESIGN.md` for any new/changed endpoint; keep this file and
the OpenAPI spec current. (The workspace `CLAUDE.md` is a **local, uncommitted** file — update it in the OpenAPI spec current. (The workspace `CLAUDE.md` is a **local, uncommitted** file — update it in
place as repos come online, but it is never committed.) place as repos come online, but it is never committed.)
6. **Branding for mobile** — confirm `/public/settings` returns the `BRAND_*` values (name, colors, 6. **Branding for mobile.**
logo/hero/favicon URLs) the app needs to theme itself per shard. ✅ **DONE (2026-07-19, RunicGateway/website#77 (+ this docs PR)).** Confirmed
`GET /public/settings` returns the per-shard `brand` block (name, `accent` color, logo/hero/favicon,
plus shortName/tagline/description/url/contactEmail) sourced from `BRAND_*` with admin
`site_title`/`contact_email` overrides — the app themes itself from it. Made it first-class in the
OpenAPI contract (`Brand` + `PublicSettings` schemas) so the app's codegen gets typed branding
instead of an untyped map; `test/publicBrand.test.js` locks the contract. Asset fields may be
site-relative paths — the app resolves them against its stored base URL.
No `link/` or `servuo-plugins/` changes are expected — the app is downstream of the website only. No `link/` or `servuo-plugins/` changes are expected — the app is downstream of the website only.

View File

@@ -195,8 +195,9 @@ by `seed.js` from env (see §6); further staff are created under `/admin/users`
### /public (public.routes.js → public.controller.js) — all GET, no auth ### /public (public.routes.js → public.controller.js) — all GET, no auth
| Method | Path | Notes | | Method | Path | Notes |
|---|---|---| |---|---|---|
| GET | `/settings` | whitelisted public keys only (mode, maintenance_message, status_message, homepage_teaser, contact_email, site_title) | | GET | `/settings` | whitelisted public keys, derived `registration`/`gameAccountSignup` flags, and the per-shard **`brand`** block (name, `accent` color, logo/hero/favicon) a client themes itself from — one image runs as any shard. Asset fields may be site-relative paths (resolve against the base URL). |
| GET | `/status` | status message + current mode | | GET | `/status` | status message + current mode, **plus a `version` block** (`{ service:'runic-gateway', api, server }`) so a client first-run probe recognizes the backend and can run a version-mismatch guard |
| GET | `/version` | lightweight, **DB-free** backend identity/version (`{ service, api, server }`) — the canonical target for the version guard and a cheap liveness check |
| GET | `/posts/:category` | published only; `category` ∈ news\|five-on-friday\|newsletter\|screenshots | | GET | `/posts/:category` | published only; `category` ∈ news\|five-on-friday\|newsletter\|screenshots |
| GET | `/posts/:category/:idOrSlug` | single published post | | GET | `/posts/:category/:idOrSlug` | single published post |
| GET | `/wiki` | list of pages (slug + title) | | GET | `/wiki` | list of pages (slug + title) |