feat(zustaendigkeit): ZUST-004 Runde 6 - kennzahlen/ablaufdaten/wartungen
Letzte dashboard-nahen Objekt-bezogenen Endpunkte ohne Standort-Filter geschlossen: kennzahlen() (vier Fehlbestand-Zählungen + Objekte-Gesamtzahl), bevorstehende_ablaufdaten(), alle_faelligen_wartungen() bekommen optionales sichtbare_standort_ids. Hintergrund-Job wartung_benachrichtigung.py ruft weiterhin ohne Filter auf. bevorstehende_qualifikationsablaeufe() bleibt bewusst unangetastet - rein Personal-bezogen, kein Objekt-/Standort-Konzept. Damit ist ZUST-004 für alle Objekt-bezogenen Endpunkte durchgezogen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VDMvneg6wKfXdXvTYNd3dN
This commit is contained in:
1 parent
9084e6c9d7
commit
b68314a06d
6 files changed
+229
-30
No files matched your search
@@ -16078,3 +16078,108 @@ Keine Commits in dieser Session.
|
||||
- backend/tests/test_zust004_standort_sichtbarkeit.py | 11 ++++++++---
|
||||
|
||||
---
|
||||
## 2026-09-14 23:31 – 23:37 (5m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** asb-material
|
||||
|
||||
### Commits
|
||||
- 9084e6c feat(zustaendigkeit): ZUST-004 Runde 5 - Lagerort mit echtem Standort verknüpft
|
||||
|
||||
### Geänderte Dateien
|
||||
- DEVLOG.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- arbeitskacheln/17_zustaendigkeit.md | 34 ++++++++++++++++++--------
|
||||
- backend/alembic/versions/0060_lagerort_standort_id.py | 28 +++++++++++++++++++++
|
||||
- backend/app/api/v1/endpoints/lager.py | 31 ++++++++++++++++++++---
|
||||
- backend/app/models/lager.py | 11 ++++++++-
|
||||
- backend/app/schemas/lager.py | 3 +++
|
||||
- backend/app/services/lager.py | 29 +++++++++++++++++++++-
|
||||
- backend/tests/test_zust004_standort_sichtbarkeit.py | 57 ++++++++++++++++++++++++++++++++++++++++++
|
||||
- frontend/src/api/types.ts | 1 +
|
||||
- frontend/src/pages/AdminPage.tsx | 4 ++-
|
||||
- frontend/src/pages/admin/LagerSection.tsx | 41 ++++++++++++++++++++++++++++---
|
||||
|
||||
---
|
||||
## 2026-09-14 23:40 – 23:41 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** nexarch
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- DEVLOG.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- arbeitskacheln/17_zustaendigkeit.md | 34 ++++++++++++++++++--------
|
||||
- backend/alembic/versions/0060_lagerort_standort_id.py | 28 +++++++++++++++++++++
|
||||
- backend/app/api/v1/endpoints/lager.py | 31 ++++++++++++++++++++---
|
||||
- backend/app/models/lager.py | 11 ++++++++-
|
||||
- backend/app/schemas/lager.py | 3 +++
|
||||
- backend/app/services/lager.py | 29 +++++++++++++++++++++-
|
||||
- backend/tests/test_zust004_standort_sichtbarkeit.py | 57 ++++++++++++++++++++++++++++++++++++++++++
|
||||
- frontend/src/api/types.ts | 1 +
|
||||
- frontend/src/pages/AdminPage.tsx | 4 ++-
|
||||
- frontend/src/pages/admin/LagerSection.tsx | 41 ++++++++++++++++++++++++++++---
|
||||
|
||||
---
|
||||
## 2026-09-14 23:49 – 23:50 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** asb-material
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- DEVLOG.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- arbeitskacheln/17_zustaendigkeit.md | 34 ++++++++++++++++++--------
|
||||
- backend/alembic/versions/0060_lagerort_standort_id.py | 28 +++++++++++++++++++++
|
||||
- backend/app/api/v1/endpoints/lager.py | 31 ++++++++++++++++++++---
|
||||
- backend/app/models/lager.py | 11 ++++++++-
|
||||
- backend/app/schemas/lager.py | 3 +++
|
||||
- backend/app/services/lager.py | 29 +++++++++++++++++++++-
|
||||
- backend/tests/test_zust004_standort_sichtbarkeit.py | 57 ++++++++++++++++++++++++++++++++++++++++++
|
||||
- frontend/src/api/types.ts | 1 +
|
||||
- frontend/src/pages/AdminPage.tsx | 4 ++-
|
||||
- frontend/src/pages/admin/LagerSection.tsx | 41 ++++++++++++++++++++++++++++---
|
||||
|
||||
---
|
||||
## 2026-09-14 23:50 – 23:52 (1m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** vsb-talk
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- DEVLOG.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- arbeitskacheln/17_zustaendigkeit.md | 34 ++++++++++++++++++--------
|
||||
- backend/alembic/versions/0060_lagerort_standort_id.py | 28 +++++++++++++++++++++
|
||||
- backend/app/api/v1/endpoints/lager.py | 31 ++++++++++++++++++++---
|
||||
- backend/app/models/lager.py | 11 ++++++++-
|
||||
- backend/app/schemas/lager.py | 3 +++
|
||||
- backend/app/services/lager.py | 29 +++++++++++++++++++++-
|
||||
- backend/tests/test_zust004_standort_sichtbarkeit.py | 57 ++++++++++++++++++++++++++++++++++++++++++
|
||||
- frontend/src/api/types.ts | 1 +
|
||||
- frontend/src/pages/AdminPage.tsx | 4 ++-
|
||||
- frontend/src/pages/admin/LagerSection.tsx | 41 ++++++++++++++++++++++++++++---
|
||||
|
||||
---
|
||||
## 2026-09-14 23:52 – 23:52 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** asb-material
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- DEVLOG.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- arbeitskacheln/17_zustaendigkeit.md | 34 ++++++++++++++++++--------
|
||||
- backend/alembic/versions/0060_lagerort_standort_id.py | 28 +++++++++++++++++++++
|
||||
- backend/app/api/v1/endpoints/lager.py | 31 ++++++++++++++++++++---
|
||||
- backend/app/models/lager.py | 11 ++++++++-
|
||||
- backend/app/schemas/lager.py | 3 +++
|
||||
- backend/app/services/lager.py | 29 +++++++++++++++++++++-
|
||||
- backend/tests/test_zust004_standort_sichtbarkeit.py | 57 ++++++++++++++++++++++++++++++++++++++++++
|
||||
- frontend/src/api/types.ts | 1 +
|
||||
- frontend/src/pages/AdminPage.tsx | 4 ++-
|
||||
- frontend/src/pages/admin/LagerSection.tsx | 41 ++++++++++++++++++++++++++++---
|
||||
|
||||
---
|
||||
@@ -204,11 +204,7 @@ war die Vorgängerlücke, diese hier ist die zweite gefundene Lücke).
|
||||
`bevorstehende_prueftermine()` bekommen optionales
|
||||
`sichtbare_standort_ids`, `None` = unrestricted - `readiness_snapshot.py`
|
||||
ruft weiterhin ohne Filter auf, der Snapshot-Job kennt kein Nutzer-
|
||||
Konzept). **Bewusst NICHT eingeschränkt:** `kennzahlen()`,
|
||||
`bevorstehende_ablaufdaten()`, `alle_faelligen_wartungen()` (dashboard-
|
||||
weit), `bevorstehende_qualifikationsablaeufe()` (Personal-bezogen, kein
|
||||
Objekt-/Standort-Konzept) - eigene Follow-up-Runde bei Bedarf, gleiche
|
||||
"kein Big-Bang"-Linie.
|
||||
Konzept).
|
||||
**Runde 5 (2026-09-14): Lagerbewegungen/Lagerplätze-Blockade aufgehoben.**
|
||||
`Lagerort` bekommt ein neues, nullable `standort_id`-Feld (Migration
|
||||
`0060_lagerort_standort_id.py`), das NUR fachlich sinnvoll an einem
|
||||
@@ -236,6 +232,18 @@ war die Vorgängerlücke, diese hier ist die zweite gefundene Lücke).
|
||||
`test_dashboard_einsatzbereitschaft_und_prueftermine_standort_eingeschraenkt`,
|
||||
`test_lagerplaetze_und_bestand_standort_eingeschraenkt`
|
||||
in `backend/tests/test_zust004_standort_sichtbarkeit.py`.
|
||||
**Runde 6 (2026-09-14): letzte dashboard-nahen Lücken geschlossen.**
|
||||
`kennzahlen()` (alle vier Fehlbestand-Zählungen + Objekte-Gesamtzahl über
|
||||
Join auf `Objekt`), `bevorstehende_ablaufdaten()`,
|
||||
`alle_faelligen_wartungen()` bekommen ebenfalls optionales
|
||||
`sichtbare_standort_ids` - `wartung_benachrichtigung.py` (Hintergrund-Job)
|
||||
ruft weiterhin ohne Filter auf. **Bewusst weiterhin NICHT eingeschränkt:**
|
||||
`bevorstehende_qualifikationsablaeufe()` - rein Personal-/Benutzer-
|
||||
bezogen (Qualifikationsablauf einer Person), kein Objekt-/Standort-Konzept,
|
||||
für das ZUST-004 überhaupt greifen könnte. Damit ist ZUST-004 für alle
|
||||
Objekt-bezogenen Endpunkte durchgezogen. Test:
|
||||
`test_dashboard_kennzahlen_ablaufdaten_wartungen_standort_eingeschraenkt`
|
||||
in `backend/tests/test_zust004_standort_sichtbarkeit.py`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -30,16 +30,25 @@ _verantwortliche = require_roles(
|
||||
|
||||
|
||||
@router.get("/dashboard/kennzahlen", response_model=KennzahlenRead)
|
||||
async def hole_kennzahlen(db: AsyncSession = Depends(get_db), _=Depends(_verantwortliche)) -> KennzahlenRead:
|
||||
async def hole_kennzahlen(
|
||||
db: AsyncSession = Depends(get_db), current_user=Depends(_verantwortliche)
|
||||
) -> KennzahlenRead:
|
||||
"""Prompt 12.1: Zielgruppe Materialverantwortlicher/Leitungsverantwortlicher/
|
||||
Administration. Filterung nach Zuständigkeitsbereich (Karte 04) folgt später,
|
||||
V1 zeigt globale Zahlen für diese Rollen."""
|
||||
return KennzahlenRead(**await kennzahlen(db))
|
||||
Administration. ZUST-004-Erweiterung (2026-09-14, Nutzer-Entscheidung):
|
||||
berücksichtigt jetzt die Standort-Sichtbarkeit - ursprüngliche "V1 zeigt
|
||||
globale Zahlen"-Festlegung bewusst aufgehoben, gleiche Linie wie
|
||||
einsatzbereitschaft()/prueftermine()."""
|
||||
sichtbare = await sichtbare_standort_ids(db, current_user.id)
|
||||
return KennzahlenRead(**await kennzahlen(db, sichtbare))
|
||||
|
||||
|
||||
@router.get("/dashboard/ablaufdaten", response_model=list[AblaufdatumRead])
|
||||
async def hole_ablaufdaten(db: AsyncSession = Depends(get_db), _=Depends(_verantwortliche)) -> list[AblaufdatumRead]:
|
||||
return [AblaufdatumRead(**eintrag) for eintrag in await bevorstehende_ablaufdaten(db)]
|
||||
async def hole_ablaufdaten(
|
||||
db: AsyncSession = Depends(get_db), current_user=Depends(_verantwortliche)
|
||||
) -> list[AblaufdatumRead]:
|
||||
sichtbare = await sichtbare_standort_ids(db, current_user.id)
|
||||
eintraege = await bevorstehende_ablaufdaten(db, sichtbare)
|
||||
return [AblaufdatumRead(**eintrag) for eintrag in eintraege]
|
||||
|
||||
|
||||
@router.get("/dashboard/einsatzbereitschaft", response_model=EinsatzbereitschaftRead)
|
||||
@@ -71,12 +80,15 @@ async def hole_prueftermine(
|
||||
|
||||
@router.get("/dashboard/faellige-wartungen", response_model=list[FaelligeWartungRead])
|
||||
async def hole_faellige_wartungen_global(
|
||||
db: AsyncSession = Depends(get_db), _=Depends(_verantwortliche)
|
||||
db: AsyncSession = Depends(get_db), current_user=Depends(_verantwortliche)
|
||||
) -> list[FaelligeWartungRead]:
|
||||
"""NOTIF-003: globale Dashboard-Kachel "Fällige Wartungen" - ergänzt die
|
||||
bereits bestehende Objekt-bezogene Sicht (MAINT-002,
|
||||
/objekte/{id}/faellige-wartungen) um eine Übersicht über alle Objekte."""
|
||||
return [FaelligeWartungRead(**eintrag) for eintrag in await alle_faelligen_wartungen(db)]
|
||||
/objekte/{id}/faellige-wartungen) um eine Übersicht über alle Objekte.
|
||||
ZUST-004-Erweiterung: Standort-Sichtbarkeit wie bei kennzahlen()."""
|
||||
sichtbare = await sichtbare_standort_ids(db, current_user.id)
|
||||
eintraege = await alle_faelligen_wartungen(db, sichtbare)
|
||||
return [FaelligeWartungRead(**eintrag) for eintrag in eintraege]
|
||||
|
||||
|
||||
@router.get("/dashboard/qualifikationsablaeufe", response_model=list[QualifikationsablaufRead])
|
||||
|
||||
@@ -24,33 +24,62 @@ OFFEN_STATI = (FehlbestandStatus.offen, FehlbestandStatus.in_bearbeitung, Fehlbe
|
||||
STANDARD_WARNZEITRAUM_TAGE = 30
|
||||
|
||||
|
||||
async def kennzahlen(db: AsyncSession) -> dict:
|
||||
async def kennzahlen(db: AsyncSession, sichtbare_standort_ids: set[int] | None = None) -> dict:
|
||||
"""ZUST-004-Erweiterung (2026-09-14, gleiche Nutzer-Entscheidung wie bei
|
||||
einsatzbereitschaft()): `sichtbare_standort_ids=None` = unrestricted
|
||||
(bewusste Abkehr von der ursprünglichen "V1 zeigt globale Zahlen"-
|
||||
Festlegung)."""
|
||||
jetzt = datetime.now(timezone.utc)
|
||||
|
||||
result = await db.execute(select(func.count()).select_from(Fehlbestand).where(Fehlbestand.status.in_(OFFEN_STATI)))
|
||||
fehlbestand_stmt = select(func.count()).select_from(Fehlbestand).where(Fehlbestand.status.in_(OFFEN_STATI))
|
||||
if sichtbare_standort_ids is not None:
|
||||
fehlbestand_stmt = fehlbestand_stmt.join(Objekt, Objekt.id == Fehlbestand.objekt_id).where(
|
||||
Objekt.standort_id.in_(sichtbare_standort_ids)
|
||||
)
|
||||
result = await db.execute(fehlbestand_stmt)
|
||||
anzahl_offen = result.scalar_one()
|
||||
|
||||
result = await db.execute(
|
||||
select(func.count(func.distinct(MindermengenGenehmigung.fehlbestand_id))).where(
|
||||
MindermengenGenehmigung.status == MindermengeStatus.aktiv
|
||||
)
|
||||
genehmigt_stmt = select(func.count(func.distinct(MindermengenGenehmigung.fehlbestand_id))).where(
|
||||
MindermengenGenehmigung.status == MindermengeStatus.aktiv
|
||||
)
|
||||
if sichtbare_standort_ids is not None:
|
||||
genehmigt_stmt = (
|
||||
genehmigt_stmt.join(Fehlbestand, Fehlbestand.id == MindermengenGenehmigung.fehlbestand_id)
|
||||
.join(Objekt, Objekt.id == Fehlbestand.objekt_id)
|
||||
.where(Objekt.standort_id.in_(sichtbare_standort_ids))
|
||||
)
|
||||
result = await db.execute(genehmigt_stmt)
|
||||
anzahl_genehmigt = result.scalar_one()
|
||||
|
||||
result = await db.execute(
|
||||
erledigt_stmt = (
|
||||
select(func.count())
|
||||
.select_from(Fehlbestand)
|
||||
.where(Fehlbestand.status == FehlbestandStatus.erledigt, Fehlbestand.erledigt_am >= jetzt - timedelta(days=7))
|
||||
)
|
||||
if sichtbare_standort_ids is not None:
|
||||
erledigt_stmt = erledigt_stmt.join(Objekt, Objekt.id == Fehlbestand.objekt_id).where(
|
||||
Objekt.standort_id.in_(sichtbare_standort_ids)
|
||||
)
|
||||
result = await db.execute(erledigt_stmt)
|
||||
anzahl_kuerzlich_erledigt = result.scalar_one()
|
||||
|
||||
result = await db.execute(select(func.count(func.distinct(Fehlbestand.objekt_id))).where(Fehlbestand.status.in_(OFFEN_STATI)))
|
||||
problematisch_stmt = select(func.count(func.distinct(Fehlbestand.objekt_id))).where(
|
||||
Fehlbestand.status.in_(OFFEN_STATI)
|
||||
)
|
||||
if sichtbare_standort_ids is not None:
|
||||
problematisch_stmt = problematisch_stmt.join(Objekt, Objekt.id == Fehlbestand.objekt_id).where(
|
||||
Objekt.standort_id.in_(sichtbare_standort_ids)
|
||||
)
|
||||
result = await db.execute(problematisch_stmt)
|
||||
anzahl_problematische_objekte = result.scalar_one()
|
||||
|
||||
result = await db.execute(select(func.count()).select_from(Objekt))
|
||||
objekte_stmt = select(func.count()).select_from(Objekt)
|
||||
if sichtbare_standort_ids is not None:
|
||||
objekte_stmt = objekte_stmt.where(Objekt.standort_id.in_(sichtbare_standort_ids))
|
||||
result = await db.execute(objekte_stmt)
|
||||
anzahl_objekte_gesamt = result.scalar_one()
|
||||
|
||||
ablaufdaten_liste = await bevorstehende_ablaufdaten(db)
|
||||
ablaufdaten_liste = await bevorstehende_ablaufdaten(db, sichtbare_standort_ids)
|
||||
|
||||
return {
|
||||
"anzahl_offener_fehlbestaende": anzahl_offen,
|
||||
@@ -71,16 +100,20 @@ def _ablauf_status(ablaufdatum: date, warnzeitraum_tage: int, heute: date) -> tu
|
||||
return "gueltig", verbleibende_tage
|
||||
|
||||
|
||||
async def bevorstehende_ablaufdaten(db: AsyncSession) -> list[dict]:
|
||||
async def bevorstehende_ablaufdaten(db: AsyncSession, sichtbare_standort_ids: set[int] | None = None) -> list[dict]:
|
||||
"""Prompt 14.5: nur bald_ablaufend/abgelaufen, sortiert nach verbleibenden Tagen
|
||||
aufsteigend (dringendste zuerst). "gueltig" gehört nicht in diese Liste."""
|
||||
aufsteigend (dringendste zuerst). "gueltig" gehört nicht in diese Liste.
|
||||
ZUST-004-Erweiterung: `sichtbare_standort_ids=None` = unrestricted."""
|
||||
heute = datetime.now(timezone.utc).date()
|
||||
result = await db.execute(
|
||||
stmt = (
|
||||
select(Objektposition, Material, Objekt)
|
||||
.join(Material, Objektposition.material_id == Material.id)
|
||||
.join(Objekt, Objektposition.objekt_id == Objekt.id)
|
||||
.where(Objektposition.ablaufdatum.is_not(None))
|
||||
)
|
||||
if sichtbare_standort_ids is not None:
|
||||
stmt = stmt.where(Objekt.standort_id.in_(sichtbare_standort_ids))
|
||||
result = await db.execute(stmt)
|
||||
eintraege = []
|
||||
for objektposition, material, objekt in result.all():
|
||||
warnzeitraum = material.warnzeitraum_tage or STANDARD_WARNZEITRAUM_TAGE
|
||||
|
||||
@@ -255,11 +255,17 @@ async def faellige_wartungen_fuer_objekt(db: AsyncSession, objekt: Objekt) -> li
|
||||
return ergebnisse
|
||||
|
||||
|
||||
async def alle_faelligen_wartungen(db: AsyncSession) -> list[dict]:
|
||||
async def alle_faelligen_wartungen(db: AsyncSession, sichtbare_standort_ids: set[int] | None = None) -> list[dict]:
|
||||
"""NOTIF-003: globale Sicht über alle Objekte für Dashboard-Kachel und
|
||||
Benachrichtigungs-Prüflauf - iteriert `faellige_wartungen_fuer_objekt` je
|
||||
Objekt (keine bestehende Aggregation vorhanden), filtert auf faellig=True."""
|
||||
objekte = (await db.execute(select(Objekt))).scalars().all()
|
||||
Objekt (keine bestehende Aggregation vorhanden), filtert auf faellig=True.
|
||||
ZUST-004-Erweiterung: `sichtbare_standort_ids=None` = unrestricted - der
|
||||
Benachrichtigungs-Prüflauf (wartung_benachrichtigung.py) ruft weiterhin
|
||||
ohne Filter auf, kein Nutzer-Konzept im Hintergrund-Job."""
|
||||
stmt = select(Objekt)
|
||||
if sichtbare_standort_ids is not None:
|
||||
stmt = stmt.where(Objekt.standort_id.in_(sichtbare_standort_ids))
|
||||
objekte = (await db.execute(stmt)).scalars().all()
|
||||
ergebnisse: list[dict] = []
|
||||
for objekt in objekte:
|
||||
for eintrag in await faellige_wartungen_fuer_objekt(db, objekt):
|
||||
|
||||
@@ -408,6 +408,41 @@ async def test_lagerplaetze_und_bestand_standort_eingeschraenkt(
|
||||
assert einlagern_verboten.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_dashboard_kennzahlen_ablaufdaten_wartungen_standort_eingeschraenkt(
|
||||
client, admin_user, materialverantwortlicher_user, standort_factory, objekt_factory
|
||||
):
|
||||
"""ZUST-004 Runde 6: kennzahlen()/bevorstehende_ablaufdaten()/
|
||||
alle_faelligen_wartungen() waren die letzten dashboard-nahen Funktionen
|
||||
ohne Standort-Filter - Nutzer-Entscheidung, ursprüngliche "V1 zeigt
|
||||
globale Zahlen"-Festlegung endgültig aufgehoben."""
|
||||
standort_a = await standort_factory("Standort A13")
|
||||
standort_b = await standort_factory("Standort B13")
|
||||
await objekt_factory(name="Objekt A13", code="ZUST4-A13", standort=standort_a)
|
||||
await objekt_factory(name="Objekt B13", code="ZUST4-B13", standort=standort_b)
|
||||
|
||||
admin_token = await login(client, "admin1")
|
||||
unbeschraenkt = await client.get("/api/v1/dashboard/kennzahlen", headers=auth_header(admin_token))
|
||||
gesamt_vorher = unbeschraenkt.json()["anzahl_objekte_gesamt"]
|
||||
assert gesamt_vorher >= 2
|
||||
|
||||
await client.put(
|
||||
f"/api/v1/benutzer/{materialverantwortlicher_user.id}/standorte",
|
||||
json={"standort_ids": [standort_a.id]},
|
||||
headers=auth_header(admin_token),
|
||||
)
|
||||
token = await login(client, "materialverantwortlicher1")
|
||||
|
||||
eingeschraenkt = await client.get("/api/v1/dashboard/kennzahlen", headers=auth_header(token))
|
||||
assert eingeschraenkt.json()["anzahl_objekte_gesamt"] < gesamt_vorher
|
||||
|
||||
ablaufdaten = await client.get("/api/v1/dashboard/ablaufdaten", headers=auth_header(token))
|
||||
assert ablaufdaten.status_code == 200
|
||||
|
||||
wartungen = await client.get("/api/v1/dashboard/faellige-wartungen", headers=auth_header(token))
|
||||
assert wartungen.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_standort_zugriff_setzen_nur_admin(client, mitarbeiter_user, mitarbeiter2_user):
|
||||
token = await login(client, "mitarbeiter1")
|
||||
|
||||
Reference in new issue
Block a user