- Kontrolle/Kontrollposition-Modelle: Kontrolle ändert NIEMALS Objektposition.istmenge
(Vier-Kernbegriffe-Tabelle, Prompt 02.9) - reine Erfassung/Snapshot
- Objekt-Sperre (Prompt 02.8): Kontrolle.status='in_bearbeitung' + benutzer_id IST die
Sperre, kein separates Sperr-Modell. Zweiter Zugriff -> 409 mit wer/seit; Übernahme
bricht alte Kontrolle ab (Datensatz bleibt, Prompt 16.6-Analogie) und protokolliert
das Ereignis in einer neuen, minimalen Historie-Tabelle (volle Ausbaustufe Sprint 5)
- Automatische Fehlbestand-Erzeugung bei Ist < Soll (U1), Überbestand erzeugt
ausdrücklich KEINEN Fehlbestand (Prompt 02.4); Korrektur vor Abschluss möglich
(von derselben Kontrolle erzeugter Fehlbestand ist bis zum Abschluss nicht final)
- Abschluss verweigert bei unbestätigten Positionen, liefert deren IDs (U11)
- Abbruch verwirft Kontrollpositionen UND von dieser Kontrolle erzeugte Fehlbestände,
Kontrolle selbst bleibt als Datensatz mit Status "abgebrochen" erhalten (U12)
- Tests: U1, U11, U12, Sperre/409, Übernahme, Fremdzugriff/403, parallele Objekte
Mitarbeiter-UI (PWA-Frontend) ist bewusst noch nicht Teil dieses Commits - eigenes
Techstack-Setup, wird als nächster Schritt separat angegangen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L85hmKbvX7Cqkq47KnQhFt
- Beladungsvorlage/Vorlagenposition-Modelle + Endpunkte: erstellen, neue Version
(Prompt 08 Punkt 4 - alte Version bleibt unverändert lesbar statt überschrieben)
- Objekt-Anlage aus Vorlage: Objektpositionen werden initialisiert, Ist-Menge startet
bei 0 ("nicht kontrolliert", Prompt 09)
- Duplizieren: Struktur/Sollmengen-Override kopiert, Ist-Menge/SN/Ablauf/Charge NICHT,
neuer Code Pflicht (409 bei Kollision)
- Sollmengen-Auflösung (Prompt 10): Override schlägt Vorlagenwert, sonst dynamisch aus
aktueller Vorlagenposition des Objekts
- GET /objekte/code/{code} bewusst vor /objekte/{id} registriert (Routing-Reihenfolge)
- Bugfix: app.models muss vollständig importiert werden (main.py + conftest.py), sonst
schlägt FK-Auflösung zwischen Modellen fehl, die noch von keinem Endpoint berührt
werden (Fund im dritten echten CI-Lauf)
- Tests: U8 (Override schlägt Vorlage), U9 (Duplizieren-Kopierregeln + Code-Konflikt),
U10 (neue Version, alte bleibt lesbar), Rollenrechte
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L85hmKbvX7Cqkq47KnQhFt
Der vorherige Fix (asyncio_default_fixture_loop_scope/asyncio_default_test_loop_scope)
griff nicht - letztere Option existiert in der gepinnten pytest-asyncio-Version
vermutlich noch nicht, Tests liefen weiterhin auf function-scoped Loops während die
Engine session-weit global war. Echte Ursache behoben: db_session erzeugt jetzt eine
frische AsyncEngine pro Test (und disposed sie danach), sodass Engine/Pool immer auf
derselben Loop laufen wie der Test selbst.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L85hmKbvX7Cqkq47KnQhFt
Installer (deploy/):
- install_server.sh: PostgreSQL+nginx auf Debian 13, idempotente Rolle/DB-Anlage,
pgcrypto-Extension, Speicher-Tuning für 4GB-VPS, Zugangsdaten in chmod-600-Datei
statt stdout (postgres-expert/owasp-Review)
- nginx-Template mit Security-Headern + Rate-Limit auf /auth/login
- systemd-Unit-Template mit Sandboxing (NoNewPrivileges/ProtectSystem/PrivateTmp)
Backend-Fixes (fastapi-expert-Review):
- get_db: einheitliche commit/rollback-Konvention statt Endpunkt-Copy-Paste
- Test-Fixtures auf SQLAlchemy-2.0-Savepoint-Pattern umgestellt (join_transaction_mode),
da get_db jetzt selbst committet
- Lifespan-Handler: Startup-Guard gegen JWT-Secret-Platzhalter, engine.dispose() beim Shutdown
- JWT-Payload ohne ungenutztes roles-Claim (Rollen kommen immer frisch aus der DB)
Zusätzlich: Subagenten-Definitionen (~/.claude/agents/) auf lauffähiges Modell fixiert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L85hmKbvX7Cqkq47KnQhFt