-- Two constraints the service-level checks need as atomic backstops:
--
-- 1. Partial unique index on (geschichte_id, document_id): the append dedup
--    guard is a check-then-insert (existsByGeschichteIdAndDocumentId), so two
--    concurrent appends of the same document can both pass the pre-check.
--    The index rejects the second INSERT; JourneyItemService.append translates
--    the DataIntegrityViolationException into the same 409
--    JOURNEY_DOCUMENT_ALREADY_ADDED as the friendly pre-check.
--    Partial (WHERE document_id IS NOT NULL) — note-only interludes must not collide.
--
-- 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)
    WHERE document_id IS NOT NULL;

ALTER TABLE journey_items
    ADD CONSTRAINT chk_journey_item_note_length
        CHECK (note IS NULL OR length(note) <= 2000);
