Karte 12: systemd-Timer für den täglichen Eskalations-Prüflauf
scripts/eskalation_pruefen.py ruft den Service direkt gegen die DB auf (kein HTTP/Admin-Token nötig, gleiches Muster wie scripts/create_admin.py). mabea-eskalation.timer läuft täglich 06:00 Uhr. Zeitschwellen bleiben in der DB (eskalation_konfiguration), nicht im Timer. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
@@ -2690,3 +2690,66 @@ Keine Commits in dieser Session.
|
|||||||
- backend/tests/test_eskalation.py | 73 ++++++++++++++++
|
- backend/tests/test_eskalation.py | 73 ++++++++++++++++
|
||||||
|
|
||||||
---
|
---
|
||||||
|
## 2026-09-04 18:07 – 18:08 (0m)
|
||||||
|
**Beschreibung:** Claude Code Session
|
||||||
|
**Projekt:** frontend
|
||||||
|
|
||||||
|
### Commits
|
||||||
|
- e0cbf4b Playwright-E2E-Tests für die PWA (Login, Sperrlogik, Fortschritt, Offline-Queue)
|
||||||
|
|
||||||
|
### Geänderte Dateien
|
||||||
|
- DEVLOG.md | 22 +++++++++
|
||||||
|
- frontend/.gitignore | 3 ++
|
||||||
|
- frontend/DEVLOG.md | 22 +++++++++
|
||||||
|
- frontend/README.md | 18 +++++--
|
||||||
|
- frontend/e2e/fortschritt.spec.ts | 41 ++++++++++++++++
|
||||||
|
- frontend/e2e/login.spec.ts | 30 ++++++++++++
|
||||||
|
- frontend/e2e/mockApi.ts | 98 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
- frontend/e2e/offline-queue.spec.ts | 65 +++++++++++++++++++++++++
|
||||||
|
- frontend/e2e/sperrlogik.spec.ts | 34 +++++++++++++
|
||||||
|
- frontend/package.json | 5 +-
|
||||||
|
- frontend/playwright.config.ts | 21 ++++++++
|
||||||
|
|
||||||
|
---
|
||||||
|
## 2026-09-04 18:15 – 18:20 (5m)
|
||||||
|
**Beschreibung:** Claude Code Session
|
||||||
|
**Projekt:** asb-material
|
||||||
|
|
||||||
|
### Commits
|
||||||
|
Keine Commits in dieser Session.
|
||||||
|
|
||||||
|
### Geänderte Dateien
|
||||||
|
- DEVLOG.md | 22 +++++++++
|
||||||
|
- frontend/.gitignore | 3 ++
|
||||||
|
- frontend/DEVLOG.md | 22 +++++++++
|
||||||
|
- frontend/README.md | 18 +++++--
|
||||||
|
- frontend/e2e/fortschritt.spec.ts | 41 ++++++++++++++++
|
||||||
|
- frontend/e2e/login.spec.ts | 30 ++++++++++++
|
||||||
|
- frontend/e2e/mockApi.ts | 98 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
- frontend/e2e/offline-queue.spec.ts | 65 +++++++++++++++++++++++++
|
||||||
|
- frontend/e2e/sperrlogik.spec.ts | 34 +++++++++++++
|
||||||
|
- frontend/package.json | 5 +-
|
||||||
|
- frontend/playwright.config.ts | 21 ++++++++
|
||||||
|
|
||||||
|
---
|
||||||
|
## 2026-09-04 18:27 – 18:27 (0m)
|
||||||
|
**Beschreibung:** Claude Code Session
|
||||||
|
**Projekt:** asb-material
|
||||||
|
|
||||||
|
### Commits
|
||||||
|
Keine Commits in dieser Session.
|
||||||
|
|
||||||
|
### Geänderte Dateien
|
||||||
|
- DEVLOG.md | 22 +++++++++
|
||||||
|
- frontend/.gitignore | 3 ++
|
||||||
|
- frontend/DEVLOG.md | 22 +++++++++
|
||||||
|
- frontend/README.md | 18 +++++--
|
||||||
|
- frontend/e2e/fortschritt.spec.ts | 41 ++++++++++++++++
|
||||||
|
- frontend/e2e/login.spec.ts | 30 ++++++++++++
|
||||||
|
- frontend/e2e/mockApi.ts | 98 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
- frontend/e2e/offline-queue.spec.ts | 65 +++++++++++++++++++++++++
|
||||||
|
- frontend/e2e/sperrlogik.spec.ts | 34 +++++++++++++
|
||||||
|
- frontend/package.json | 5 +-
|
||||||
|
- frontend/playwright.config.ts | 21 ++++++++
|
||||||
|
|
||||||
|
---
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
"""Karte 12: periodischer Eskalations-Prüflauf, für einen systemd-Timer gedacht.
|
||||||
|
|
||||||
|
Deployment-Regel (Prompt 19): nur Skript-Datei hier, Ausführung auf Zielsystem.
|
||||||
|
Direkter DB-Zugriff statt HTTP-Aufruf des Endpunkts (POST /eskalation/pruefen) -
|
||||||
|
kein Admin-Token/Login nötig für einen lokalen Cron/Timer auf demselben Host,
|
||||||
|
gleiches Muster wie scripts/create_admin.py.
|
||||||
|
|
||||||
|
Aufruf (im aktivierten venv auf dem Server):
|
||||||
|
|
||||||
|
python -m scripts.eskalation_pruefen
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from app.db.session import SessionLocal
|
||||||
|
from app.services.eskalation import pruefe_offene_fehlbestaende
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def main() -> None:
|
||||||
|
async with SessionLocal() as db:
|
||||||
|
ergebnis = await pruefe_offene_fehlbestaende(db)
|
||||||
|
await db.commit()
|
||||||
|
logger.info(
|
||||||
|
"Eskalations-Prüflauf: %d Erinnerung(en), %d Eskalation(en) verschickt.",
|
||||||
|
ergebnis["erinnerungen"],
|
||||||
|
ergebnis["eskalationen"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
@@ -21,7 +21,23 @@ Installiert PostgreSQL + nginx, legt DB-Rolle/Datenbank an, richtet nginx als Re
|
|||||||
3. `alembic upgrade head` ausführen.
|
3. `alembic upgrade head` ausführen.
|
||||||
4. `mabea-backend.service.template` nach `/etc/systemd/system/mabea-backend.service` kopieren (Pfade/User anpassen), `systemctl daemon-reload && systemctl enable --now mabea-backend`.
|
4. `mabea-backend.service.template` nach `/etc/systemd/system/mabea-backend.service` kopieren (Pfade/User anpassen), `systemctl daemon-reload && systemctl enable --now mabea-backend`.
|
||||||
|
|
||||||
|
## Eskalations-Prüfung einrichten (Karte 12, nach Backend-Deploy)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp mabea-eskalation.service.template /etc/systemd/system/mabea-eskalation.service
|
||||||
|
cp mabea-eskalation.timer.template /etc/systemd/system/mabea-eskalation.timer
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now mabea-eskalation.timer
|
||||||
|
```
|
||||||
|
|
||||||
|
Läuft täglich 06:00 Uhr (±5min Streuung), ruft `scripts/eskalation_pruefen.py` direkt
|
||||||
|
gegen die DB auf (kein HTTP/Admin-Token nötig). Zeitschwellen selbst liegen in der DB
|
||||||
|
(`eskalation_konfiguration`, admin-editierbar über `GET/PUT /api/v1/eskalation/konfiguration`),
|
||||||
|
nicht in dieser Timer-Konfiguration. Manueller Testlauf: `systemctl start mabea-eskalation.service`,
|
||||||
|
Ergebnis in `journalctl -u mabea-eskalation.service`.
|
||||||
|
|
||||||
## Dateien
|
## Dateien
|
||||||
- `install_server.sh` – Server-Grundausstattung (PostgreSQL, nginx), idempotent
|
- `install_server.sh` – Server-Grundausstattung (PostgreSQL, nginx), idempotent
|
||||||
- `nginx_mabea.conf.template` – Reverse-Proxy-Vorlage, von `install_server.sh` verwendet
|
- `nginx_mabea.conf.template` – Reverse-Proxy-Vorlage, von `install_server.sh` verwendet
|
||||||
- `mabea-backend.service.template` – systemd-Unit-Vorlage für das Backend (noch nicht aktiviert, Pfade anpassen)
|
- `mabea-backend.service.template` – systemd-Unit-Vorlage für das Backend (noch nicht aktiviert, Pfade anpassen)
|
||||||
|
- `mabea-eskalation.service.template` / `mabea-eskalation.timer.template` – täglicher Eskalations-Prüflauf (Karte 12)
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=MABEA Eskalations-Pruefung (Karte 12, oneshot)
|
||||||
|
After=network.target postgresql.service
|
||||||
|
Requires=postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
User=mabea
|
||||||
|
WorkingDirectory=/opt/mabea/backend
|
||||||
|
EnvironmentFile=/opt/mabea/backend/.env
|
||||||
|
ExecStart=/opt/mabea/backend/.venv/bin/python -m scripts.eskalation_pruefen
|
||||||
|
|
||||||
|
NoNewPrivileges=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ReadWritePaths=/opt/mabea/backend
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=MABEA Eskalations-Pruefung taeglich (Karte 12)
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
# Taegliche Pruefung reicht - Schwellen (eskalation_konfiguration) sind in Tagen,
|
||||||
|
# ein untertaegiges Intervall brächte keinen echten Zusatznutzen, nur mehr Last.
|
||||||
|
OnCalendar=*-*-* 06:00:00
|
||||||
|
Persistent=true
|
||||||
|
RandomizedDelaySec=300
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
Reference in New Issue
Block a user