docs: tick reservationService in migrate.md and refresh the migration graph

- nest/README.md: reservations joins the DI-native list; recipe history gains
  the residue-fold paragraph; next up is dayService per the dependency-honest
  order.
- migrate.md: wave-4 entry ticked, with the migration-graph correction borne
  out — reservationService imported neither budgetService nor dayService.
- migration-graph.md: regenerated for the post-fold import graph (row/node
  removed, frontier and order updated, dayService is the next pick).
- plugins/DI-MIGRATION.md: the factory's last plain-function reservation
  import is drained.
This commit is contained in:
jubnl
2026-07-27 19:47:09 +02:00
parent 203d67c45f
commit c7dde2af2e
2 changed files with 42 additions and 38 deletions
+3 -1
View File
@@ -24,7 +24,9 @@ Wave 3 — domain services with existing modules, low fan-in
Wave 4 — the coupled cluster (order matters here)
8. dayService → budgetService → reservationService in that order: reservations depend on both (budget-item linking, day resolution), so migrating the dependencies first lets ReservationsService inject the finished versions instead of
importing legacy functions.
importing legacy functions. — **Correction (migration-graph.md, borne out by the migration): the claimed ordering constraint doesn't exist at the service layer.** reservationService (done 2026-07) imported neither budgetService nor
dayService; the budget/day coupling lives in the Nest wrapper's budget-sync seam and the MCP registrars, which keep their legacy imports until those domains migrate. Reservations went first as the frontier residue fold; dayService and
budgetService follow.
9. Then placeService (7 internal deps, mostly on things migrated by now) and tripService (10 deps — the biggest hub; last in this wave, since nearly everything it needs will already be injectable).
Wave 5 — the heavyweights, last
+39 -37
View File
@@ -1,7 +1,8 @@
# Legacy `src/services/` dependency graph
Generated from the actual imports in `server/src` on **2026-07-27** (after the vacayService
migration — the first frontier pick following collabService's Wave-3 completion). Regenerate any
Generated from the actual imports in `server/src` on **2026-07-27** (after the
reservationService migration — the residue fold, step 1 of the dependency-honest order below).
Regenerate any
time — the extraction script only parses `from './x'` /
`from '../services/x'` imports:
@@ -24,11 +25,11 @@ How to read it:
## Node classification
- **Already DI-native (legacy file deleted):** tags, categories, todo, packing, day-notes,
trip-invite, assignments, share, settings, files, collab, vacay.
trip-invite, assignments, share, settings, files, collab, vacay, reservations.
- **Domain migration targets** (the wave material): adminService, airportService, atlasService,
authService, backupService, budgetService, collectionsService, dayService,
journeyService, journeyShareService, mapsService, notificationService, oauthService,
oidcService, passkeyService, placeService, reservationService, transitService,
oidcService, passkeyService, placeService, transitService,
transitItineraryService, tripService, weatherService, wikiService.
- **Cross-cutting Wave-2 targets:** permissions (17 nest consumers), auditLog (13 nest + 5
out-of-container), tripAccess (delete, don't migrate).
@@ -52,7 +53,6 @@ flowchart TD
subgraph frontier["READY FRONTIER (no unmigrated domain deps)"]
atlas[atlasService]:::ready
reserv[reservationService]:::ready
day[dayService]:::ready
weather[weatherService]:::ready
airport["airportService (boot special case)"]:::ready
@@ -82,13 +82,13 @@ flowchart TD
fx[exchangeRateService]:::infra
cleanup[userCleanupService]:::infra
trip --> budget & day & reserv & cleanup
trip --> budget & day & cleanup
budget --> fx
cleanup --> budget
place --> maps
maps --> notifCluster
transit --> maps
transitItin --> reserv & transit
transitItin --> transit
notifSvc --> notifCluster & auditLog
admin --> auth & notifSvc & cleanup
auth --> atlas & permissions
@@ -115,14 +115,14 @@ journey/memories corner tangle with the admin corner.)
| `apiKeyCrypto` | (none) | adminService, airtrail/airtrailService, authService, llmConfig, mapsService, memories/helpersService, memories/immichService, memories/photoResolverService, memories/synologyService, memories/unifiedService, notifications, oidcService, unsplashService | 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 |
| `atlasService` | (none) | authService | nest/atlas/atlas.service.ts, nest/plugins/host/plugin-host-deps.factory.ts | mcp/resources.ts, mcp/tools/atlas.ts |
| `auditLog` | (none) | airtrail/airtrailService, airtrail/airtrailSync, memories/immichService, notificationService, notifications, oauthService | nest/admin/admin.controller.ts, nest/auth/auth-public.controller.ts, nest/auth/auth.controller.ts, nest/auth/passkey.controller.ts, nest/backup/backup.controller.ts, nest/integrations/airtrail.controller.ts, nest/memories/immich.controller.ts, nest/oauth/oauth-api.controller.ts, nest/oauth/oauth-public.controller.ts, nest/plugins/plugin-runtime.service.ts, nest/plugins/plugins.controller.ts, nest/trip-invite/trip-invite.controller.ts, nest/trips/trips.controller.ts | index.ts, mcp/index.ts, mcp/oauthProvider.ts, middleware/globalMiddleware.ts, scheduler.ts |
| `authService` | apiKeyCrypto, atlasService, avatarUrl, demo, distanceService, ephemeralTokens, mfaCrypto, passwordPolicy, permissions, tripMembership, userCleanupService, webauthnConfig | adminService, oidcService, passkeyService | nest/assignments/assignments.mcp.ts, nest/auth/auth.service.ts, nest/auth/passkey-enabled.guard.ts, nest/collab/collab.mcp.ts, nest/days/day-notes.mcp.ts, nest/oidc/oidc.service.ts, nest/packing/packing.mcp.ts, nest/tags/tags.mcp.ts, nest/todo/todo.mcp.ts, nest/vacay/vacay.mcp.ts | mcp/index.ts, mcp/tools/atlas.ts, mcp/tools/budget.ts, mcp/tools/collections.ts, mcp/tools/days.ts, mcp/tools/journey.ts, mcp/tools/notifications.ts, mcp/tools/places.ts, mcp/tools/reservations.ts, mcp/tools/transit.ts, mcp/tools/transports.ts, mcp/tools/trips.ts |
| `avatarUrl` | (none) | adminService, authService, budgetService, inAppNotifications, journeyService, reservationService, tripService | nest/collab/collab.service.ts, nest/files/files.service.ts, nest/packing/packing.service.ts | (none) |
| `authService` | apiKeyCrypto, atlasService, avatarUrl, demo, distanceService, ephemeralTokens, mfaCrypto, passwordPolicy, permissions, tripMembership, userCleanupService, webauthnConfig | adminService, oidcService, passkeyService | nest/assignments/assignments.mcp.ts, nest/auth/auth.service.ts, nest/auth/passkey-enabled.guard.ts, nest/collab/collab.mcp.ts, nest/days/day-notes.mcp.ts, nest/oidc/oidc.service.ts, nest/packing/packing.mcp.ts, nest/reservations/reservations.mcp.ts, nest/tags/tags.mcp.ts, nest/todo/todo.mcp.ts, nest/vacay/vacay.mcp.ts | mcp/index.ts, mcp/tools/atlas.ts, mcp/tools/budget.ts, mcp/tools/collections.ts, mcp/tools/days.ts, mcp/tools/journey.ts, mcp/tools/notifications.ts, mcp/tools/places.ts, mcp/tools/transit.ts, mcp/tools/transports.ts, mcp/tools/trips.ts |
| `avatarUrl` | (none) | adminService, authService, budgetService, inAppNotifications, journeyService, tripService | nest/collab/collab.service.ts, nest/files/files.service.ts, nest/packing/packing.service.ts, nest/reservations/reservations.service.ts | (none) |
| `backupService` | permissions | (none) | nest/backup/backup.controller.ts, nest/backup/backup.service.ts | (none) |
| `budgetService` | avatarUrl, exchangeRateService, tripAccess | tripService, userCleanupService | nest/booking-import/booking-import.service.ts, nest/budget/budget.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/reservations/reservations.service.ts, nest/trips/trips.service.ts | mcp/resources.ts, mcp/tools/budget.ts, mcp/tools/reservations.ts, mcp/tools/transports.ts, mcp/tools/trips.ts |
| `budgetService` | avatarUrl, exchangeRateService, tripAccess | tripService, userCleanupService | nest/booking-import/booking-import.service.ts, nest/budget/budget.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/reservations/reservations.mcp.ts, nest/reservations/reservations.service.ts, nest/trips/trips.service.ts | mcp/resources.ts, mcp/tools/budget.ts, mcp/tools/transports.ts, mcp/tools/trips.ts |
| `collectionsService` | permissions, placeImage | (none) | nest/collections/collections.service.ts, nest/plugins/host/plugin-host-deps.factory.ts | mcp/tools/collections.ts |
| `conflictResult` | (none) | placeService | nest/packing/packing.controller.ts, nest/packing/packing.service.ts, nest/places/places.controller.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) |
| `dayService` | queryHelpers, tripAccess | tripService | nest/assignments/assignments.mcp.ts, nest/days/days.controller.ts, nest/days/days.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/reservations/accommodations.service.ts, nest/trips/trips.service.ts | mcp/resources.ts, mcp/tools/days.ts, mcp/tools/reservations.ts, mcp/tools/transit.ts, mcp/tools/transports.ts |
| `dayService` | queryHelpers, tripAccess | tripService | nest/assignments/assignments.mcp.ts, nest/days/days.controller.ts, nest/days/days.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/reservations/accommodations.service.ts, nest/reservations/reservations.mcp.ts, nest/trips/trips.service.ts | mcp/resources.ts, mcp/tools/days.ts, mcp/tools/transit.ts, mcp/tools/transports.ts |
| `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, transitItineraryService | (none) | (none) |
| `ephemeralTokens` | (none) | authService | nest/files/files.service.ts | index.ts, websocket.ts |
@@ -148,13 +148,12 @@ journey/memories corner tangle with the admin corner.)
| `placePhotoCache` | (none) | mapsService, placeService | nest/maps/maps.service.ts, nest/share/share.service.ts | scheduler.ts |
| `placeService` | conflictResult, kmlImport, placeEnrichment, placeImage, placePhotoCache, queryHelpers, unsplashService | (none) | nest/booking-import/booking-import.service.ts, nest/places/places.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/trips/trips.service.ts | mcp/resources.ts, mcp/tools/days.ts, mcp/tools/places.ts |
| `queryHelpers` | (none) | dayService, placeService | nest/assignments/assignments.service.ts, nest/share/share.service.ts | (none) |
| `reservationService` | avatarUrl, tripAccess | airtrail/airtrailImport, airtrail/airtrailSync, transitItineraryService, tripService | nest/booking-import/booking-import.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/reservations/reservations.service.ts, nest/trips/trips.service.ts | mcp/resources.ts, mcp/tools/reservations.ts, mcp/tools/transit.ts, mcp/tools/transports.ts |
| `timezoneService` | (none) | airtrail/airtrailMapper, transitItineraryService, tripService | (none) | (none) |
| `transitItineraryService` | distanceService, reservationService, timezoneService, transitService | (none) | (none) | mcp/tools/transit.ts |
| `transitItineraryService` | distanceService, timezoneService, transitService (+ type-only `reservations.bridge`) | (none) | (none) | mcp/tools/transit.ts |
| `transitService` | mapsService, notifications | transitItineraryService | nest/transit/transit.controller.ts | mcp/tools/transit.ts |
| `tripAccess` | (none) | budgetService, dayService, reservationService, tripService | nest/booking-import/booking-import.service.ts, nest/collab/collab.service.ts, nest/integrations/airtrail-import.controller.ts, nest/packing/packing.service.ts, nest/todo/todo.service.ts | (none) |
| `tripAccess` | (none) | budgetService, dayService, tripService | nest/booking-import/booking-import.service.ts, nest/collab/collab.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) |
| `tripService` | avatarUrl, budgetService, dayService, reservationService, timezoneService, tripAccess, userCleanupService | (none) | nest/feeds/feeds.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/trips/trips.controller.ts, nest/trips/trips.service.ts | mcp/resources.ts, mcp/tools/budget.ts, mcp/tools/prompts.ts, mcp/tools/trips.ts |
| `tripService` | avatarUrl, budgetService, dayService, timezoneService, tripAccess, userCleanupService (+ `reservations.bridge`) | (none) | nest/feeds/feeds.service.ts, nest/plugins/host/plugin-host-deps.factory.ts, nest/trips/trips.controller.ts, nest/trips/trips.service.ts | mcp/resources.ts, mcp/tools/budget.ts, mcp/tools/prompts.ts, mcp/tools/trips.ts |
| `unsplashService` | apiKeyCrypto | placeService | nest/trips/trips.controller.ts, nest/trips/trips.service.ts | (none) |
| `userCleanupService` | budgetService | adminService, authService, tripService | (none) | (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 |
@@ -170,8 +169,8 @@ journey/memories corner tangle with the admin corner.)
`photoResolverService` is the seam `journeyService` consumes; `thumbnailService → adminService`
and `synology/unified → notificationService` couple this cluster to the admin corner.
- **`airtrail/`**: `airtrailClient` (base) ← mapper ← service ← import/sync; `import`/`sync`
consume `reservationService` and `adminService` — repoint (or bridge) when reservations
migrates.
consume `adminService` and (since the 2026-07 reservations fold) the
`nest/reservations/reservations.bridge` instead of the deleted `reservationService`.
## Decoding "what's next"
@@ -179,8 +178,7 @@ journey/memories corner tangle with the admin corner.)
| Candidate | Why now / why not | Bridge tax (legacy dependents + out-of-container) |
|---|---|---|
| **reservationService** ← pick | Nest `ReservationsService` is already DI-native — this is folding the residue (`listReservations`, `notifyBookingChange`, …); unblocks `transitItineraryService` + `airtrail/` repoints | `tripService`, `transitItineraryService`, `airtrail/{import,sync}`; 4 mcp files |
| **dayService** | Heavy factory import; unblocks accommodations seam | `tripService`; 5 mcp files |
| **dayService** ← pick | Heavy factory import; unblocks the accommodations seam (`nest/reservations/accommodations.service.ts` still delegates to it) | `tripService`; 4 mcp files |
| **atlasService** | Zero deps, but its legacy dependent is `authService` (Wave-5) → bridge lives long | `authService`; `mcp/tools/atlas.ts`, `mcp/resources.ts` |
| **weatherService / wikiService / airportService** | Independent leaves; airport has the `db/database.ts` boot lazy-require special case | little / none |
| **permissions / auditLog (Wave 2)** | Zero deps, giant fan-in (17 / 13 nest consumers) — pure leverage, parallelizable with any domain migration | mcp `_shared.ts`; index/scheduler/middleware for auditLog |
@@ -188,13 +186,14 @@ journey/memories corner tangle with the admin corner.)
**Blocked, and by what (shortest unblock path):**
- `budgetService` ← `exchangeRateService` (itself zero-dep — one prep hop, or fold it in).
- `tripService` (the hub) ← budget + day + reservation (+ `userCleanupService`
→ budget; collab and vacay are done — their edges are now the `collab.bridge` /
`vacay.bridge` repoints). Migrating the
three remaining frontier/near-frontier domains **is** the tripService unblock.
- `tripService` (the hub) ← budget + day (+ `userCleanupService`
→ budget; collab, vacay and reservations are done — their edges are now the
`collab.bridge` / `vacay.bridge` / `reservations.bridge` repoints). Migrating the
two remaining frontier/near-frontier domains **is** the tripService unblock.
- `placeService` ← `mapsService` (via placeEnrichment) ← notifications cluster.
- `notificationService` ← notifications cluster + `auditLog` (Wave 2 first).
- `transitItineraryService` ← `reservationService` + `transitService` (← mapsService).
- `transitItineraryService` ← `transitService` (← mapsService) — its reservation edge is now
the `reservations.bridge` repoint (type-only).
- `adminService`/`oauthService`/`authService` corner: `authService` ← `atlasService` +
`permissions`; `adminService` ← `authService` + `notificationService`; `oauthService` ←
`adminService`. Order inside the corner: permissions → atlas → auth → admin → oauth
@@ -205,23 +204,26 @@ journey/memories corner tangle with the admin corner.)
(owns the closeDb/reinitialize lifecycle).
**Dependency-honest order** (each step's deps are already done at that point;
`vacayService` was step 1 — done 2026-07, after `collabService` completed Wave 3):
`vacayService` and `reservationService` (the residue fold) were the first two frontier
picks — both done 2026-07, after `collabService` completed Wave 3):
1. `reservationService` (residue fold)
2. `dayService`
3. `permissions` + `auditLog` (Wave 2 — anytime, ideally early and in parallel)
4. `exchangeRateService` fold → `budgetService` (then `userCleanupService` is free)
5. `tripService` — all remaining domain edges + userCleanup now gone
6. notifications cluster → `notificationService`
7. `mapsService` → `transitService` → `placeService` → `transitItineraryService`
8. `atlasService` → `authService` (+ oidc/passkey) → `adminService` → `oauthService`
9. `memories/` cluster → `journeyService` → `journeyShareService`; `collectionsService`
10. Independent any time: `weatherService`, `wikiService`, `airportService` (move the
1. `dayService`
2. `permissions` + `auditLog` (Wave 2 — anytime, ideally early and in parallel)
3. `exchangeRateService` fold → `budgetService` (then `userCleanupService` is free)
4. `tripService` — all remaining domain edges + userCleanup now gone
5. notifications cluster → `notificationService`
6. `mapsService` → `transitService` → `placeService` → `transitItineraryService`
7. `atlasService` → `authService` (+ oidc/passkey) → `adminService` → `oauthService`
8. `memories/` cluster → `journeyService` → `journeyShareService`; `collectionsService`
9. Independent any time: `weatherService`, `wikiService`, `airportService` (move the
boot backfill into Nest bootstrap when you do it); `backupService` last
**Corrections to `migrate.md` this graph surfaced:**
- `reservationService` does **not** import `budgetService`/`dayService` — the claimed Wave-4
ordering constraint doesn't exist at the service layer; its legacy remainder is frontier-ready.
- `reservationService` did **not** import `budgetService`/`dayService` — the claimed Wave-4
ordering constraint didn't exist at the service layer; its legacy remainder was
frontier-ready. **Borne out by the 2026-07 fold**: the budget/day coupling lives in the
Nest wrapper's budget-sync seam and the MCP surface, which keep their legacy imports until
those domains migrate.
- Every remaining Wave-3/4 domain has legacy `tripService` as a dependent — each migration
before tripService pays a small bridge/repoint tax the files migration didn't have.