feat(identity): IDENT-005 Hersteller/Modell-Stammdaten
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:
@@ -187,3 +187,34 @@ async def test_defekt_kann_fehlbestand_erzeugen(client, objekt_mit_position, mat
|
||||
"/api/v1/fehlbestaende", params={"objekt_id": objekt.id}, headers=auth_header(token)
|
||||
)
|
||||
assert len(nachher.json()) == anzahl_vorher + 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_geraet_kann_mit_hersteller_modell_verknuepft_werden(
|
||||
client, objekt_mit_position, materialverantwortlicher_user, admin_user
|
||||
):
|
||||
"""IDENT-005: optionales modell_id-Feld verweist auf Hersteller/Modell-Stammdaten."""
|
||||
objekt, _material = objekt_mit_position
|
||||
admin_token = await login(client, "admin1")
|
||||
token = await login(client, "materialverantwortlicher1")
|
||||
|
||||
hersteller = await client.post(
|
||||
"/api/v1/hersteller", json={"name": "Weinmann"}, headers=auth_header(admin_token)
|
||||
)
|
||||
modell = await client.post(
|
||||
"/api/v1/modelle",
|
||||
json={"hersteller_id": hersteller.json()["id"], "name": "MEDUMAT Standard2"},
|
||||
headers=auth_header(admin_token),
|
||||
)
|
||||
modell_id = modell.json()["id"]
|
||||
|
||||
positionen = await client.get(f"/api/v1/objekte/{objekt.id}/positionen", headers=auth_header(token))
|
||||
position_id = positionen.json()[0]["id"]
|
||||
|
||||
erstellt = await client.post(
|
||||
f"/api/v1/objektpositionen/{position_id}/geraete",
|
||||
json={"seriennummer": "SN-MODELL-1", "modell_id": modell_id},
|
||||
headers=auth_header(token),
|
||||
)
|
||||
assert erstellt.status_code == 201
|
||||
assert erstellt.json()["modell_id"] == modell_id
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user