Management API foundation #544
Labels
No labels
blocked
duplicate
high priority
needs
approval
needs
criteria
needs
estimate
needs
tests
question
step
doing
step
review
step
testing
step
todo
step
uat
type
admin
type
alert
type
bug
type
change
type
defect
type
dependencies
type
development
type/documentation
type
epic
type
idea
type
incident
type
investigation
type
spike
type
story
type
tests
wontfix
No project
No assignees
1 participant
Notifications
Total time spent: 15 minutes 56 seconds
Due date
Smithy-bot
15 minutes 56 seconds
No due date set.
Blocks
#545 Discord OAuth + session for BOT_ADMINS
External/card-drop
Reference
External/card-drop#544
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Epic: #543
Story Points: 5
SO THAT management routes share one Express surface with auth middleware and the existing
/api/reload-dbhook is no longer unauthenticated.Expand the in-process Express app (
src/webhooks.ts) into a Management API foundation: structured routing, shared auth middleware hook-point, and protect/api/reload-db.Scope
Foundational Express structure for the Web Management UI epic (#543). Discord OAuth and sessions are implemented in #545; this story defines the routing layout and protected
/apisurface those features plug into.In scope: Refactor/bootstrap Management API, protected route registration, auth middleware hook, securing existing
POST /api/reload-db.Out of scope: Discord OAuth flows (#545), React SPA shell (#546), feature endpoints (settings/cards/ops #547–#550), static asset serving (#546).
Acceptance criteria
GIVEN the bot process starts with
EXPRESS_PORTsetWHEN the Management API boots
THEN it uses the existing in-process Express entry (
src/webhooks.tsor successor) and listens on the same port as today.GIVEN the Management API foundation
WHEN a new management handler is added (current or future stories)
THEN it registers on a shared protected router (e.g. under
/api/) so all management routes use the same middleware stack.GIVEN a caller without a valid admin session
WHEN they
POST /api/reload-dbTHEN the response is 401 or 403 and
CardMetadataFunctiondoes not run.GIVEN a caller with a valid admin session (session shape defined in #545)
WHEN they
POST /api/reload-dbwith a session belonging to a Discord user ID inBOT_ADMINSTHEN behaviour matches today (reload card metadata, 200 on success).
GIVEN public auth routes from #545 (e.g. OAuth callback/login)
WHEN they are mounted
THEN they are not behind the admin-session middleware (mounted on a separate public router).
GIVEN protected management routes
WHEN authorization is evaluated
THEN v1 checks only Admin membership (
BOT_ADMINS), but the middleware/resource-check shape allows finer roles later (#551) without rewriting route registration.GIVEN automated tests exist for the Management API
WHEN CI runs
THEN tests cover at least: unauthenticated
POST /api/reload-dbrejected; authenticated admin can invoke reload (may stub session until #545 lands).Subtasks
src/webhooks.ts)requireManagementAuthmiddleware (admin session /BOT_ADMINScheck; integrates with #545 session)POST /api/reload-dbon the protected router (move from public registration)/api/*management routes (#547–#550)/api/reload-dbNotes
src/hooks/ReloadDB.ts./api/reload-dbuntil #545 provides login/session (merge or ship both in the same release).Estimate: 5 story points
src/webhooks.tswithout changing listen behaviourrequireManagementAuth+ admin/BOT_ADMINScheck with a shape that #551 can extend/apirouter, public router hook for #545, movePOST /api/reload-dbCriteria are clear; no open questions. Moving to needs/tests.
Planning — needs/tests → needs/approval
QA scripts mapped to the acceptance criteria in the issue description. Run on a branch with this story and #545 (or session stubs) on stage; automated rows via
yarn testlocally/CI.Preconditions
EXPRESS_PORTset (same as today).BOT_ADMINSincludes at least one Discord user ID used for “admin” tests.BOT_ADMINS.POSTto management host (curl/httpie) and runyarn test.AC1 — Management API boots on existing Express entry and port
EXPRESS_PORTconfiguredsrc/webhooks.ts(or successor module) is the entry; no regression to Discord bot startupAC2 — Shared protected router for
/api/*management routes/api/reload-db)/apiroutesAC3 — Unauthenticated
POST /api/reload-dbrejected; reload does not runPOST /api/reload-dbwith no session cookie / auth headerCardMetadataFunction(reload handler) not invokedBOT_ADMINSAC4 — Authenticated admin
POST /api/reload-dbsucceedsBOT_ADMINSPOST /api/reload-dbwith that sessionAC5 — Public auth routes (#545) not behind admin middleware
GET/POSTOAuth/login/callback routes from #545 without admin sessionrequireManagementAuth(may redirect or return OAuth-specific responses)/apirouterBOT_ADMINSsessionAC6 — v1 Admin-only check; extensible for #551
BOT_ADMINS) on protected routeAC7 — Automated tests in CI
yarn test— Management API / reload-db auth testsPOST /api/reload-dbSubtasks / documentation
/api/reload-dbauthSign-off checklist
Moving to needs/approval for your review before implementation. @Vylpes