mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
docs: regenerate migration-graph after the auth fold
Re-ran the three-pattern import scan over server/src: authService row deleted, thirteen helper rows updated (nine lose their last legacy importer), oidcService/passkeyService join the ready frontier as auth.bridge repoints, adminService is blocked on notificationService alone, atlas.bridge's death recorded, dependency-honest order step 5 ticked, a post-auth-fold corrections entry added (bridge tax held exactly; the reverse cycle-break, the in-container module fan-out and path-mock rot are now tracked shapes), and the preserved auth quirks listed as trailing fix(server) candidates.
This commit is contained in:
+156
-41
@@ -1,9 +1,58 @@
|
||||
# Legacy `src/services/` dependency graph
|
||||
|
||||
Generated from the actual imports in `server/src` on **2026-08-01** (after the
|
||||
authService fold — the Wave-5 chain opener, cashed in the moment the atlas fold
|
||||
unblocked it, while the notifications fan-in stays the order's official next
|
||||
step: the 1497-line auth core — the biggest single fold of the migration —
|
||||
split places-style. The pure crypto half (backup-code hash/match/generate with
|
||||
the bcrypt/legacy-SHA dual verify, `stripUserForClient`, key masking, the
|
||||
import-time `DUMMY_PASSWORD_HASH` timing equaliser and the `avatarDir` mkdir,
|
||||
both documented parity exceptions) moved to the plain module
|
||||
`nest/auth/auth.helpers.ts`; the DB half (toggles/app-config, register/login
|
||||
with the CWE-208 dummy-hash path, MFA setup/enable/disable/verify-login, the
|
||||
password-reset throttle + token flows with their two `db.transaction()`
|
||||
revocation blocks, API keys/settings, travel stats, MCP/ws/resource tokens,
|
||||
`isDemoUser` and the two token verifiers) folded into the DI-native
|
||||
`AuthService` over `DatabaseService` + injected `PermissionsService` (ex
|
||||
`permissions.bridge`) + `AtlasService` (ex `atlas.bridge`, which **died on
|
||||
schedule** — its doc-comment said "delete this file when authService
|
||||
migrates"). The `mfaSetupPending` and per-email reset-throttle maps stay
|
||||
module-scoped (with the import-time unref'd cleanup interval, atlas-geo
|
||||
class) so the bridge instance and the container singleton share one copy;
|
||||
`require('../../../package.json')` and `avatarDir` re-anchored one directory
|
||||
deeper — with the two injection swaps, the only non-verbatim lines. No MCP
|
||||
registrar existed and the plugin host never imported authService, so neither
|
||||
surface changed — but the fold's real fan-out was in-container: the 15
|
||||
domain `*.mcp.ts` demo guards now inject `AuthService` (15 modules gained an
|
||||
`AuthModule` import), with `atlas.mcp.ts` alone staying on a bridge import
|
||||
because AuthService injects AtlasService and the reverse module edge would
|
||||
close an AuthModule↔AtlasModule cycle — the second entry in the
|
||||
cycle-break-bridge category the place fold opened (`assignments.bridge`
|
||||
precedent), except this time on the brand-new bridge. That bridge —
|
||||
the 8-export `nest/auth/auth.bridge.ts` — otherwise serves exactly the
|
||||
predicted tax: `mcp/index.ts`'s token verification
|
||||
(`verifyMcpToken`/`verifyJwtToken`), `isDemoUser` for the three legacy
|
||||
registrars (journey/notifications/transports), and
|
||||
`resolveAuthToggles`/`generateToken`/`stripUserForClient`/`avatarUrl` for the
|
||||
still-legacy adminService/oidcService/passkeyService. Tests moved with case
|
||||
IDs preserved (authService.test.ts → auth.helpers.test.ts,
|
||||
authServiceDb.test.ts → auth.service.test.ts, which also gained
|
||||
AUTH-BR-001…007 bridge-delegation cases and AUTH-DB-050…088 — the fold put
|
||||
~1400 previously ungated lines under the ≥80% `src/nest/**` branch gate, and
|
||||
the legacy suite left getAppConfig/resetPassword/the MFA success flows
|
||||
unpinned); `auth.e2e.test.ts` converted DI-native (the 30-method whole-module
|
||||
mock died — login now runs real bcrypt against a factory hash and audit rows
|
||||
land in a real audit_log), and `oidc.e2e.test.ts` swapped its silently-dead
|
||||
`services/authService` path mock for a `vi.spyOn(app.get(AuthService), …)`
|
||||
instance stub. A sibling DTO ratchet cleared all **14** auth allow-list
|
||||
entries (9 `AuthController` + 5 `AuthPublicController`; `PasskeyController`'s
|
||||
4 stay until passkeyService migrates), adding the six missing request schemas
|
||||
(mapsKey/apiKeys/settings/appSettings/mfaDisable/resourceToken) to
|
||||
`shared/src/auth/auth.schema.ts`. No trailing quirk commit yet — the
|
||||
faithfully-carried defects are listed under "Quirks preserved" below,
|
||||
awaiting their own `fix(server)` pass. Earlier the same day, the
|
||||
atlasService fold — the second frontier pull-forward of the day, opening the
|
||||
Wave-5 auth chain while the notifications fan-in stays the order's official
|
||||
next step: the 1612-line atlas core split two ways, places precedent. The DB
|
||||
Wave-5 auth chain: the 1612-line atlas core split two ways, places precedent. The DB
|
||||
half — the stats aggregation with its two divergent return shapes, visited
|
||||
countries/regions with the #1490 tombstone/cascade logic, bucket-list CRUD —
|
||||
folded into the DI-native `AtlasService` over `DatabaseService` alone (no
|
||||
@@ -29,7 +78,7 @@ ends at five: `authService.getTravelStats` (legacy, Wave-5) consumes
|
||||
`getCountryFromCoords` + `getHiddenCountries`, so a minimal 2-export
|
||||
`atlas.bridge.ts` exists for that one edge — `getCountryFromCoords`
|
||||
re-exported straight from atlas-geo, `getHiddenCountries` over the bridge
|
||||
instance — and dies when authService migrates. A sibling DTO ratchet cleared
|
||||
instance — and it died with the auth fold later the same day. A sibling DTO ratchet cleared
|
||||
all three `AtlasController` body-contract allow-list entries
|
||||
(mark-region + bucket create/update), trading the hand-rolled
|
||||
`'name and country_code are required'` 400 for the pipe envelope while the
|
||||
@@ -202,11 +251,25 @@ How to read it:
|
||||
`nest/atlas/atlas-geo.ts` so the multi-MB caches stay process-global across
|
||||
every instance (#1576); the 10-tool registrar + all four resources onto
|
||||
`atlas.mcp.ts` with the `when:` atlas-addon gate that IS parity here; the
|
||||
plugin host injects the service as its 23rd constructor dep; **one bridge**,
|
||||
the 2-export `atlas.bridge.ts` for legacy `authService.getTravelStats` —
|
||||
it dies when authService migrates).
|
||||
plugin host injects the service as its 23rd constructor dep; its 2-export
|
||||
`atlas.bridge.ts` served legacy `authService.getTravelStats` and died on
|
||||
schedule with the auth fold),
|
||||
auth (the 1497-line credential/MFA/reset/settings core folded into
|
||||
`AuthService` over `DatabaseService` + injected `PermissionsService` +
|
||||
`AtlasService`; the pure crypto half — backup-code hashing/matching,
|
||||
`stripUserForClient`, key masking, the import-time `DUMMY_PASSWORD_HASH`
|
||||
and `avatarDir` mkdir parity exceptions — is plain exports in
|
||||
`nest/auth/auth.helpers.ts`; `mfaSetupPending` + the per-email
|
||||
reset-throttle map (and its unref'd interval) stay module-scoped so the
|
||||
bridge and container instances share them; **one bridge**, the 8-export
|
||||
`auth.bridge.ts` — for `mcp/index.ts` token verification, the three legacy
|
||||
registrars' `isDemoUser`, the still-legacy
|
||||
adminService/oidcService/passkeyService, and the one in-container
|
||||
cycle-break consumer `atlas.mcp.ts` (AuthService injects AtlasService, so
|
||||
AtlasModule cannot import AuthModule — assignments.bridge precedent); the
|
||||
other 15 domain `*.mcp.ts` demo guards inject `AuthService`).
|
||||
- **Domain migration targets** (the wave material): adminService, airportService,
|
||||
authService, backupService,
|
||||
backupService,
|
||||
journeyService, journeyShareService, notificationService, oauthService,
|
||||
oidcService, passkeyService, weatherService, wikiService.
|
||||
- **Cross-cutting Wave-2 targets:** permissions and auditLog are done (2026-07) — see the
|
||||
@@ -237,13 +300,12 @@ flowchart TD
|
||||
airport["airportService (boot special case)"]:::ready
|
||||
wiki[wikiService]:::ready
|
||||
oauth[oauthService]:::ready
|
||||
auth["authService (frontier since the 2026-08 atlas fold)"]:::ready
|
||||
oidc["oidcService (frontier since the 2026-08 auth fold)"]:::ready
|
||||
passkey["passkeyService (frontier since the 2026-08 auth fold)"]:::ready
|
||||
end
|
||||
|
||||
notifSvc[notificationService]:::blocked
|
||||
admin[adminService]:::blocked
|
||||
oidc[oidcService]:::blocked
|
||||
passkey[passkeyService]:::blocked
|
||||
journey[journeyService]:::blocked
|
||||
journeyShare[journeyShareService]:::blocked
|
||||
backup["backupService (last by design)"]:::infra
|
||||
@@ -252,20 +314,25 @@ flowchart TD
|
||||
cleanup[userCleanupService]:::infra
|
||||
|
||||
notifSvc --> notifCluster
|
||||
admin --> auth & notifSvc & cleanup
|
||||
oidc --> auth
|
||||
passkey --> auth
|
||||
admin --> notifSvc & cleanup
|
||||
journey --> memories
|
||||
journeyShare --> journey
|
||||
memories --> notifSvc & admin
|
||||
```
|
||||
|
||||
(The `atlasService` node is gone since the 2026-08-01 fold — it left the
|
||||
frontier as the first fold whose legacy dependent outlives it: the former
|
||||
`auth --> atlas` edge is now legacy `authService` importing the 2-export
|
||||
`nest/atlas/atlas.bridge` (an import-path-only repoint, todo-bridge precedent),
|
||||
so authService's own migration is UNBLOCKED — the Wave-5 auth chain
|
||||
`auth → admin → oauth` can start any time the notifications step allows.
|
||||
(The `authService` node is gone since the 2026-08-01 fold — the Wave-5 chain
|
||||
opener landed the same day its atlas blocker cleared. The three `--> auth`
|
||||
edges (admin/oidc/passkey, all `resolveAuthToggles`-class imports, passkey
|
||||
also `generateToken`/`stripUserForClient`/`avatarUrl`) became import-path-only
|
||||
repoints onto the 8-export `nest/auth/auth.bridge` (todo-bridge precedent),
|
||||
which puts **oidcService and passkeyService on the frontier** — their only
|
||||
other legacy deps are helpers (apiKeyCrypto/tripMembership,
|
||||
webauthnConfig) — while `adminService` stays blocked on its hard
|
||||
`notificationService` import alone. `userCleanupService` is infra, not a
|
||||
blocker (helpers never block). The `atlasService` node left the frontier
|
||||
earlier the same day as the first fold whose legacy dependent outlived it:
|
||||
its former `auth --> atlas` bridge edge died with the auth fold, and
|
||||
`atlas.bridge.ts` with it.
|
||||
The `collectionsService` node is gone since the 2026-08-01 fold — its dotted
|
||||
call-time `import()` edge to notificationService survives inside the DI-native
|
||||
`CollectionsService`, exactly like the identical lazy sends in the
|
||||
@@ -299,41 +366,40 @@ never block).)
|
||||
|
||||
| service | imports (services/) | imported by (services/) | nest consumers | out-of-container consumers |
|
||||
|---|---|---|---|---|
|
||||
| `adminService` | apiKeyCrypto, authService, avatarUrl, llmConfig, memories/helpersService, notificationService, passwordPolicy, userCleanupService (+ `permissions.bridge`, `addons.bridge`) | (none) | nest/admin/admin.service.ts, nest/packing/packing.mcp.ts (`deletePackingTemplate`, the `admin-2` residual) | scheduler.ts (lazy) |
|
||||
| `adminService` | apiKeyCrypto, avatarUrl, llmConfig, memories/helpersService, notificationService, passwordPolicy, userCleanupService (+ `permissions.bridge`, `addons.bridge`, `auth.bridge`) | (none) | nest/admin/admin.service.ts, nest/packing/packing.mcp.ts (`deletePackingTemplate`, the `admin-2` residual) | scheduler.ts (lazy) |
|
||||
| `airportService` | (none) | (none) | nest/airports/airports.service.ts, nest/booking-import/kitinerary-mapper.ts | db/database.ts (lazy boot backfill), mcp/tools/mapsWeather.ts, mcp/tools/transports.ts |
|
||||
| `apiKeyCrypto` | (none) | adminService, airtrail/airtrailService, authService, llmConfig, memories/helpersService, memories/immichService, memories/photoResolverService, memories/synologyService, memories/unifiedService, notifications, oidcService, unsplashService | nest/maps/maps.service.ts, nest/plugins/plugin-oauth.service.ts, nest/plugins/plugin-runtime.service.ts, nest/plugins/plugins.service.ts, nest/settings/settings.service.ts | db/migrations.ts |
|
||||
| `authService` | apiKeyCrypto, avatarUrl, demo, distanceService, ephemeralTokens, mfaCrypto, passwordPolicy, tripMembership, userCleanupService, webauthnConfig (+ `permissions.bridge`, `atlas.bridge`) | adminService, oidcService, passkeyService | nest/assignments/assignments.mcp.ts, nest/atlas/atlas.mcp.ts, nest/auth/auth.service.ts, nest/auth/passkey-enabled.guard.ts, nest/budget/budget.mcp.ts, nest/collab/collab.mcp.ts, nest/collections/collections.mcp.ts, nest/days/day-notes.mcp.ts, nest/days/days.mcp.ts, nest/oidc/oidc.service.ts, nest/packing/packing.mcp.ts, nest/places/places.mcp.ts, nest/reservations/reservations.mcp.ts, nest/share/share.mcp.ts, nest/tags/tags.mcp.ts, nest/todo/todo.mcp.ts, nest/transit/transit.mcp.ts, nest/trips/trips.mcp.ts, nest/vacay/vacay.mcp.ts | mcp/index.ts, mcp/tools/journey.ts, mcp/tools/notifications.ts, mcp/tools/transports.ts |
|
||||
| `avatarUrl` | (none) | adminService, authService, inAppNotifications, journeyService | nest/budget/budget.service.ts, nest/collab/collab.service.ts, nest/files/files.service.ts, nest/packing/packing.service.ts, nest/reservations/reservations.service.ts, nest/trips/trips.service.ts | (none) |
|
||||
| `apiKeyCrypto` | (none) | adminService, airtrail/airtrailService, llmConfig, memories/helpersService, memories/immichService, memories/photoResolverService, memories/synologyService, memories/unifiedService, notifications, oidcService, unsplashService | nest/auth/auth.helpers.ts, nest/auth/auth.service.ts, nest/maps/maps.service.ts, nest/plugins/plugin-oauth.service.ts, nest/plugins/plugin-runtime.service.ts, nest/plugins/plugins.service.ts, nest/settings/settings.service.ts | db/migrations.ts |
|
||||
| `avatarUrl` | (none) | adminService, inAppNotifications, journeyService | nest/auth/auth.bridge.ts, nest/auth/auth.service.ts, nest/budget/budget.service.ts, nest/collab/collab.service.ts, nest/files/files.service.ts, nest/packing/packing.service.ts, nest/reservations/reservations.service.ts, nest/trips/trips.service.ts | (none) |
|
||||
| `backupService` | (none — `permissions.bridge`, plugin backup/paths infra only) | (none) | nest/backup/backup.controller.ts, nest/backup/backup.service.ts | scheduler.ts (lazy) |
|
||||
| `conflictResult` | (none) | (none) | nest/packing/packing.controller.ts, nest/packing/packing.service.ts, nest/places/places.controller.ts, nest/places/places.service.ts, nest/plugins/host/plugin-host-deps.factory.ts | (none) |
|
||||
| `cookie` | (none) | (none) | nest/auth/auth-public.controller.ts, nest/auth/auth.service.ts, nest/auth/passkey.controller.ts, nest/oidc/oidc.controller.ts, nest/oidc/oidc.service.ts | (none) |
|
||||
| `demo` | (none) | authService | nest/auth/auth.controller.ts, nest/collections/collections.controller.ts, nest/files/files.controller.ts, nest/places/places.controller.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/trips/trips.controller.ts | middleware/auth.ts, middleware/mfaPolicy.ts |
|
||||
| `distanceService` | (none) | authService | nest/transit/transit-itinerary.helpers.ts | (none) |
|
||||
| `ephemeralTokens` | (none) | authService | nest/files/files.service.ts | index.ts, websocket.ts |
|
||||
| `demo` | (none) | (none) | nest/auth/auth.controller.ts, nest/auth/auth.service.ts, nest/collections/collections.controller.ts, nest/files/files.controller.ts, nest/places/places.controller.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/trips/trips.controller.ts | middleware/auth.ts, middleware/mfaPolicy.ts |
|
||||
| `distanceService` | (none) | (none) | nest/auth/auth.service.ts, nest/transit/transit-itinerary.helpers.ts | (none) |
|
||||
| `ephemeralTokens` | (none) | (none) | nest/auth/auth.service.ts, nest/files/files.service.ts | index.ts, websocket.ts |
|
||||
| `inAppNotificationActions` | (none) | inAppNotifications | (none) | (none) |
|
||||
| `inAppNotifications` | avatarUrl, inAppNotificationActions, notificationPreferencesService | notificationService | nest/notifications/notifications.service.ts | mcp/resources.ts, mcp/tools/notifications.ts |
|
||||
| `journeyService` | avatarUrl, memories/photoResolverService | journeyShareService | nest/assignments/assignments.service.ts, nest/journey/journey.service.ts, nest/places/places.mcp.ts, nest/places/places.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/plugins/journal-entry-rows.controller.ts | mcp/resources.ts, mcp/tools/journey.ts |
|
||||
| `journeyShareService` | journeyService | (none) | nest/journey/journey.service.ts | mcp/tools/journey.ts |
|
||||
| `kmlImport` | (none) | (none) | nest/places/places.helpers.ts, nest/places/places.service.ts | (none) |
|
||||
| `llmConfig` | apiKeyCrypto | adminService | nest/llm-parse/llm-client.factory.ts, nest/llm-parse/llm-config.resolver.ts | (none) |
|
||||
| `mfaCrypto` | (none) | authService | (none) | (none) |
|
||||
| `mfaCrypto` | (none) | (none) | nest/auth/auth.service.ts | (none) |
|
||||
| `notificationPreferencesService` | notifications, notifications/builtins, notifications/channelRegistry | inAppNotifications, notificationService, notifications, notifications/channelRegistry | nest/admin/admin.service.ts, nest/notifications/notifications.service.ts, nest/plugins/install/manifest.ts | (none) |
|
||||
| `notifications` | apiKeyCrypto, notificationPreferencesService (+ `audit-log.logger`) | notificationPreferencesService, notificationService, notifications/builtins | nest/auth/auth.service.ts, nest/notifications/notifications.service.ts | (none) |
|
||||
| `notificationService` | inAppNotifications, notificationPreferencesService, notifications, notifications/channelRegistry (+ `audit-log.logger`) | adminService, memories/synologyService, memories/unifiedService | nest/admin/admin.controller.ts, nest/collab/collab.service.ts, nest/collections/collections.service.ts (lazy), nest/packing/packing.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/reservations/reservations.service.ts, nest/trips/trips.service.ts, nest/vacay/vacay.service.ts | scheduler.ts (lazy) |
|
||||
| `oauthService` | (none — `addons.bridge` + `audit.bridge` only) | (none) | nest/oauth/oauth-api.controller.ts, nest/oauth/oauth.service.ts | mcp/index.ts, mcp/oauthProvider.ts |
|
||||
| `oidcService` | apiKeyCrypto, authService, tripMembership | (none) | nest/oidc/oidc.service.ts | (none) |
|
||||
| `passkeyService` | authService, webauthnConfig | (none) | nest/admin/admin.service.ts, nest/auth/passkey.controller.ts | (none) |
|
||||
| `passwordPolicy` | (none) | adminService, authService | (none) | (none) |
|
||||
| `oidcService` | apiKeyCrypto, tripMembership (+ `auth.bridge`) | (none) | nest/oidc/oidc.service.ts | (none) |
|
||||
| `passkeyService` | webauthnConfig (+ `auth.bridge`) | (none) | nest/admin/admin.service.ts, nest/auth/passkey.controller.ts | (none) |
|
||||
| `passwordPolicy` | (none) | adminService | nest/auth/auth.service.ts | (none) |
|
||||
| `placeImage` | (none) | (none) | nest/collections/collections.controller.ts, nest/collections/collections.service.ts, nest/common/place-image-upload.ts, nest/places/places.controller.ts, nest/places/places.service.ts | (none) |
|
||||
| `placePhotoCache` | (none) | (none) | nest/maps/maps.service.ts, nest/places/places.helpers.ts, nest/share/share.service.ts | scheduler.ts (lazy) |
|
||||
| `queryHelpers` | (none) | (none) | nest/assignments/assignments.service.ts, nest/days/days.service.ts, nest/places/places.service.ts, nest/share/share.service.ts | (none) |
|
||||
| `timezoneService` | (none) | airtrail/airtrailMapper | nest/transit/transit-itinerary.helpers.ts, nest/trips/trips.service.ts | (none) |
|
||||
| `tripAccess` | (none) | (none) | nest/booking-import/booking-import.service.ts, nest/budget/budget.service.ts, nest/collab/collab.service.ts, nest/days/day-notes.service.ts, nest/integrations/airtrail-import.controller.ts, nest/packing/packing.service.ts, nest/reservations/reservations.service.ts, nest/todo/todo.service.ts | (none) |
|
||||
| `tripMembership` | (none) | authService, oidcService | nest/plugins/host/plugin-host-deps.factory.ts, nest/trip-invite/trip-invite.service.ts | (none) |
|
||||
| `tripMembership` | (none) | oidcService | nest/auth/auth.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/trip-invite/trip-invite.service.ts | (none) |
|
||||
| `unsplashService` | apiKeyCrypto | (none) | nest/places/places.service.ts, nest/trips/trips.controller.ts, nest/trips/trips.service.ts | (none) |
|
||||
| `userCleanupService` | (none — `budget.bridge`, plugin paths infra only) | adminService, authService | nest/trips/trips.service.ts | (none) |
|
||||
| `userCleanupService` | (none — `budget.bridge`, plugin paths infra only) | adminService | nest/auth/auth.service.ts, nest/trips/trips.service.ts | (none) |
|
||||
| `weatherService` | (none) | (none) | nest/plugins/host/plugin-host-deps.factory.ts, nest/weather/weather.controller.ts, nest/weather/weather.service.ts | mcp/tools/mapsWeather.ts |
|
||||
| `webauthnConfig` | (none) | authService, passkeyService | (none) | (none) |
|
||||
| `webauthnConfig` | (none) | passkeyService | nest/auth/auth.service.ts | (none) |
|
||||
| `wikiService` | (none) | (none) | nest/help/help.controller.ts | (none) |
|
||||
|
||||
## Subdirectory clusters
|
||||
@@ -368,7 +434,7 @@ frontier candidates below can still go any time:
|
||||
|
||||
| Candidate | Why now / why not | Bridge tax (legacy dependents + out-of-container) |
|
||||
|---|---|---|
|
||||
| **authService** | Unblocked by the 2026-08 atlas fold (its atlasService edge became the `atlas.bridge` repoint; permissions already bridged) — the biggest remaining fold (1494 lines, 18 in-container `.mcp.ts` consumers) and the head of the coherence chain auth → admin → oauth | `adminService`, `oidcService`, `passkeyService`; `mcp/index.ts`, `mcp/tools/journey.ts`, `mcp/tools/notifications.ts`, `mcp/tools/transports.ts` |
|
||||
| **oidcService / passkeyService** | Frontier since the 2026-08 auth fold — their `authService` edges became `auth.bridge` repoints, leaving only helpers (apiKeyCrypto/tripMembership, webauthnConfig); both fold into existing thin Nest wrappers (`OidcService` already injects `AuthService`; `PasskeyController` still `import *`s the legacy module). The coherence order rides them with the auth chain, before/with adminService | oidc: none; passkey: none (both are leaves — nothing legacy imports them) |
|
||||
| **oauthService** | Dependency-free since the Phase 0 addons extraction (adminService edge was only `isAddonEnabled` → `addons.bridge`) — but the coherence order keeps it after admin so the `mcp/oauthProvider.ts` merge (`mcp-2`) lands with it | `mcp/index.ts`, `mcp/oauthProvider.ts` |
|
||||
| **weatherService / wikiService / airportService** | Independent leaves; airport has the `db/database.ts` boot lazy-require special case | little / none |
|
||||
|
||||
@@ -376,14 +442,15 @@ frontier candidates below can still go any time:
|
||||
|
||||
- `notificationService` ← notifications cluster (its auditLog edge is now the plain
|
||||
`audit-log.logger` import — gone as a blocker since the 2026-07 Wave-2 pair).
|
||||
- `adminService`/`authService` corner: `authService` is UNBLOCKED since the 2026-08
|
||||
atlas fold (its atlasService edge became the `atlas.bridge` repoint, its permissions
|
||||
edge the `permissions.bridge` repoint); `adminService` ←
|
||||
`authService` + `notificationService`. `oauthService` is dependency-free since the
|
||||
- `adminService` corner: `authService` is DONE (2026-08 — the fold repointed
|
||||
adminService's `resolveAuthToggles` import to `auth.bridge`), so adminService is
|
||||
blocked by its hard `notificationService` import alone (userCleanupService is a
|
||||
helper — never blocks). `oauthService` is dependency-free since the
|
||||
Phase 0 addons extraction (its adminService edge was only `isAddonEnabled`, now
|
||||
`addons.bridge`), but the coherence order stays auth → admin → oauth so the
|
||||
`mcp/oauthProvider.ts` merge (`mcp-2`) lands after admin (oidc/passkey ride auth;
|
||||
permissions done 2026-07, atlas done 2026-08).
|
||||
`mcp/oauthProvider.ts` merge (`mcp-2`) lands after admin (oidc/passkey are
|
||||
frontier-ready bridge consumers now; permissions done 2026-07, atlas + auth done
|
||||
2026-08).
|
||||
- `journeyService` ← `memories/` cluster (which itself touches admin + notificationService) →
|
||||
`journeyShareService` after. Note the place fold added two more in-container
|
||||
journeyService consumers (`places.service.ts`'s hooks and `places.mcp.ts`'s
|
||||
@@ -426,7 +493,14 @@ Wave-2 `permissions` + `auditLog` pair were the first frontier picks — all don
|
||||
`atlas-geo.ts`, the 10-tool registrar + 4 resources onto `atlas.mcp.ts`,
|
||||
the plugin host's 23rd constructor dep, the 2-export `atlas.bridge.ts` for
|
||||
authService, and the DTO ratchet clearing all three allow-list entries)
|
||||
→ `authService` (+ oidc/passkey) → `adminService` → `oauthService`
|
||||
→ `authService` (done 2026-08 — the 1497-line chain opener: the crypto half
|
||||
to the plain `auth.helpers.ts`, the DB half into `AuthService` over
|
||||
DatabaseService + injected Permissions/AtlasService, `atlas.bridge` deleted
|
||||
on schedule, the 8-export `auth.bridge.ts` for the mcp transport + three
|
||||
legacy registrars + admin/oidc/passkey, 15 `*.mcp.ts` demo guards injecting
|
||||
AuthService with `atlas.mcp.ts` as the documented cycle-break exception,
|
||||
and the DTO ratchet clearing all 14 auth allow-list entries)
|
||||
→ oidc/passkey → `adminService` → `oauthService`
|
||||
6. `memories/` cluster → `journeyService` → `journeyShareService`; `collectionsService`
|
||||
(done 2026-08-01 — taken off the frontier ahead of step 3: the 1024-line fold
|
||||
into `CollectionsService`, the 25-tool registrar onto `collections.mcp.ts`,
|
||||
@@ -559,6 +633,47 @@ Wave-2 `permissions` + `auditLog` pair were the first frontier picks — all don
|
||||
addon, so the `when:` gate is parity, not a trailing fix — the gate-asymmetry
|
||||
check is now a per-domain question, not a default.
|
||||
|
||||
- (2026-08-01 regeneration, post auth fold) The frontier row's bridge tax held **exactly**
|
||||
— adminService/oidcService/passkeyService plus the four `mcp/` consumers, all
|
||||
import-path-only repoints — and the "18 in-container `.mcp.ts` consumers" count resolved
|
||||
to 16 files (15 injections + the atlas exception; the row had counted `oidc.service.ts`
|
||||
and the passkey guard among them). Three shapes the graph had not tracked: (a) the fold
|
||||
created the **reverse** of the place fold's cycle — AuthService must inject AtlasService
|
||||
for `getTravelStats`, so `atlas.mcp.ts` cannot inject AuthService and stays on
|
||||
`auth.bridge` (the cycle-break-bridge category now has two members, one per direction);
|
||||
(b) the in-container fan-out was the real cost — 15 modules gained an `AuthModule`
|
||||
import and `tests/helpers/mcp-test-controllers.ts` threads one shared `AuthService`
|
||||
into 15 constructions — a class of diff no bridge column predicts; and (c) two suites
|
||||
held **silently-dead path mocks**: `oidc.e2e.test.ts` mocked `services/authService`
|
||||
which OidcService no longer imports (fixed with an instance spy), and the legacy unit
|
||||
suite's `vi.mock('src/mcp')` never intercepted anything (authService always imported
|
||||
`mcp/sessionManager` directly) — path-mock rot is now a named risk for every remaining
|
||||
fold. Also borne out: moving ~1400 lines under the `src/nest/**` gate dropped its
|
||||
branch coverage below 80% until the fold added AUTH-DB-050…088 — the gate polices
|
||||
relocations, not just new code.
|
||||
|
||||
## Quirks preserved in the auth fold (trailing `fix(server)` candidates)
|
||||
|
||||
The relocation was byte-identical; these verified oddities were carried as-is and await
|
||||
their own fix commit (atlas/collections precedent — parity first, fixes separate):
|
||||
|
||||
1. **`getTravelStats` drops 0-coordinates.** `if (p.lat && p.lng)` skips a place on the
|
||||
equator or prime meridian (the exact `|| null` class the atlas trailing commit fixed
|
||||
in bucket items).
|
||||
2. **`registerUser` multi-writes aren't transactional.** INSERT user → UPDATE
|
||||
invite_tokens → `joinTripAsMember` run statement-by-statement; a mid-sequence throw
|
||||
leaves a user without the invite bookkeeping.
|
||||
3. **`verifyMfaLogin` splices the backup code outside a transaction.** The backup-code
|
||||
UPDATE and the last_login UPDATE are separate statements.
|
||||
4. **`enableMfa` bypasses `getPendingMfaSecret`'s TTL cleanup on failure** — a wrong code
|
||||
leaves the pending secret live for the full 15 min (arguably by design).
|
||||
5. **The two "Password authentication is disabled" strings differ** between login
|
||||
(`… Please sign in with SSO.`) and changePassword (bare) — parity says both stay.
|
||||
6. **`deleteMcpToken` calls `revokeUserSessions` unguarded** while changePassword/
|
||||
resetPassword wrap the same call in try/catch — an inconsistency, not yet a defect.
|
||||
7. **`updateApiKeys` re-selects with `current!` non-null assertions** — a deleted-user
|
||||
race throws instead of 404ing (pre-existing).
|
||||
|
||||
## Quirks fixed after the atlas fold (the trailing `fix(server)` commit)
|
||||
|
||||
The relocation itself was byte-identical; these were then fixed on top, each with a
|
||||
|
||||
Reference in New Issue
Block a user