feat(public): type the brand block so mobile clients get typed theming
All checks were successful
PR Checks / client-build (pull_request) Successful in 9m29s
PR Checks / server-tests (pull_request) Successful in 10m30s
PR Checks / bot-install (pull_request) Successful in 9m21s

Branding is already returned by GET /public/settings (the `brand` block:
name/colors/logo/hero/favicon, per-shard from BRAND_*). §8.6 of the Android
plan asks to confirm it — this makes it a first-class part of the contract so
the app's OpenAPI codegen produces typed branding instead of an untyped map.

- Swagger: add Brand + PublicSettings schemas; /public/settings now references
  PublicSettings (was additionalProperties:true). Brand documents that asset
  fields may be site-relative paths (resolve against the base URL).
- test/publicBrand.test.js locks the brand theming contract the app depends on
  (all fields present; BRAND_* defaults; admin site_title/contact_email
  overrides; accentInt never leaked).

No behavior change to the response — it already carried `brand`; this types and
guards it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
This commit is contained in:
2026-07-19 11:58:01 -05:00
parent 90c8eae20f
commit c35509e8b3
4 changed files with 367 additions and 8 deletions

View File

@@ -13,9 +13,9 @@ const publicRouter = express.Router()
publicRouter.get(
'/settings',
// #swagger.tags = ['Public']
// #swagger.summary = 'Public site settings'
// #swagger.description = 'Whitelisted, non-sensitive settings the client needs to render the site.'
/* #swagger.responses[200] = { description: 'Key/value settings', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
// #swagger.summary = 'Public site settings + branding'
// #swagger.description = 'Whitelisted, non-sensitive settings plus the per-shard brand block (name/colors/logo/hero/favicon) a client themes itself from, and derived registration / game-account-signup availability flags.'
/* #swagger.responses[200] = { description: 'Public settings + branding', content: { "application/json": { schema: { $ref: "#/components/schemas/PublicSettings" } } } } */
ctrl.getSettings,
)
publicRouter.get(