-- FDN-04: Postgres-Jobqueue fuer asynchrone Verarbeitung (OCR, Konvertierung, -- Indexierung, Exporte) — kein Redis/AMQP, dasselbe Muster wie das -- projektweite Postgres-Jobqueue-Konzept (siehe SKALIERUNGSKONZEPT.md). -- Laeuft in der DB EINES Mandanten (Modell C, siehe Core TEN-01). CREATE TABLE processing_jobs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), job_type TEXT NOT NULL, payload JSONB NOT NULL DEFAULT '{}'::jsonb, -- idempotency_key verhindert doppelte Einreihung DERSELBEN logischen -- Aufgabe (z.B. "ocr:") — NULL erlaubt mehrere Zeilen ohne -- Dedup-Anspruch (Standard-Postgres-Verhalten: NULL ist nie gleich NULL -- im UNIQUE-Index). idempotency_key TEXT UNIQUE, status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'succeeded', 'failed', 'dead_letter')), attempts INT NOT NULL DEFAULT 0, max_attempts INT NOT NULL DEFAULT 5, available_at TIMESTAMPTZ NOT NULL DEFAULT now(), locked_at TIMESTAMPTZ, locked_by TEXT, last_error TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- Deckt genau die Zugriffsmuster von Dequeue (status+available_at) und der -- Stale-Lock-Wiedervorlage (status+locked_at) ab. CREATE INDEX idx_processing_jobs_pending ON processing_jobs (available_at) WHERE status = 'pending'; CREATE INDEX idx_processing_jobs_processing ON processing_jobs (locked_at) WHERE status = 'processing'; CREATE INDEX idx_processing_jobs_job_type ON processing_jobs (job_type);