From 98805f596a51cac7b0168736b36b1f46c94a7ab0 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 11 Jun 2026 07:51:20 +0200 Subject: [PATCH] fix(db): make V74 self-healing on databases that ran the base branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dedup DELETE + note clamp before the DDL so the unique index and CHECK cannot fail mid-migration (failed Flyway row -> backend boot loop) on a DB that served writes under the old code (no dedup guard, 5000-char notes). No-ops on a clean database. Note: this changes V74's checksum — dev databases that already ran V74 on this branch need 'flyway repair' (or a fresh DB). CI and prod run from V73 or clean and are unaffected. Review round 3: Tobias (1). Co-Authored-By: Claude Fable 5 --- ...rney_items_document_dedup_and_note_length.sql | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/backend/src/main/resources/db/migration/V74__journey_items_document_dedup_and_note_length.sql b/backend/src/main/resources/db/migration/V74__journey_items_document_dedup_and_note_length.sql index 5939d2c6..062e0d6d 100644 --- a/backend/src/main/resources/db/migration/V74__journey_items_document_dedup_and_note_length.sql +++ b/backend/src/main/resources/db/migration/V74__journey_items_document_dedup_and_note_length.sql @@ -11,6 +11,22 @@ -- 2. CHECK on note length: mirrors chk_text_length on transcription_blocks. -- 2000 is the spec'd limit — JourneyItemService.MAX_NOTE_LENGTH, the frontend -- maxlength, and the i18n error message all agree (#793). +-- +-- Defensive cleanup first: a database that served writes on the base branch +-- (no dedup guard, MAX_NOTE_LENGTH = 5000) can hold rows that would make the +-- DDL below fail mid-migration and boot-loop the backend on a failed Flyway +-- row. Both statements are no-ops on a clean database. + +-- Keep the earliest-positioned row of each (geschichte, document) pair. +DELETE FROM journey_items a + USING journey_items b + WHERE a.geschichte_id = b.geschichte_id + AND a.document_id = b.document_id + AND a.document_id IS NOT NULL + AND a.position > b.position; + +-- Clamp over-long notes written under the old 5000-char service limit. +UPDATE journey_items SET note = left(note, 2000) WHERE length(note) > 2000; CREATE UNIQUE INDEX uq_journey_items_geschichte_document ON journey_items (geschichte_id, document_id)