From d901d001c777f8ac02b6e1973054fad1e94acecc Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Tue, 25 Aug 2026 00:59:49 +0200 Subject: [PATCH] =?UTF-8?q?fix(i-c):=20Outbox-Cluster=20behoben=20?= =?UTF-8?q?=E2=80=94=20OutboxDelivery-Model=20in=20app/models/outbox.py=20?= =?UTF-8?q?ergaenzt=20(Migration-0075-konform=20inkl.=20uq=5Foutbox=5Fdeli?= =?UTF-8?q?veries=5Fevent=5Fconsumer=20UniqueConstraint);=20Root-Cause:=20?= =?UTF-8?q?create=5Fall-basiertes=20Test-Schema=20fehlte=20die=20Tabelle?= =?UTF-8?q?=20und=20den=20Constraint=20(ON=20CONFLICT=20schlug=20fehl);=20?= =?UTF-8?q?12=20Failures=20=E2=86=92=200;=20Beweistest=20test=5Foutbox+tes?= =?UTF-8?q?t=5Foutbox=5Fphase5=2023/23=20gruen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/outbox.py | 48 +++++++++++++++++++++++++++++++++++++++++++- docs/test-bugs.md | 2 +- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/app/models/outbox.py b/app/models/outbox.py index dd7fe35..833a822 100644 --- a/app/models/outbox.py +++ b/app/models/outbox.py @@ -5,7 +5,7 @@ from __future__ import annotations import uuid from datetime import datetime -from sqlalchemy import DateTime, Integer, String, Text, func +from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, UniqueConstraint, func from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.dialects.postgresql import UUID as PGUUID from sqlalchemy.orm import Mapped, mapped_column @@ -77,3 +77,49 @@ class EventOutbox(Base): failed_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True, ) + + +class OutboxDelivery(Base): + """Per-consumer delivery status for an event_outbox row (Migration 0075). + + Tracks whether each consumer successfully processed an event; an event is + only 'published' when all mandatory deliveries succeed. + """ + + __tablename__ = "outbox_deliveries" + __table_args__ = ( + UniqueConstraint( + "event_id", "consumer_name", + name="uq_outbox_deliveries_event_consumer", + ), + ) + + id: Mapped[uuid.UUID] = mapped_column( + PGUUID(as_uuid=True), primary_key=True, + server_default=func.gen_random_uuid(), + ) + event_id: Mapped[uuid.UUID] = mapped_column( + PGUUID(as_uuid=True), + ForeignKey("event_outbox.id", ondelete="CASCADE"), + nullable=False, + ) + consumer_name: Mapped[str] = mapped_column(String(150), nullable=False) + status: Mapped[str] = mapped_column( + String(30), nullable=False, server_default="pending", + ) + attempt_count: Mapped[int] = mapped_column( + Integer, nullable=False, server_default="0", + ) + next_attempt_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), nullable=True, + ) + last_error: Mapped[str | None] = mapped_column(Text, nullable=True) + processed_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), nullable=True, + ) + created_at: Mapped[datetime] = mapped_column( + DateTime(timezone=True), nullable=False, server_default=func.now(), + ) + updated_at: Mapped[datetime] = mapped_column( + DateTime(timezone=True), nullable=False, server_default=func.now(), + ) diff --git a/docs/test-bugs.md b/docs/test-bugs.md index 8769cdc..1a9a27a 100644 --- a/docs/test-bugs.md +++ b/docs/test-bugs.md @@ -478,7 +478,7 @@ Playwright E2E: 10 passed, 24 failed (BUG-011/012/013 — Mock-Daten und data-te - **Erwartet:** Alle pytest Tests bestehen - **Tatsächlich:** Mehrere Tests fehlgeschlagen (F..F.F..FF, FFFFFFFF) - **Schweregrad:** Medium -- **Status:** ⏳ Nicht gefixt — muss genauer untersuchen welche Tests fehlschlagen +- **Status:** ✅ Teilweise erledigt 2026-08-24 (Block E/I-C): Outbox-Cluster (12 Failures in test_outbox+test_outbox_phase5) BEHOBEN — Root-Cause exakt bewiesen: create_all-basierte Test-Schema fehlte outbox_deliveries-Tabelle UND den uq_outbox_deliveries_event_consumer UniqueConstraint (ON CONFLICT im Produktionscode schlug fehl). Fix: OutboxDelivery-Model in app/models/outbox.py ergänzt (Migration-0075-konform inkl. UniqueConstraint); Beweistest 23/23 grün. Verbleibende Failures anderer Suiten einzeln triagieren. ### BUG-068: Field-Level Permissions nicht implementiert in contacts routes - **Kategorie:** Rechte-System