4 parallele Review-Agenten (Reuse/Simplification/Efficiency/Altitude) gegen den
Diff dieser Session (c7dd47f...HEAD) laufen lassen, echte Funde angewendet:
- lager.py: 5x wiederholtes "db.get(...) or 404 raisen" durch _get_or_404()-
Helper ersetzt
- akte.py: zwei Queries für Geräte-Instanzen (erst Positions-IDs, dann Geräte)
zu einer Query mit Subquery zusammengefasst
- akte.py: manuelle Feld-für-Feld-Rekonstruktion von ObjektRead/HistorieRead
durch model_validate()+model_copy() ersetzt (HistorieRead.benutzer_name
bekommt dafür einen Default, harmlos für den bestehenden Endpunkt)
- vorlagen.py: doppelte "Positionen löschen + flush"-Logik (Vorlage-Löschen
und Positionen-Ersetzen) in loesche_alle_positionen() zusammengeführt
Bewusst nicht angewendet:
- Zentrale Session-Rollback-Vereinheitlichung für die drei Pre-Check-Stellen
(objekte.py Selbstbezug, geraet_instanz.py SN-Duplikat, lager.py Eltern-
Selbstbezug) - der Altitude-Review schlug das vor, aber get_db() rollt in
Produktion bei jeder Exception bereits korrekt zurück (jede Anfrage hat eine
eigene Session); das PendingRollbackError-Problem trat nur in der geteilten
Test-Session auf und wurde bereits gezielt per Pre-Check vermieden - eine
zusätzliche zentrale Rollback-Schicht würde nichts mehr reparieren, was
nicht schon repariert ist.
- Postgres-Cluster-Encoding (template1) auf beiden Hosts fixen, nicht nur in
CI/für die eine migrierte DB - echter Infra-Eingriff, braucht Rücksprache.
- LagerSection.tsx "inkonsistente" Formular-Resets - beim genaueren Hinsehen
gewolltes UX (Ort/Typ bleiben ausgewählt für mehrere Anlagen hintereinander).
140 Tests weiterhin grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
Bisher wurde die Sollmenge einer Objektposition live aus der Vorlagenposition
gelesen (objekt.vorlage_id -> vorlagenposition.sollmenge), Bearbeiten der
Vorlage erzeugte deshalb zwingend eine neue Version - sonst hätte sich jede
Änderung rückwirkend auf alle Objekte ausgewirkt, die diese Vorlage nutzen.
- Neue Spalte objektposition.sollmenge_vorlage (Migration 0020): kopiert die
Sollmenge fest bei Anlage/Duplizieren statt live nachzuschlagen
- sollmenge_effektiv(position) liest jetzt nur noch override/sollmenge_vorlage,
kein DB-Lookup mehr nötig (sollmenge_map() entfernt)
- Neuer Endpoint PUT /vorlagen/{id}/positionen: ersetzt Positionen direkt,
ohne neue Version. Bestehende Objekte unbetroffen, nur neu angelegte nutzen
die aktualisierten Werte (Test: test_aktualisiere_positionen_wirkt_nicht_
rueckwirkend_auf_bestehendes_objekt)
- POST /vorlagen/{id}/neue-version bleibt zusätzlich bestehen (nicht entfernt)
- Frontend: "Neue Version speichern" -> "Positionen speichern" (PUT statt POST)
- 140 Tests grün
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
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