mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
f0e1da2d81
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.
30 lines
1.5 KiB
TypeScript
30 lines
1.5 KiB
TypeScript
import type { Database } from 'better-sqlite3';
|
|
import { AccommodationsService } from '../../src/nest/accommodations/accommodations.service';
|
|
import { AssignmentsService } from '../../src/nest/assignments/assignments.service';
|
|
import { DatabaseService } from '../../src/nest/database/database.service';
|
|
import { JourneyDomainService } from '../../src/nest/journey/journey-domain.service';
|
|
import { PermissionsService } from '../../src/nest/permissions/permissions.service';
|
|
import { QueryHelpersService } from '../../src/nest/query-helpers/query-helpers.service';
|
|
import { RealtimeService } from '../../src/nest/realtime/realtime.service';
|
|
import { TrekPhotosRepository } from '../../src/nest/photos/trek-photos.repository';
|
|
|
|
/**
|
|
* AccommodationsService over a test connection.
|
|
*
|
|
* Booking a night also writes the day stop that puts it on the route, through a
|
|
* real AssignmentsService rather than a stub: the stop is a row these cases read
|
|
* back, and it has to come out of the same connection. Five collaborators deep is
|
|
* why this is a helper and not five copies across the suites.
|
|
*/
|
|
export function makeAccommodationsService(conn: Database): AccommodationsService {
|
|
const dbs = new DatabaseService(conn);
|
|
const permissions = new PermissionsService(dbs);
|
|
const realtime = new RealtimeService();
|
|
const assignments = new AssignmentsService(
|
|
dbs, permissions, realtime,
|
|
new QueryHelpersService(dbs),
|
|
new JourneyDomainService(dbs, realtime, new TrekPhotosRepository(dbs)),
|
|
);
|
|
return new AccommodationsService(dbs, permissions, realtime, assignments);
|
|
}
|