Objekttyp.ist_zugfahrzeug (Migration 0011) grenzt die Fahrzeug-Zuordnung serverseitig auf tatsächliche Zugfahrzeuge ein (422 bei Verstoß), Frontend filtert die Fahrzeug-Dropdowns entsprechend. Neue Dashboard-Endpunkte /dashboard/einsatzbereitschaft und /dashboard/prueftermine plus DashboardPage mit drei Kacheln (Einsatzbereitschaft, Prüftermine, Ablaufdaten). Aktive Mindermengen-Genehmigung zählt als "eingeschränkt einsatzbereit", nicht als voll einsatzbereit (U2/Karte 08). Neue FehlbestandListePage: Fehlbestände eigenständig nachfüllen/Mindermenge genehmigen, ohne komplette Kontrolle des Objekts zu starten (Backend existierte bereits, nur das Frontend fehlte). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
57 lines
2.3 KiB
Python
57 lines
2.3 KiB
Python
from fastapi import APIRouter, Depends
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.api.deps import require_roles
|
|
from app.db.session import get_db
|
|
from app.models.auth import RolleTyp
|
|
from app.schemas.dashboard import (
|
|
AblaufdatumRead,
|
|
EinsatzbereitschaftRead,
|
|
KennzahlenRead,
|
|
PrueftermineintragRead,
|
|
)
|
|
from app.services.dashboard import (
|
|
bevorstehende_ablaufdaten,
|
|
bevorstehende_prueftermine,
|
|
einsatzbereitschaft,
|
|
kennzahlen,
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
_verantwortliche = require_roles(
|
|
RolleTyp.administration, RolleTyp.materialverantwortlicher, RolleTyp.leitungsverantwortlicher
|
|
)
|
|
|
|
|
|
@router.get("/dashboard/kennzahlen", response_model=KennzahlenRead)
|
|
async def hole_kennzahlen(db: AsyncSession = Depends(get_db), _=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))
|
|
|
|
|
|
@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)]
|
|
|
|
|
|
@router.get("/dashboard/einsatzbereitschaft", response_model=EinsatzbereitschaftRead)
|
|
async def hole_einsatzbereitschaft(
|
|
db: AsyncSession = Depends(get_db), _=Depends(_verantwortliche)
|
|
) -> EinsatzbereitschaftRead:
|
|
"""Kachel 1 Leitungs-Dashboard: einsatzbereit/eingeschränkt/nicht einsatzbereit
|
|
je Objekt, siehe app/services/dashboard.py:einsatzbereitschaft für die
|
|
Kriterien und die Mindermenge-Sonderrolle (U2, Karte 08)."""
|
|
return EinsatzbereitschaftRead(**await einsatzbereitschaft(db))
|
|
|
|
|
|
@router.get("/dashboard/prueftermine", response_model=list[PrueftermineintragRead])
|
|
async def hole_prueftermine(
|
|
db: AsyncSession = Depends(get_db), _=Depends(_verantwortliche)
|
|
) -> list[PrueftermineintragRead]:
|
|
"""Kachel 2 Leitungs-Dashboard: Geräteprüfungen (Karte 14), bewusst getrennt
|
|
von /dashboard/ablaufdaten (Nutzer-Entscheidung: Prüfung ≠ Ablauf)."""
|
|
return [PrueftermineintragRead(**eintrag) for eintrag in await bevorstehende_prueftermine(db)]
|