synops/docs/features/varsler.md
vegard 6370b02cc7 26.7 ferdig: utgående varsler med brukerpreferanser
Vaktmesteren kan nå sende epost-varsler og WebSocket-push til brukere
via synops-notify, med respekt for brukerens preferanser.

Endringer:
- jobs.rs: send_notification jobbtype som delegerer til synops-notify CLI
- synops-notify: preferansesjekk fra metadata.preferences.notifications
  (opt-out-modell, per-kanal og per-type bryter, --skip-preferences)
- intentions.rs: POST /intentions/send_notification (admin-only)
- Dokumentasjon: docs/features/varsler.md

Preferanseskjema (i brukernodens metadata):
  preferences.notifications.email: bool (global epost-bryter)
  preferences.notifications.ws: bool (global WS-bryter)
  preferences.notifications.<type>: bool (per-type, f.eks. task_assigned)
2026-03-19 02:08:00 +00:00

132 lines
3.3 KiB
Markdown

# Varsler (notifications)
Vaktmesteren kan sende varsler til brukere via epost og/eller
WebSocket-push. Konfigurerbart per bruker i metadata.preferences.
## Arkitektur
```
Trigger (orkestreringsscript, intention, manuelt)
Jobbkø: send_notification
synops-notify CLI
├── Sjekk metadata.preferences.notifications
├── Epost: synops-mail --send → msmtp → Brevo SMTP
└── WebSocket: notification-node i PG → NOTIFY → portvokteren → klient
```
## Kanaler
| Kanal | Beskrivelse |
|-------|-------------|
| `email` | Epost via msmtp/Brevo. Slår opp adresse i `auth_identities`. |
| `ws` | Oppretter `notification`-node med `node_access` → PG NOTIFY → WebSocket. |
| `both` | Begge kanaler. |
## Brukerpreferanser
Lagres i brukerens node (`node_kind='person'`), i `metadata.preferences.notifications`.
**Opt-out-modell:** Alt er aktivert som default. Brukere skrur av det de
ikke vil ha. Manglende felt = aktivert.
### Skjema
```json
{
"preferences": {
"notifications": {
"email": true, // global epost-bryter
"ws": true, // global WS-bryter
"task_assigned": true, // per-type: ny oppgave tildelt
"article_approved": true, // per-type: artikkel godkjent
"comment_reply": true // per-type: svar på kommentar
}
}
}
```
### Evalueringslogikk
1. Ingen preferanser satt → alle kanaler aktivert
2. Per-type bryter (`task_assigned: false`) → begge kanaler deaktivert for den typen
3. Global kanal-bryter (`email: false`) → epost deaktivert for alle typer
4. `--skip-preferences` → ignorer preferanser (for systemkritiske varsler)
## Bruk
### CLI (direkte)
```bash
# WebSocket-varsel (default)
synops-notify --to <node_id> --message "Tekst" --channel ws
# Epost-varsel
synops-notify --to <node_id> --message "Tekst" --subject "Emne" --channel email
# Begge kanaler med type-sjekk
synops-notify --to <node_id> --message "Ny oppgave" --channel both \
--notification-type task_assigned
# Ignorer preferanser (systemkritisk)
synops-notify --to <node_id> --message "Viktig" --channel email --skip-preferences
```
### Via jobbkø
```json
{
"job_type": "send_notification",
"payload": {
"to": "a0eebc99-...",
"message": "Du har fått en ny oppgave",
"subject": "Ny oppgave",
"channel": "both",
"notification_type": "task_assigned"
}
}
```
### Via API (intention)
```
POST /intentions/send_notification
{
"to": "a0eebc99-...",
"message": "Artikkelen din er godkjent",
"subject": "Artikkel godkjent",
"channel": "both",
"notification_type": "article_approved"
}
```
Krever admin-rolle. Legger jobben i køen med prioritet 10.
## Orkestreringsscript
Varsler kan trigges fra orkestreringsscript:
```
NÅR edge opprettet OG type = "member_of"
KJØR synops-notify --to {event.target_id} --message "Ny oppgave tildelt" --channel both --notification-type task_assigned
```
## Varslingstyper
Konvensjon for `notification_type`-feltet:
| Type | Beskrivelse |
|------|-------------|
| `task_assigned` | Ny oppgave tildelt |
| `article_approved` | Innsendt artikkel godkjent |
| `article_rejected` | Innsendt artikkel avvist |
| `comment_reply` | Svar på kommentar |
| `communication_ended` | Møte/samtale avsluttet |
| `mention` | Nevnt i en node |
Nye typer legges til etter behov — ingen hardkodet liste i koden.