mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 06:26:26 +00:00
fix(journey): a place kept across two days is two days of the journal
The sync engine keyed a skeleton by source_place_id alone, so a stop standing on two days — the city you land in at dusk and walk through the next morning — got one entry on the first of them and nothing on the rest. Key on the day assignment instead. The assignment row rather than the day, because moving a stop updates day_assignments.day_id in place: keyed this way an entry follows the move instead of reading as one stop leaving the plan and another arriving. Existing rows are backfilled to the place's earliest assignment, and reconciliation adopts an unlinked row rather than annotating it out from under its author. Fixes #2329
This commit is contained in:
@@ -4900,6 +4900,50 @@ function runMigrations(db: Database.Database): void {
|
||||
END
|
||||
`);
|
||||
},
|
||||
|
||||
/*
|
||||
* A journal skeleton belongs to a day, not just to a place (#2329).
|
||||
*
|
||||
* The sync engine keyed a skeleton by `source_place_id` alone, so the same
|
||||
* place standing on two days — the city you land in at dusk and walk through
|
||||
* the next morning, the hotel you sleep in three nights — produced one entry
|
||||
* on the first of them and nothing on the rest. There was nowhere to put the
|
||||
* second evening's photographs but the first evening's entry.
|
||||
*
|
||||
* The assignment row, not the day, is the missing half of that key: moving a
|
||||
* stop to another day updates `day_assignments.day_id` in place, so keying on
|
||||
* the assignment lets an entry follow the move the way it always has, while
|
||||
* still telling two days of the same place apart.
|
||||
*
|
||||
* Deliberately no REFERENCES clause. Unassigning a stop has to leave the id
|
||||
* stale rather than NULL, because reconciliation reads a key that no longer
|
||||
* matches as "this stop left the plan" — which is what happened — and a NULL
|
||||
* would be indistinguishable from a row this migration could not resolve. The
|
||||
* id is safe to dangle: `day_assignments.id` is AUTOINCREMENT, so it is never
|
||||
* handed out twice.
|
||||
*
|
||||
* Existing rows are backfilled to the place's earliest assignment, which is
|
||||
* the one the old engine would have picked, so reconciliation matches what is
|
||||
* already there instead of writing a duplicate beside it.
|
||||
*/
|
||||
() => {
|
||||
db.exec('ALTER TABLE journey_entries ADD COLUMN source_assignment_id INTEGER');
|
||||
db.exec(`
|
||||
UPDATE journey_entries
|
||||
SET source_assignment_id = (
|
||||
SELECT da.id
|
||||
FROM day_assignments da
|
||||
JOIN days d ON d.id = da.day_id
|
||||
WHERE da.place_id = journey_entries.source_place_id
|
||||
ORDER BY d.day_number ASC, d.date ASC, da.order_index ASC, da.id ASC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE source_place_id IS NOT NULL
|
||||
`);
|
||||
db.exec(
|
||||
'CREATE INDEX IF NOT EXISTS idx_journey_entries_source_assignment ON journey_entries(source_place_id, source_assignment_id)',
|
||||
);
|
||||
},
|
||||
];
|
||||
|
||||
if (currentVersion < migrations.length) {
|
||||
|
||||
Reference in New Issue
Block a user