CI-Bugfixes aus erstem echten Testlauf: bcrypt-Pin, pytest-asyncio Loop-Scope
CI / backend-tests (push) Failing after 35s

1. passlib 1.7.4 liest bcrypt.__about__.__version__, das bcrypt>=4.1 entfernt hat -
   führte zu irreführendem "password cannot be longer than 72 bytes". Fix: bcrypt<4.1 pinnen.
2. Globaler async engine in conftest.py + pytest-asyncios default function-scoped Event-Loop
   führte zu "Task ... attached to a different loop" bei asyncpg. Fix: session-weiter
   Loop-Scope für Fixtures und Tests.

Erster echter CI-Lauf (Host-Runner ohne Docker) kam bis zum pytest-Schritt durch,
beide Fehler dort aufgedeckt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L85hmKbvX7Cqkq47KnQhFt
This commit is contained in:
2026-09-03 23:24:40 +02:00
co-authored by Claude Sonnet 5
parent d7d61f2013
commit 8f9bd57c5b
4 changed files with 54 additions and 3 deletions
+41
View File
@@ -0,0 +1,41 @@
import enum
import uuid
from datetime import date
from decimal import Decimal
from sqlalchemy import Date, ForeignKey, Numeric, String, UniqueConstraint
from sqlalchemy.dialects.postgresql import ENUM as PgEnum, UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base import Base
class ObjektpositionStatus(str, enum.Enum):
aktiv = "aktiv"
entfernt = "entfernt"
objektposition_status_pg = PgEnum(
ObjektpositionStatus, name="objektposition_status", create_type=False
)
class Objektposition(Base):
"""Prompt 10: Ist-Bestand + individuelle Soll-Abweichung je Objekt/Material.
UUID-PK (Karte 13: sync-relevant, siehe ergebnisse/20_datenbank_schema.md)."""
__tablename__ = "objektposition"
__table_args__ = (UniqueConstraint("objekt_id", "material_id"),)
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
objekt_id: Mapped[int] = mapped_column(ForeignKey("objekt.id"), nullable=False)
material_id: Mapped[int] = mapped_column(ForeignKey("material.id"), nullable=False)
# NULL = Sollmenge folgt dynamisch der aktuellen Vorlagenposition (Prompt 10).
sollmenge_override: Mapped[Decimal | None] = mapped_column(Numeric)
ist_status: Mapped[ObjektpositionStatus] = mapped_column(
objektposition_status_pg, nullable=False, default=ObjektpositionStatus.aktiv
)
istmenge: Mapped[Decimal] = mapped_column(Numeric, nullable=False, default=0)
seriennummer: Mapped[str | None] = mapped_column(String)
ablaufdatum: Mapped[date | None] = mapped_column(Date)
chargennummer: Mapped[str | None] = mapped_column(String)