mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
feat(accommodations): put a booked night on its check-in day
A road-trip stop is a day assignment: the rail, the server-side plan and the map all build their stops from day_assignments and only look the stay up afterwards, to hang check-in and check-out on one. A stay written without an assignment was therefore invisible to every routing surface, so a hotel entered in the day planner never reached the road-trip view and had to be entered a second time as an ordinary place. The road-trip side has always written both halves in one go; this is the day planner catching up, in the domain that writes the stay. Booking a night now also assigns its place to the check-in day, inside the transaction that already writes the stay and its partner hotel reservation, and types the place as a hotel stop when it carries no type of its own, so it reads exactly like a night booked in the road trip. Only the check-in day gets a stop; the later nights ride on the stay row. A place already planned for that day gets no second stop and the booking claims none, so cancelling it cannot delete a stop somebody placed by hand. Moving the booking moves its own stop, deleting it takes its own stop back, and a trip re-date carries it along with the stay. All four write surfaces (REST, plugin RPC and both MCP tools) run the same write and announce the same events; the answers carry the stop too, because the broadcast skips the socket that sent the request. New nullable day_assignments.accommodation_id marks a stop as a booking's own. It stays NULL for every existing row on purpose: everything planned before this was planned by hand, and no backfill rewrites a finished trip. A stay booked earlier picks up its stop the next time somebody saves it. The booking form keeps writing stays on its own: that surface is gated on reservation_edit and the day stop is day_edit work.
This commit is contained in:
@@ -66,6 +66,7 @@ import { UserCleanupService } from '../../../src/nest/auth/user-cleanup.service'
|
||||
import { TripMembersService } from '../../../src/nest/trip-members/trip-members.service';
|
||||
import { TripReadModelService } from '../../../src/nest/trip-read-model/trip-read-model.service';
|
||||
import { AccommodationsService } from '../../../src/nest/accommodations/accommodations.service';
|
||||
import { makeAccommodationsService } from '../../helpers/accommodations-service';
|
||||
import { MapsService } from '../../../src/nest/maps/maps.service';
|
||||
import { QueryHelpersService } from '../../../src/nest/query-helpers/query-helpers.service';
|
||||
import { notificationsStub } from '../../helpers/notifications';
|
||||
@@ -93,7 +94,7 @@ const placesSvc = new PlacesService(
|
||||
new JourneyDomainService(dbs(), new RealtimeService(), new TrekPhotosRepository(dbs())),
|
||||
makeStorageFixture('').storage,
|
||||
);
|
||||
const accommodationsSvc = new AccommodationsService(dbs(), new PermissionsService(dbs()), new RealtimeService());
|
||||
const accommodationsSvc = makeAccommodationsService(testDb);
|
||||
const membersSvc = new TripMembersService(dbs(), budgetSvc, new UserCleanupService(dbs(), budgetSvc), new PermissionsService(dbs()), new RealtimeService(), notificationsStub());
|
||||
|
||||
const buildReadModel = (database: DatabaseService, roster: TripMembersService = membersSvc) =>
|
||||
|
||||
Reference in New Issue
Block a user