PR 3 of the in-place admin router split (docs/website/API_V2_PLAN.md § Phase 2).
Moves the content tier out of the residual admin.routes.js into one router file
per capability, each mounted at the prefix it already owned. No URL, gate or
handler changes.
posts.router.js ( 9) /admin/posts
uploads.router.js ( 1) /admin/uploads
wiki.router.js (14) /admin/wiki
pages.router.js ( 7) /admin/pages
admin.routes.js (33) residual, was 64
All four capabilities are editor tier, so no gate moved: the shared
`noindex, isLoggedIn, staffOnly` in admin/index.js is their whole gate.
The multer config moved to admin/imageUpload.js because the two routes that
share it (POST /posts/upload and POST /uploads) now live in different files;
duplicating a mimetype allowlist is how the two copies drift. It stays in
admin/ because UPLOAD_DIR is resolved relative to __dirname.
Acceptance — all four gates zero-diff:
routes.manifest.json unchanged (200 public + 2 internal)
routes.guards.json unchanged (no route lost or gained a gate)
swagger-output.json unchanged (198 operations)
api-route-inventory.json already in sync
plus 434 server tests green.
Verified separately, because no gate can catch it: the wiki router's literal
/categories and /tags paths still precede /:slug in declaration order. The
manifest sorts its entries, so a reordering there would be invisible.
Co-Authored-By: Claude <noreply@anthropic.com>