Karte 12: Eskalationslogik für lange offene Fehlbestände
Zwei Stufen (Erinnerung an Materialverantwortliche, Eskalation an Leitungsverantwortliche/Administration) mit Tracking-Zeitstempel je Stufe gegen Mehrfachversand. Zeitschwellen in eskalation_konfiguration (DB, Singleton), admin-editierbar über GET/PUT /eskalation/konfiguration - bewusst nicht fix im Code. Prüflauf per POST /eskalation/pruefen angestoßen, Scheduling (Cron/systemd-Timer) bleibt Betriebsaufgabe. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
@@ -4,6 +4,7 @@ from app.api.v1.endpoints import (
|
||||
auth,
|
||||
benutzer,
|
||||
dashboard,
|
||||
eskalation,
|
||||
fehlbestaende,
|
||||
health,
|
||||
kontrollen,
|
||||
@@ -23,4 +24,5 @@ api_router.include_router(vorlagen.router, tags=["vorlagen"])
|
||||
api_router.include_router(objekte.router, tags=["objekte"])
|
||||
api_router.include_router(kontrollen.router, tags=["kontrollen"])
|
||||
api_router.include_router(fehlbestaende.router, tags=["fehlbestaende"])
|
||||
api_router.include_router(eskalation.router, tags=["eskalation"])
|
||||
api_router.include_router(dashboard.router, tags=["dashboard"])
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
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.models.eskalation import EskalationKonfiguration
|
||||
from app.schemas.eskalation import (
|
||||
EskalationKonfigurationRead,
|
||||
EskalationKonfigurationUpdate,
|
||||
EskalationPruefungResult,
|
||||
)
|
||||
from app.services.eskalation import hole_konfiguration, pruefe_offene_fehlbestaende
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
_admin_only = require_roles(RolleTyp.administration)
|
||||
|
||||
|
||||
@router.get("/eskalation/konfiguration", response_model=EskalationKonfigurationRead)
|
||||
async def lese_konfiguration(
|
||||
db: AsyncSession = Depends(get_db), _=Depends(_admin_only)
|
||||
) -> EskalationKonfiguration:
|
||||
return await hole_konfiguration(db)
|
||||
|
||||
|
||||
@router.put("/eskalation/konfiguration", response_model=EskalationKonfigurationRead)
|
||||
async def aendere_konfiguration(
|
||||
payload: EskalationKonfigurationUpdate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_=Depends(_admin_only),
|
||||
) -> EskalationKonfiguration:
|
||||
"""Karte 12: Zeitschwellen zur Laufzeit änderbar (Nutzer-Vorgabe: nicht fix
|
||||
im Code)."""
|
||||
konfiguration = await hole_konfiguration(db)
|
||||
konfiguration.erinnerung_tage = payload.erinnerung_tage
|
||||
konfiguration.leitung_tage = payload.leitung_tage
|
||||
await db.flush()
|
||||
return konfiguration
|
||||
|
||||
|
||||
@router.post("/eskalation/pruefen", response_model=EskalationPruefungResult)
|
||||
async def pruefen(db: AsyncSession = Depends(get_db), _=Depends(_admin_only)) -> dict[str, int]:
|
||||
"""Trigger für den Eskalations-Prüflauf (Karte 12). Scheduling selbst ist
|
||||
Betriebsaufgabe (z.B. System-Cron ruft diesen Endpunkt periodisch auf,
|
||||
Prompt 19 Deployment-Regel: kein eigener Scheduler-Prozess im Code)."""
|
||||
return await pruefe_offene_fehlbestaende(db)
|
||||
Reference in New Issue
Block a user