KOHAMI Docs
Guides

Alerts cascade

La cascade aidants est le mécanisme par lequel KOHAMI escalade une situation critique (idéation suicidaire, AVC suspecté, douleur sévère, bouton d'alerte) auprès du réseau de soutien du senior. Elle est régie par deux invariants stricts.

Invariants

  • INV-S01, idéation suicidaire détectée, alerte rouge dispatchée en moins de 5 secondes (timestamp détection vers timestamp alert.created).
  • INV-S02, aucun ticket silencieux hors N3, toute alerte génère un retour vocal au senior et une trace dans alert_trail.

Vue d'ensemble

Pour chaque senior, jusqu'à trois aidants sont configurés en cascade par ordre de priorité. Le pipeline standard :

  1. Niveau 1 (N1), Twilio Voice (appel automatique) et Twilio SMS en parallèle
  2. Niveau 2 (N2), bascule après timeout configurable (par défaut 90 s sans réponse) sur le N+1
  3. Niveau 3 (N3), fallback JUWA support (escalade externe, log opérationnel)

Le state machine de la cascade vit dans Inngest (apps/api/src/modules/security/inngest/caregiver-cascade-dispatchers.ts).

Diagramme

Endpoints clés

Ingestion bouton d'alerte

POST /v1/alerts/button-pressed (idempotency requis, voir Gestion d'erreurs)

Payload :

{
  pressedAt: string; // ISO 8601
  context: "voluntary" | "fall_detected" | "extended_inactivity";
}

Réponse :

{
  alertId: string; // UUID, trace dans alert_trail
  cascadeStarted: true;
}

Trail d'alertes

GET /v1/alerts/trail/:seniorId (rôle aidant requis, RLS appliqué)

Retourne l'historique paginé (cursor-based) :

{
  items: Array<{
    id: string;
    kind: "button" | "suicide" | "avc" | "pain" | "battery" | "inactivity";
    severity: "info" | "warning" | "critical";
    occurredAt: string;
    cascadeState: "pending" | "dispatched_n1" | "dispatched_n2" | "escalated" | "resolved";
    resolvedAt?: string;
    resolvedBy?: string;
  }>;
  nextCursor?: string;
}

Alertes récentes (admin)

GET /v1/admin/alerts/recent (rôle admin requis), monitoring global pour le dashboard JUWA.

Vue cascade d'un senior (admin)

GET /v1/admin/seniors/:seniorId/caregivers/cascade (rôle admin requis), expose la configuration de cascade (primary / secondary / tertiary) jointe à la dernière alert row et son alert_trails. Les numéros E.164 et display_name des aidants sont masqués (PII masking, INV-T07b). Si aucune alerte n'existe pour le senior, last_alert: null et alert_trails: [].

Vues admin par senior

Pour le dashboard /seniors/:id, l'API expose un set de vues admin avec seniorId en path :

  • GET /v1/admin/seniors/:seniorId/reminders — rappels à venir (filtre ?within_days=, ?kind=).
  • GET /v1/admin/seniors/:seniorId/reminders/all — vue brute table reminders (tous statuses, passé + futur, filtres opt-in ?status=, ?kind=, ?from=, ?to=).
  • GET /v1/admin/seniors/:seniorId/mood-entries — journal humeur brut (1 row / capture mood_scores, filtres ?source=, ?from=, ?to=).
  • GET /v1/admin/seniors/:seniorId/absence-mode et PUT /v1/admin/seniors/:seniorId/absence-mode — état / pilotage du mode absence (INV-S07, SOP V3.2 §4.3).

Toutes les vues admin sont protégées par JwtAuthGuard + assertion role === 'admin' en defense in depth. RLS Postgres applique la couche finale.

Frames DataChannel

AlertButtonAcknowledgedEvent

Publiée immédiatement après kohami.user.alert_button_pressed pour confirmer au senior que la cascade a démarré (INV-S02).

type AlertButtonAcknowledgedEvent = {
  kind: "alert:button_acknowledged";
  alertId: string;
  message: string; // texte affiché et lu par Helena
  ts: string;
};

Cascade events (admin dashboard)

Sur le canal kohami.admin.events (réservé au dashboard) :

  • alert.cascade.dispatched_n1
  • alert.cascade.dispatched_n2
  • alert.cascade.escalated
  • alert.cascade.resolved

Configuration aidants

POST /v1/admin/caregivers/:id/reactivation-notice permet à un admin de notifier un aidant désactivé. Le contrat complet est documenté dans packages/shared/src/types/caregivers.ts.

Aller plus loin