Files
TREK/server/src/db/repositories/TourWaypoints.repository.ts
T
Maurice 7ca7dfd555 Merge dev into fix/prettier
Brings in the Tours addon and the MikroORM follow-ups. Conflicts were
resolved to dev's content, then every file dev brought in was run through
prettier and eslint --fix so the branch stays uniformly formatted.
2026-10-07 15:43:13 +02:00

78 lines
2.6 KiB
TypeScript

import type { TourWaypoints } from '../entities/TourWaypoints.entity';
import { TrekRepository } from './_shared/trek-repository';
/** One saved routing control point of a tour, in route order. */
export interface TourWaypointRow {
lat: number;
lng: number;
role: 'start' | 'via' | 'end';
sequence: number;
}
/** {@link TourWaypointRow} plus the tour it belongs to, as the trip copy reads it. */
export interface TourWaypointWithPlaceRow extends TourWaypointRow {
place_id: number;
}
interface TourWaypointsKyselyDB {
tour_waypoints: {
id: number;
place_id: number;
lat: number;
lng: number;
role: TourWaypointRow['role'];
sequence: number;
};
places: { id: number; trip_id: number };
}
/**
* `tour_waypoints` — the start, via and end points the route editor saved
* for a tour, so reopening it restores the controls rather than only the
* derived line. Rows hang off `tours(place_id)` and go with the tour.
*/
export class TourWaypointsRepository extends TrekRepository<TourWaypoints> {
private db() {
return this.kysely<TourWaypointsKyselyDB>();
}
/** TW1 — `SELECT lat, lng, role, sequence FROM tour_waypoints WHERE place_id = ? ORDER BY sequence`. */
async listForPlace(place_id: number): Promise<TourWaypointRow[]> {
return await this.db()
.selectFrom('tour_waypoints')
.select(['lat', 'lng', 'role', 'sequence'])
.where('place_id', '=', place_id)
.orderBy('sequence', 'asc')
.execute();
}
/** TW2 — every waypoint of a trip's tours, for the trip copy to remap by place. */
async listForTrip(trip_id: number): Promise<TourWaypointWithPlaceRow[]> {
return await this.db()
.selectFrom('tour_waypoints as tw')
.innerJoin('places as p', 'p.id', 'tw.place_id')
.select(['tw.place_id', 'tw.lat', 'tw.lng', 'tw.role', 'tw.sequence'])
.where('p.trip_id', '=', trip_id)
.orderBy('tw.place_id', 'asc')
.orderBy('tw.sequence', 'asc')
.execute();
}
/**
* TW3 — `INSERT INTO tour_waypoints (place_id, lat, lng, role, sequence)
* VALUES (...)` for each point. The caller owns the transaction: a create
* writes the tour first, an edit clears the old points first.
*/
async insertForPlace(place_id: number, waypoints: readonly TourWaypointRow[]): Promise<void> {
if (waypoints.length === 0) return;
await this.insertMany(
waypoints.map((w) => ({ place: place_id, lat: w.lat, lng: w.lng, role: w.role, sequence: w.sequence })),
);
}
/** TW4 — `DELETE FROM tour_waypoints WHERE place_id = ?`. */
async deleteForPlace(place_id: number): Promise<void> {
await this.nativeDelete({ place: place_id });
}
}