Files
VacatureRadar/docs/operations/RUNBOOK.md
T
Jens b8091e59bd
deploy / deploy (push) Canceled after 0s
Initial deploy setup
2026-07-21 14:00:00 +02:00

119 lines
5.6 KiB
Markdown

# Operationeel runbook
## Dagelijkse controle
Controleer bij voorkeur automatisch en minstens wekelijks handmatig:
- `/health/ready/` is 200;
- web, worker, scheduler, PostgreSQL en Redis zijn actief;
- vrije ruimte op database-, media-, log- en back-upvolume;
- bronnen in `quarantined`, `paused` of met oplopende `failure_count`;
- `DigestOutbox` met status `failed` of langdurig `pending`;
- meest recente geslaagde back-up en laatste hersteltest;
- onverwachte login- of policyfouten in logs.
## Incidentprioriteiten
| Niveau | Voorbeeld | Eerste actie |
|---|---|---|
| P1 | datalek, secret gepubliceerd, ongeautoriseerde netwerkfetch | stop web/worker/scheduler, isoleer netwerk, roteer secrets |
| P2 | database niet beschikbaar, imports corrupt, herhaalde mail | stop schrijvende processen, behoud bewijs, maak snapshot |
| P3 | één adapter kapot, digest vertraagd, bron in quarantaine | pauzeer bron/functie, herstel met fixture en test |
| P4 | copy/layout/probleem zonder datarisico | registreer backlogtaak en plan normale release |
## Web niet ready
1. Controleer liveness. Faalt die ook, inspecteer webcontainer/proces en poortbinding.
2. Bij `database=error:*`: controleer PostgreSQL-status, disk, credentials en netwerknaam.
3. Test vanuit webcontainer of DNS `postgres` resolveert en poort 5432 bereikbaar is.
4. Draai geen migraties herhaald blind; lees eerst de laatste stacktrace.
5. Herstart alleen de falende laag. Een volledige stackrestart kan diagnostiek wissen.
## Worker verwerkt niets
1. Controleer Redis en `CELERY_BROKER_URL`.
2. Controleer workerqueues `high,default,low`.
3. Inspecteer actieve en gereserveerde taken:
```bash
celery -A config inspect ping
celery -A config inspect active
celery -A config inspect reserved
```
4. Kijk naar timeouts, policyblokkades en retryloops.
5. Start niet meerdere schedulers; dat kan dubbele planning veroorzaken, ook al zijn imports idempotent.
## Bron faalt of gaat in quarantaine
1. Laat quarantaine staan; forceer geen fetch.
2. Lees alleen categorie, status, URL-host en beperkte foutmelding in `SourceRun`.
3. Controleer of het domein, redirectdoel, robots-/voorwaardenstatus of contenttype veranderde.
4. Download geen pagina met een onbeveiligde shellopdracht vanaf de productiehost.
5. Reproduceer met een gesaneerde fixture in een ontwikkelomgeving.
6. Werk parser/policy en securitytests bij.
7. Zet bron pas terug op `trial`, voer één begrensde run uit en promoveer daarna eventueel naar `active`.
## IMAP-import stopt
1. Zet `IMAP_ENABLED=0` om lockout of herhaalde fouten te beperken.
2. Controleer host, poort, TLS, mailboxnaam en app-password.
3. Verifieer dat de mailbox niet is hernoemd en het account niet is vergrendeld.
4. Test eerst read-only met `IMAP_MARK_SEEN=0`.
5. Een reeds verwerkte mail is idempotent via message identity; verwijder geen `EmailMessageRecord` om opnieuw te proberen zonder analyse.
## Digest ontbreekt of dubbel
- Controleer actief profiel, digesttijd/zone en `DIGEST_RECIPIENT`.
- Controleer `DigestOutbox` op datum en status.
- Bij SMTP-fout: corrigeer configuratie en retry dezelfde outbox gecontroleerd.
- Maak geen tweede outboxrecord handmatig; uniciteit per profiel/datum is de duplicaatbarrière.
- Een lege digest is toegestaan wanneer geen vacature boven de ingestelde drempel valt.
## Verdachte of kwaadaardige vacature-inhoud
1. Open de originele bron niet automatisch in een ingelogde browser.
2. Zet bij twijfel het raw document op `quarantined` zodat retentie het bewijs niet wist.
3. Controleer opgeslagen gesaniteerde tekst en veldherkomst.
4. Voeg de payload als geanonimiseerde fixture toe wanneer een parser/sanitizerfout bestaat.
5. Laat AI-output nooit een commando, URL-fetch of configuratiemutatie veroorzaken.
## Sollicitatiedossier exporteren en opschonen
1. Open de sollicitatielijst in een ingelogde gebruiker-sessie en ga naar het dossier.
2. Controleer dat de timeline alleen mutaties voor dat dossier bevat (status, notities, contact, snapshot).
3. Exporteer met het dossier-exportendpoint om een zip met `application.json`, `timeline.csv`, `application_print.html` te controleren.
4. Controleer het zipbestand lokaal op:
- correcte dossier-ID;
- geen raw e-mailbody of bron-payload;
- geen externe assets of scriptrequests in HTML.
5. Verwijderen mag alleen op gebruikersniveau (`delete` endpoint); herhaalde delete-aanroepen moeten zonder fout uitkomen.
## Schijfruimte laag
1. Stop scheduler en worker wanneer de database- of PostgreSQL-volume kritiek vol is.
2. Controleer oude back-ups, containerlogs, raw-documentretentie en Ollama-modellen.
3. Verwijder nooit willekeurig PostgreSQL-bestanden.
4. Laat `cleanup_raw_documents` alleen niet-gequarantaineerde verlopen documenten opruimen.
5. Vergroot volume of herstel rotatie, start daarna database, web, worker en scheduler in die volgorde.
## Secret vermoedelijk gelekt
1. Stop externe toegang en disable betrokken account/token.
2. Roteer Django secret, adminwachtwoord, database-, SMTP-, IMAP- en registrycredentials voor zover betrokken.
3. Trek oude sessies in door sessies te verwijderen of het secret te wijzigen.
4. Controleer logs en source-runs op misbruik, zonder gevoelige payload verder te kopiëren.
5. Maak een incidentnotitie met exacte tijden, scope, rotaties en herstelvalidatie.
## Herstelvalidatie
Na ieder incident:
```bash
python manage.py check
python manage.py migrate --plan
python manage.py shell -c "from apps.core.health import readiness; print(readiness())"
```
Controleer daarna login, één fixture-import, scoreberekening, bronlijst, sollicitatielijst en mailbackend. Start live polling pas nadat deze controles slagen.