feat(identity): IDENT-005 Hersteller/Modell-Stammdaten
CI / backend-tests (push) Failing after 2m16s
CI / frontend-build (push) Successful in 26s

Neue Tabellen hersteller/modell (Migration 0030), CRUD-Endpunkte
(/hersteller, /modelle) nach bestehendem Kategorie-Muster, inkl. 409 bei
Duplikaten (IntegrityError abgefangen wie in personal.py). geraet_instanz
bekommt optionales modell_id-Feld - verknüpft eine konkrete Geräteinstanz
(mit Seriennummer, IDENT-004) mit ihrem Hersteller/Modell.

Ergänzt Material.hersteller (bleibt unverändert als Freitext) um eine
normalisierte Variante gezielt für Geräte mit Seriennummer - keine
Datenmigration bestehender Freitext-Werte (Scope dieser Kachel).

Bewusst kein neues Admin-UI-Screen für die Pflege (Scope-Grenze der
Kachel) - Hersteller/Modell aktuell nur über die API verwaltbar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
2026-09-08 14:51:15 +02:00
co-authored by Claude Sonnet 5
parent ae09433c11
commit 2dd7e574e6
12 changed files with 249 additions and 6 deletions
+4 -2
View File
@@ -25,7 +25,9 @@ class SeriennummerBereitsVergebenError(Exception):
pass
async def erstelle(db: AsyncSession, *, objektposition_id, seriennummer: str) -> GeraetInstanz:
async def erstelle(
db: AsyncSession, *, objektposition_id, seriennummer: str, modell_id: int | None = None
) -> GeraetInstanz:
# Explizit vorab prüfen statt sich auf den UNIQUE-Constraint zu verlassen:
# ein Flush-Fehlschlag hier hinterlässt die Session im Zustand DEACTIVE
# (SQLAlchemy 2.0), was in einer über mehrere Requests geteilten Session
@@ -39,7 +41,7 @@ async def erstelle(db: AsyncSession, *, objektposition_id, seriennummer: str) ->
)
if result.scalar_one_or_none() is not None:
raise SeriennummerBereitsVergebenError
instanz = GeraetInstanz(objektposition_id=objektposition_id, seriennummer=seriennummer)
instanz = GeraetInstanz(objektposition_id=objektposition_id, seriennummer=seriennummer, modell_id=modell_id)
db.add(instanz)
await db.flush()
return instanz