Swap the factory's six tripService imports for the injected TripsService; delete services/tripService.ts and the collab/vacay bridges with it; prune the days/budget bridges to their surviving exports; update the migration docs and regenerate migration-graph.md.
Nest services inject RealtimeService (call-time delegation to the
websocket module, DatabaseService pattern) instead of importing
broadcast/broadcastToUser globals. Zero behavior change; test edits
are constructor-arg additions plus RealtimeModule in e2e harness
imports only.
Folds the 626-line services/reservationService.ts into the DI-native
ReservationsService — byte-identical SQL, statuses, bodies, error strings
and broadcasts; the legacy file is deleted.
- reservations.mcp.ts: the 5 legacy tools (create/update/delete_reservation,
reorder_reservations, link_hotel_accommodation) + the trip-reservations
resource move to the decorator registry (identical names, schemas,
annotations, error strings, broadcasts); the canWrite/canRead registration
gates become declarative access markers. Legacy registrar and resource
entries removed.
- reservations.bridge.ts: 9 legacy-named exports + 3 type re-exports for the
outside-container consumers (tripService, airtrail import/sync, the
still-legacy transit + transports registrars, transitItineraryService's
type-only import).
- notifyBookingChange folds to the legacy (tripId, actorId) signature; the
controller passes user.id and the plugin-host factory drops its last
plain-function reservation import for a private method over the injected
service (constructor unchanged).
- TripsService and BookingImportService inject ReservationsService instead of
importing legacy functions.
- Tests: reservations.service.test.ts rewritten as a real-SQL suite
(RESV-SVC-001..030, RES-TRAV-001..005 moved verbatim,
RESV-BRIDGE-001..009 pinning the bridge); both e2e suites converted to the
DI-native pattern; path mocks repointed to the bridge or constructor stubs;
tools-reservations kept and extended with the moved resource cases.
Quirks preserved on purpose (parity first — see the follow-up fix commit):
the raw-accommodation_id metadata-sync gate, the un-transactioned
multi-statement writes, the truthy updatePositions dayId check, the
empty-string COALESCE keeps, and the TEXT accommodation_id normalization.
Folds the legacy services/fileService.ts into the DI-native FilesService
(injected DatabaseService, byte-identical SQL). Load-time constants move to
files.constants.ts; files.bridge.ts survives with a single export for the
request-time getAllowedExtensions read the module-scope multer configs need
outside DI. TripsService and PluginHostDepsFactory inject FilesService.
Also rides the nestjs-zod ratchet (FileUploadDto/FileUpdateDto/FileLinkDto
over the @trek/shared contracts, FilesController entries dropped from the
body-contract allow-list) and fixes the verified legacy quirks: file-link
insert failures now surface instead of being swallowed, updateFile coerces
an empty-string description to NULL like createFile, and formatFile's
misleading optional trip_id annotation is gone.
Folds the legacy services/settingsService SQL into the Nest SettingsService
(byte-identical statements; BEGIN/COMMIT blocks become db.transaction()).
AdminService and ShareService inject it; llm-config.resolver becomes the
injectable LlmConfigResolver (SettingsService + DatabaseService), injected by
LlmParseService and PluginHostDepsFactory. No MCP surface, no bridge.
Whole-file commit, so this also carries the post-migration quirk fixes that
live in the same files: null serializes as '' (a stored "null" leaked out of
getDecryptedUserSetting as the literal string), bulk upserts skip the masked
sentinel (mirroring the single-upsert no-op) and return the written count.
Unit suite moved to tests/unit/nest with SET-SVC-001..026 preserved,
027..030 pin the fixes; settings/admin e2e converted to DI-native.