# Fase B — Proactieve Signalering Lions GCC (Alerts)

**Status:** ✅ Gebouwd & lokaal getest (26/26 pytest groen, `tests/test_alerts.py`) · **Nog NIET live** — integratie hieronder is een patch-instructie voor Kas.

## Wat is er gebouwd

| Bestand | Inhoud |
|---|---|
| `alerts_module.py` | Zelfstandige module: `bereken_signalen()` + route `GET /agenda/api/alerts` via `register_alert_routes(app, page, BASE_PATH, db)` |
| `templates/agenda-alerts-widget.html` | Dashboard-widget (inline CSS + JS, donkere badges: rood=T-2, oranje=T-7, geel=T-14/T-20) |
| `telegram_push.py` | Content-generator voor de dagelijkse push: print `TELEGRAM:<bericht>` of `SKIP` |
| `tests/test_alerts.py` | 26 tests tegen de échte agenda-JSON (70 items) |
| `data/alerts-vandaag.json` | Dagelijkse output (idempotent: herberekening van dezelfde dag overschrijft) |

## Signaal- & stiltevensterlogica (vastgesteld)

- **Signaalschema:** T-20 / T-14 / T-7 / T-2 — signalen gaan altijd uit van de **startdatum** (ook bij `datum_eind`, bv. Zonebijeenkomstweek)
- **Komende items:** startdatum binnen 14 dagen, plus lopende meerdaagse items (`datum ≤ vandaag ≤ datum_eind`)
- **Bron-volgorde:** `agenda_items`-tabel (Fase A) via meegegeven `db` indien aanwezig, anders `data/agenda-110AN-2026-2027.json` (bron van waarheid)
- **Stiltevenster:** pushes nooit vóór 08:00 Europe/Amsterdam; verstuurvenster 08:00–21:30 (08:00 inclusief, 21:30 exclusief)
- Afgeronde items (`status=afgerond`) signaleren niet meer

## Integratie in de productie-app (stappen voor Kas)

### Stap 1 — bestanden kopiëren
```bash
cp /root/projects/jg/lgcc-proactieve-agenda/alerts_module.py \
   /root/.openclaw/workspace/lions-gcc/alerts_module.py
cp /root/projects/jg/lgcc-proactieve-agenda/templates/agenda-alerts-widget.html \
   /root/.openclaw/workspace/lions-gcc/templates/agenda-alerts-widget.html
```
`telegram_push.py` + agenda-JSON blijven buiten de app (draaien vanuit deze repo op de host, via OpenClaw-cron).

### Stap 2 — app.py aanpassen (2 mini-patches)

**2a. Import** (naast de agenda_module-import):
```python
from alerts_module import register_alert_routes
```

**2b. Route-registratie** (direct ná `register_agenda_routes(app, page, BASE_PATH, ai_complete, db)`):
```python
register_alert_routes(app, page, BASE_PATH, db)
```
Let op: deze signature is `(app, page, BASE_PATH, db)` — zonder `ai_complete`.

### Stap 3 — widget in de homepage-template
Exacte include-instructie (Jinja), direct boven/na de openings-card van de dashboard-body in `templates/home.html` (of equivalent):
```jinja
{% include 'agenda-alerts-widget.html' %}
```
Werkt de homepage via string-injectie (`page()`-body zoals agenda_module doet), dan in Python:
```python
with open('templates/agenda-alerts-widget.html', encoding='utf-8') as f:
    alerts_widget_html = f.read()
# alerts_widget_html in de homepage-body-string injecteren op de widget-plek
```
De widget haalt zijn data zelf op via `GET agenda/api/alerts` (relatief; fallback `/lgcc/agenda/api/alerts`) en verbergt zichzelf als de API onbereikbaar is. Geen externe dependencies.

### Stap 4 — OpenClaw-cron (dagelijkse signalering)

Twee runs per dag achter elkaar (alleen content-generatie; de daadwerkelijke Telegram-push doet de OpenClaw-cron/announce-route, NIET dit script):

```
# 1) alerts herberekenen (elke nacht, vóór 08:00 Amsterdam — bv. 06:05)
06 06 * * *  cd /root/projects/jg/lgcc-proactieve-agenda && /usr/bin/python3 alerts_module.py

# 2) push-content genereren (elke ochtend na stiltevenster — bv. 08:05)
05 08 * * *  cd /root/projects/jg/lgcc-proactieve-agenda && /usr/bin/python3 telegram_push.py
```
`telegram_push.py` print `TELEGRAM:<bericht>` of `SKIP`; de cron/Agent beslist of de content daadwerkelijk verstuurd wordt. Het script pushéér zelf niets. Zonder signalen, buiten het venster, of bij een verouderd alerts-bestand → `SKIP` (veilig bij dubbele of gemiste runs).

### Stap 5 — herstart & verificatie
```bash
pm2 restart lions-command
curl -s https://mescalinerabbit.shop/lgcc/agenda/api/alerts | python3 -m json.tool
```
Verwacht: JSON met `datum`, `alerts` (signalen van vandaag) en `komende` (binnen 14 dagen). De widget verschijnt op de homepage zodra daar geïnclude.

## Endpoint

`GET /agenda/api/alerts` (optioneel `?datum=YYYY-MM-DD` voor herberekening/inspectie) →
```json
{"datum": "2026-08-17", "aantal_alerts": 1,
 "alerts": [{"datum": "2026-08-24", "datum_eind": null,
             "titel": "Uitnodiging workshop GST/alzheimerdag versturen",
             "type": "training", "signaaltype": "T-7", "dagen_tot": 7}],
 "aantal_komende": 2, "komende": [...], "bron": "json"}
```

## Tests (alle groen, 26/26)

- **a)** workshop 24-08 → T-20 op 04-08, T-14 op 10-08
- **b)** Kabinetsvergadering 21-09 → T-20 op 01-09, T-14 op 07-09, T-7 op 14-09, T-2 op 19-09 (+ geen vals signaal op 10-09)
- **c)** Zonebijeenkomstweek (23 t/m 28-11) → signalen op startdatum (T-2 op 21-11), níet afgeleid van einddatum; lopend item verschijnt in `komende`
- **d)** stiltevenster: 07:59 → `SKIP`, 08:00 → `TELEGRAM:…`, 21:29 ok / 21:30 `SKIP`, geen signalen → `SKIP`, verouderd bestand → `SKIP`, bericht max 6 regels, `main()` met gemockte tijd
- plus: alerts-vandaag.json-schrijving + idempotentie, db-bron + JSON-fallback, afgeronde items, API-route (200/400)

Draaien: `python3 -m pytest tests/test_alerts.py -v`
