docs(website): record the PR 3 admin router split (posts, uploads, wiki, pages) #56

Merged
whitlocktech merged 1 commits from docs/admin-router-split-3 into main 2026-07-28 00:28:26 +00:00
Member

What & why

Records PR 3 of the admin router splitRunicGateway/website#104 (posts, uploads, wiki, pages; 31 routes extracted, 33 left in admin.routes.js). Follows docs#53 (PR 1) and docs#54 (PR 2).

website/API_V2_PLAN.md — adds a "PR 3 — as landed" section and ticks the sequencing list. Findings carried forward:

  • The residual 33 is exactly PR 4's list (shard 16, email 6, uo-link 5, settings 2, discord-bot 2, dashboard 1, site-mode 1), so admin.routes.js is deleted by PR 4, one PR earlier than the sequencing list implied. PR 5 becomes public/* + player/* + auth/* only.
  • First shared module in the split (admin/imageUpload.js) — the multer config, because POST /posts/upload and POST /uploads no longer live in the same file. Documented with the reason it must stay in admin/: UPLOAD_DIR is __dirname-relative.
  • POST /uploads keeps its Admin · Posts swagger tag — retagging is a real OpenAPI diff, so it doesn't belong in a PR whose acceptance criterion is a byte-identical spec. Same call as PR 1's /shard/* tag mismatch.
  • A new class of hazard no gate can catch: the wiki router's literal /categories and /tags paths must precede /:slug, and the manifest sorts its entries, so a reordering is invisible in all three gates. Verified instead by introspecting the built router stack. Any future PR moving /:slug-style routes needs the same explicit check — this is the most reusable finding in the section.
  • /admin/pages (CMS builder) vs /admin/shard/pages (in-game help queue) are unrelated capabilities that read alike — same trap as PR 2's activity/dashboard/bot-activity trio.

website/BACKEND_DESIGN.md — §2 folder tree gains the four routers plus imageUpload.js (marked as not-a-router) and the residual count drops 64 → 33; the "landed so far" note covers PR 3. §4's /admin preamble now says the content capabilities add no gate beyond staffOnly. The §4 URL table is unchanged, because no URL changed.

PROJECT_TREE.md is deliberately untouched — it's auto-generated by the sync-project-tree workflow (website#98), which opens its own docs PR after the merge.

How it was tested

Documentation only — no code. Verified against the merged state of website#104: route counts per prefix were read out of the generated routes.manifest.json rather than counted by hand.

admin total: 110
  /account 6   /activity 1   /auth 4        /bot-activity 2   /dashboard 1
  /discord-bot 2   /email 6   /invites 3    /moderation 15    /pages 7
  /posts 9     /settings 2    /shard 16     /site-mode 1      /uo-link 5
  /uploads 1   /users 15      /wiki 14

Checklist

  • I have read CONTRIBUTING.md.
  • The change builds and existing tests/checks pass locally.
  • I have added or updated tests/docs where it makes sense.
  • My commits are reasonably scoped with clear messages.

AI-assisted contributions (required)

This project requires disclosure of AI tool usage. Please pick one:

  • No AI tools were used to produce this contribution.
  • AI tools were used. Tool(s): Claude Code (Opus 5). I have reviewed and understand
    every change, and take responsibility for it. AI-authored commits are
    marked with a Co-Authored-By / Assisted-By trailer.

License

  • I agree that my contribution is licensed under this project's license
    (GNU GPL v3.0 or later), and I have the right to contribute it.
## What & why Records **PR 3 of the admin router split** — RunicGateway/website#104 (`posts`, `uploads`, `wiki`, `pages`; 31 routes extracted, 33 left in `admin.routes.js`). Follows docs#53 (PR 1) and docs#54 (PR 2). **`website/API_V2_PLAN.md`** — adds a "PR 3 — as landed" section and ticks the sequencing list. Findings carried forward: - **The residual 33 is exactly PR 4's list** (shard 16, email 6, uo-link 5, settings 2, discord-bot 2, dashboard 1, site-mode 1), so `admin.routes.js` is deleted by **PR 4**, one PR earlier than the sequencing list implied. PR 5 becomes `public/*` + `player/*` + `auth/*` only. - **First shared module in the split** (`admin/imageUpload.js`) — the multer config, because `POST /posts/upload` and `POST /uploads` no longer live in the same file. Documented with the reason it must stay in `admin/`: `UPLOAD_DIR` is `__dirname`-relative. - **`POST /uploads` keeps its `Admin · Posts` swagger tag** — retagging is a real OpenAPI diff, so it doesn't belong in a PR whose acceptance criterion is a byte-identical spec. Same call as PR 1's `/shard/*` tag mismatch. - **A new class of hazard no gate can catch:** the wiki router's literal `/categories` and `/tags` paths must precede `/:slug`, and **the manifest sorts its entries, so a reordering is invisible in all three gates**. Verified instead by introspecting the built router stack. Any future PR moving `/:slug`-style routes needs the same explicit check — this is the most reusable finding in the section. - `/admin/pages` (CMS builder) vs `/admin/shard/pages` (in-game help queue) are unrelated capabilities that read alike — same trap as PR 2's `activity`/`dashboard`/`bot-activity` trio. **`website/BACKEND_DESIGN.md`** — §2 folder tree gains the four routers plus `imageUpload.js` (marked as not-a-router) and the residual count drops 64 → 33; the "landed so far" note covers PR 3. §4's `/admin` preamble now says the content capabilities add no gate beyond `staffOnly`. The §4 URL table is unchanged, because no URL changed. `PROJECT_TREE.md` is deliberately untouched — it's auto-generated by the `sync-project-tree` workflow (website#98), which opens its own docs PR after the merge. ## How it was tested Documentation only — no code. Verified against the merged state of website#104: route counts per prefix were read out of the generated `routes.manifest.json` rather than counted by hand. ``` admin total: 110 /account 6 /activity 1 /auth 4 /bot-activity 2 /dashboard 1 /discord-bot 2 /email 6 /invites 3 /moderation 15 /pages 7 /posts 9 /settings 2 /shard 16 /site-mode 1 /uo-link 5 /uploads 1 /users 15 /wiki 14 ``` ## Checklist - [x] I have read [CONTRIBUTING.md](CONTRIBUTING.md). - [x] The change builds and existing tests/checks pass locally. - [x] I have added or updated tests/docs where it makes sense. - [x] My commits are reasonably scoped with clear messages. ## AI-assisted contributions (required) This project **requires disclosure of AI tool usage**. Please pick one: - [ ] No AI tools were used to produce this contribution. - [x] AI tools were used. Tool(s): `Claude Code (Opus 5)`. I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a `Co-Authored-By` / `Assisted-By` trailer. ## License - [x] I agree that my contribution is licensed under this project's license (**GNU GPL v3.0 or later**), and I have the right to contribute it.
wtclaude added 1 commit 2026-07-28 00:27:01 +00:00
Adds a "PR 3 — as landed" section to API_V2_PLAN.md and ticks the sequencing
list. 31 routes extracted, 33 left in admin.routes.js; all four zero-diff gates
came back clean and 434 server tests passed.

Findings carried forward:

- The residual 33 is exactly PR 4's list, so admin.routes.js is deleted by
  PR 4 rather than PR 5.
- First shared module in the split: the multer config, because POST
  /posts/upload and POST /uploads no longer live in the same file.
- POST /uploads keeps its Admin · Posts swagger tag — retagging is a real
  OpenAPI diff and does not belong in a route-move PR.
- The wiki router has load-bearing intra-file route order (/categories and
  /tags ahead of /:slug) that no gate can catch, because the manifest sorts
  its entries. Verified by introspecting the built router stack instead.

BACKEND_DESIGN.md §2 gets the four new routers plus imageUpload.js in the
folder tree, and §4 notes that the content capabilities add no gate beyond
staffOnly.

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech merged commit 9f6ad6888d into main 2026-07-28 00:28:26 +00:00
whitlocktech deleted branch docs/admin-router-split-3 2026-07-28 00:28:27 +00:00
Sign in to join this conversation.
No description provided.