From 36c1fe805e2de486d17cef77e2d17f4b46874d64 Mon Sep 17 00:00:00 2001 From: Julien Gautier Date: Fri, 1 May 2026 20:43:13 +0200 Subject: [PATCH] refactor(routes): extract user and application routes into auth domain Move /api/cms/user and /api/skydive/applications to a new /api/auth domain. Users and API key applications are identity/access concerns, not CMS or skydive content. The auth domain provides a clear boundary for future middleware hardening (rate limiting, audit logging, etc). docs: add ADR 0014 --- docs/decisions/0014-auth-domain-extraction.md | 60 +++++++++++++++++++ .../{skydive => auth}/applications.routes.js | 0 src/routes/api/auth/index.js | 6 ++ src/routes/api/{cms => auth}/users.routes.js | 0 src/routes/api/cms/index.js | 1 - src/routes/api/index.js | 1 + src/routes/api/skydive/index.js | 1 - 7 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 docs/decisions/0014-auth-domain-extraction.md rename src/routes/api/{skydive => auth}/applications.routes.js (100%) create mode 100644 src/routes/api/auth/index.js rename src/routes/api/{cms => auth}/users.routes.js (100%) diff --git a/docs/decisions/0014-auth-domain-extraction.md b/docs/decisions/0014-auth-domain-extraction.md new file mode 100644 index 0000000..6324f1b --- /dev/null +++ b/docs/decisions/0014-auth-domain-extraction.md @@ -0,0 +1,60 @@ +# Extract user and application routes into a dedicated auth domain + +* Status: accepted +* Date: 2026-05-01 + +## Context and Problem Statement + +User authentication/registration routes (`/api/cms/user`) were grouped under the CMS domain, and API key application routes (`/api/skydive/applications`) were grouped under the Skydive domain. Neither resource is domain-specific content: users and applications are identity and access management concerns shared across all domains. + +## Decision Drivers + +* The domain prefix should reflect what a resource *is*, not which feature first needed it. +* `/api/cms/user` implies users are CMS content; `/api/skydive/applications` implies API keys are skydive data — both are misleading. +* A dedicated `auth` domain makes the security boundary explicit and easier to apply targeted middleware (rate limiting, stricter CORS, etc.) in the future. + +## Considered Options + +* Keep routes in their current domains +* Move only users out of CMS, leave applications in skydive +* Create a dedicated `auth` domain for both + +## Decision Outcome + +Chosen option: "dedicated `auth` domain", because both resources are identity/access concerns and grouping them together makes the API surface self-documenting. + +Changes made: +- `src/routes/api/auth/` created with `users.routes.js`, `applications.routes.js`, and `index.js` +- `/user` removed from `src/routes/api/cms/index.js` +- `/applications` removed from `src/routes/api/skydive/index.js` +- `/auth` domain registered in `src/routes/api/index.js` +- Frontend `user.service.ts` and `applications.service.ts` updated: `_apiDomain` changed from `/cms` and `/skydive` to `/auth` + +Resulting routes: `/api/auth/user/*` and `/api/auth/applications/*`. + +### Positive Consequences + +* API domain structure matches resource semantics — auth concerns are isolated from content and feature domains. +* A single place to tighten auth-specific middleware (rate limiting, IP allowlists, audit logging) without touching other domains. + +### Negative Consequences + +* Breaking change on the API surface — any client other than the Angular frontend calling the old paths must be updated. + +## Pros and Cons of the Options + +### Keep routes in current domains + +* Good, because no migration effort. +* Bad, because the domain prefix actively misleads — users are not CMS content, applications are not skydive data. + +### Move only users out of CMS + +* Good, because smaller change. +* Bad, because applications in skydive remains wrong, and two related resources end up in different places. + +### Dedicated auth domain + +* Good, because both resources land where their semantics say they belong. +* Good, because the auth boundary is explicit and ready for future hardening. +* Bad, because it is a breaking change requiring a coordinated update of all consumers. diff --git a/src/routes/api/skydive/applications.routes.js b/src/routes/api/auth/applications.routes.js similarity index 100% rename from src/routes/api/skydive/applications.routes.js rename to src/routes/api/auth/applications.routes.js diff --git a/src/routes/api/auth/index.js b/src/routes/api/auth/index.js new file mode 100644 index 0000000..4d91f03 --- /dev/null +++ b/src/routes/api/auth/index.js @@ -0,0 +1,6 @@ +var routes = require('express').Router(); + +routes.use('/user', require('./users.routes')); +routes.use('/applications', require('./applications.routes')); + +module.exports = routes; diff --git a/src/routes/api/cms/users.routes.js b/src/routes/api/auth/users.routes.js similarity index 100% rename from src/routes/api/cms/users.routes.js rename to src/routes/api/auth/users.routes.js diff --git a/src/routes/api/cms/index.js b/src/routes/api/cms/index.js index b998f61..b6dd559 100644 --- a/src/routes/api/cms/index.js +++ b/src/routes/api/cms/index.js @@ -1,6 +1,5 @@ var routes = require('express').Router(); -routes.use('/user', require('./users.routes')); routes.use('/articles', require('./articles.routes')); routes.use('/comments', require('./comments.routes')); routes.use('/profiles', require('./profiles.routes')); diff --git a/src/routes/api/index.js b/src/routes/api/index.js index 17e67b3..fab05c2 100644 --- a/src/routes/api/index.js +++ b/src/routes/api/index.js @@ -1,5 +1,6 @@ var routes = require('express').Router(); +routes.use('/auth', require('./auth')); routes.use('/skydive', require('./skydive')); routes.use('/cms', require('./cms')); routes.use('/ecommerce', require('./ecommerce')); diff --git a/src/routes/api/skydive/index.js b/src/routes/api/skydive/index.js index d9da4b6..0689e1b 100644 --- a/src/routes/api/skydive/index.js +++ b/src/routes/api/skydive/index.js @@ -1,6 +1,5 @@ var routes = require('express').Router(); -routes.use('/applications', require('./applications.routes')); routes.use('/aeronefs', require('./aeronefs.routes')); routes.use('/canopies', require('./canopies.routes')); routes.use('/dropzones', require('./dropzones.routes'));