assign broadcast, unassign did not, so the place stayed on the Plan tab until
a manual refresh. It emits the same event as the REST route now. createPlace,
updatePlace and deletePlace in the same file had the identical gap.
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.