Summary
POST /team-sessions/create is registered by two different routers. systemRouter mounts first, so its handler always wins and createTeamSession in team.controller.ts is never reached.
Nothing is exposed by this — both registrations carry requireAccessToken — but one of the two implementations is unreachable, and the fact that it's unreachable isn't visible from either file.
The two registrations
backend/src/routes/system.routes.ts:94
router.post('/team-sessions/create', requireAccessToken, async (req, res) => { ... });
backend/src/routes/team.routes.ts:8
router.post('/team-sessions/create', requireAccessToken, createTeamSession);
Which one wins, and why
Express matches in mount order. server.ts:
117: app.use(createSystemRouter());
...
125: app.use(createTeamRouter());
systemRouter is mounted eight lines earlier, so its handler answers every request and teamRouter's never runs.
Why it's worth fixing even though nothing is broken
The two implementations are currently equivalent — same isValidTeamRepo validation, same teamSessionStore.createSession call, same response shape. That equivalence is what makes this a trap rather than a bug today.
The moment someone fixes a bug or adds validation in team.controller.ts — the file whose name suggests it owns team sessions — the change will have no effect, and there is nothing in that file to indicate why. Debugging that costs far more than the duplication itself.
team.routes.ts also registers GET /team-sessions/:code, which is not duplicated and does work, so the file isn't obviously dead at a glance.
Suggested fix
Keep one. team.routes.ts + team.controller.ts is the better home — it's where the name says the logic lives, and it keeps system.routes.ts for genuinely system-level concerns. That means deleting the block at system.routes.ts:94-115 and confirming the controller version handles everything the inline one did.
Worth a quick check for other duplicate registrations at the same time; I only noticed this one because the route list happened to show both.
Happy to take this.
Summary
POST /team-sessions/createis registered by two different routers.systemRoutermounts first, so its handler always wins andcreateTeamSessioninteam.controller.tsis never reached.Nothing is exposed by this — both registrations carry
requireAccessToken— but one of the two implementations is unreachable, and the fact that it's unreachable isn't visible from either file.The two registrations
backend/src/routes/system.routes.ts:94backend/src/routes/team.routes.ts:8Which one wins, and why
Express matches in mount order.
server.ts:systemRouteris mounted eight lines earlier, so its handler answers every request andteamRouter's never runs.Why it's worth fixing even though nothing is broken
The two implementations are currently equivalent — same
isValidTeamRepovalidation, sameteamSessionStore.createSessioncall, same response shape. That equivalence is what makes this a trap rather than a bug today.The moment someone fixes a bug or adds validation in
team.controller.ts— the file whose name suggests it owns team sessions — the change will have no effect, and there is nothing in that file to indicate why. Debugging that costs far more than the duplication itself.team.routes.tsalso registersGET /team-sessions/:code, which is not duplicated and does work, so the file isn't obviously dead at a glance.Suggested fix
Keep one.
team.routes.ts+team.controller.tsis the better home — it's where the name says the logic lives, and it keepssystem.routes.tsfor genuinely system-level concerns. That means deleting the block atsystem.routes.ts:94-115and confirming the controller version handles everything the inline one did.Worth a quick check for other duplicate registrations at the same time; I only noticed this one because the route list happened to show both.
Happy to take this.