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
+44
View File
@@ -369,3 +369,47 @@ async def test_mitarbeiter_cannot_create_fach(client, mitarbeiter_user, admin_us
headers=auth_header(token),
)
assert response.status_code == 403
@pytest.mark.asyncio
async def test_hersteller_modell_lifecycle(client, admin_user, mitarbeiter_user):
"""IDENT-005: Hersteller/Modell-Stammdaten anlegen, per hersteller_id filtern."""
admin_token = await login(client, "admin1")
hersteller = await client.post(
"/api/v1/hersteller", json={"name": "Weinmann"}, headers=auth_header(admin_token)
)
assert hersteller.status_code == 201
hersteller_id = hersteller.json()["id"]
modell = await client.post(
"/api/v1/modelle",
json={"hersteller_id": hersteller_id, "name": "MEDUMAT Standard2"},
headers=auth_header(admin_token),
)
assert modell.status_code == 201
assert modell.json()["hersteller_id"] == hersteller_id
anderer_hersteller = await client.post(
"/api/v1/hersteller", json={"name": "Weinmann"}, headers=auth_header(admin_token)
)
assert anderer_hersteller.status_code == 409
unbekannter_hersteller = await client.post(
"/api/v1/modelle",
json={"hersteller_id": 999999, "name": "Irgendwas"},
headers=auth_header(admin_token),
)
assert unbekannter_hersteller.status_code == 404
mitarbeiter_token = await login(client, "mitarbeiter1")
verweigert = await client.post(
"/api/v1/hersteller", json={"name": "Dräger"}, headers=auth_header(mitarbeiter_token)
)
assert verweigert.status_code == 403
liste = await client.get(
f"/api/v1/modelle?hersteller_id={hersteller_id}", headers=auth_header(mitarbeiter_token)
)
assert len(liste.json()) == 1
assert liste.json()[0]["name"] == "MEDUMAT Standard2"