-- Append-only Audit-Log für jede Scan-Aktion an einer Lieferposition.
--
-- Doppelter Wahrheits-Ansatz:
-- * delivery_items.scan_* = "schnelle Wahrheit" über WIEVIEL (Embedded)
-- * scan_audit            = "lange Wahrheit" über WIE und WANN
--
-- Idempotenz: client_scan_id ist UNIQUE. Schickt die App einen Scan
-- nach Netzfehler erneut, kollidiert sie auf diesem Index — der Server
-- liefert "duplicate" zurück, ohne den embedded scan_state zu verändern.
--
-- Beleg-Bezug wird denormalisiert mitgespeichert: bleibt nachvollziehbar,
-- auch wenn delivery_items irgendwann archiviert oder bereinigt wird.

CREATE TABLE scan_audit (
    id                       UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Idempotenz-Schlüssel vom Client.
    client_scan_id           UUID NOT NULL UNIQUE,

    delivery_item_id         UUID NOT NULL REFERENCES delivery_items(id) ON DELETE CASCADE,

    action                   TEXT NOT NULL
                                CHECK (action IN ('scan','unscan','hold','unhold','remove')),

    -- Signed Delta auf scanned_quantity. +1 / -1 / 0 abhängig vom action.
    delta                    INT  NOT NULL,
    -- Snapshot scanned_quantity nach dieser Aktion (Reports brauchen keinen Replay).
    resulting_quantity       INT  NOT NULL CHECK (resulting_quantity >= 0),
    resulting_status         TEXT NOT NULL
                                CHECK (resulting_status IN ('in_progress','done','held','removed')),

    reason                   TEXT,

    -- Akteur: Personalnummer aus dem JWT (Pflicht).
    -- car_id NULL bis Cars im Backend gemanagt werden.
    actor_personalnummer     BIGINT NOT NULL,
    actor_car_id             UUID,

    -- Zeitpunkt am Client (offline-fähig) + Eingang am Server.
    client_scanned_at        TIMESTAMPTZ NOT NULL,
    server_recorded_at       TIMESTAMPTZ NOT NULL DEFAULT now(),

    -- Denormalisierter ERP-Beleg-Bezug.
    erp_belegart_id          BIGINT NOT NULL,
    erp_belegnummer          TEXT   NOT NULL,
    erp_belegzeilen_nr       INT    NOT NULL,
    erp_komponenten_artikel_nr TEXT
);

CREATE INDEX scan_audit_item     ON scan_audit(delivery_item_id);
CREATE INDEX scan_audit_recorded ON scan_audit(server_recorded_at);
CREATE INDEX scan_audit_actor    ON scan_audit(actor_personalnummer, server_recorded_at);
