My App

Notifications

WhatsApp Business API, Resend email, notifications in-app

Voir ADR-03 pour le rationnel des choix de canaux.

Architecture

flowchart TD
    A[Nouveau signalement] --> B[Notification Service]
    B --> C{Canal activé ?}
    C -->|In-app| D[DB insert + WebSocket]
    C -->|Email| E[Queue → Resend API]
    C -->|WhatsApp| F{Fenêtre d'agrégation ?}
    F -->|Premier message| G[Queue → WhatsApp API]
    F -->|Déjà envoyé récemment| H[Agrégé — pas d'envoi]

Canal 1 — In-app

Notification en temps réel dans le dashboard.

  • Stockage : Table notification avec channel = "in_app"
  • Temps réel : WebSocket (ou polling court-terme) pour le badge + toast
  • Marquage : "Lu" quand l'établissement ouvre le signalement
  • Coût : Gratuit

Canal 2 — Email (Resend)

Template HTML envoyé via l'API Resend.

import { Resend } from "resend";

const resend = new Resend(env.RESEND_API_KEY);

await resend.emails.send({
  from: "alerts@wcare.fr",
  to: establishment.email,
  subject: `🚽 Signalement — ${toilet.name}`,
  html: renderReportEmail({ establishment, toilet, report }),
});

Template :

  • En-tête avec logo Wcare
  • Nom de l'établissement et du WC
  • Catégorie + texte libre du signalement
  • Bouton "Voir dans le dashboard"
  • Pied de page avec lien de désabonnement

Coût : Resend free tier = 3000 emails/mois. Largement suffisant en V1.

Canal 3 — WhatsApp Business API

Le plus coûteux — nécessite une agrégation intelligente.

Prérequis

  1. Compte Meta Business vérifié
  2. Numéro WhatsApp Business dédié
  3. Templates de message approuvés par Meta
  4. Provider : Twilio / Meta Cloud API direct

Template de message (à faire approuver)

🚽 *{{establishment_name}}* — Signalement WC

📍 *{{toilet_name}}* {{#if toilet_location}}({{toilet_location}}){{/if}}
⚠️ {{issue_category}}: {{issue_detail}}
🕐 {{timestamp}}

👉 Dashboard : {{dashboard_url}}

Agrégation

async function shouldSendWhatsApp(
  toiletId: string,
  windowMinutes: number,
): Promise<boolean> {
  const recentWhatsapp = await db
    .select()
    .from(notification)
    .where(
      and(
        eq(notification.channel, "whatsapp"),
        eq(notification.status, "sent"),
        gt(notification.sentAt, subMinutes(new Date(), windowMinutes)),
        // Joindre avec report pour filtrer par toiletId
      ),
    )
    .limit(1);

  return recentWhatsapp.length === 0;
}

Coûts estimés

VolumeMessages/moisCoût (~0.05€/msg)
1 établissement, 5 WC~50–1002.50–5.00€
10 établissements~500–100025–50€
50 établissements~2500–5000125–250€

L'agrégation réduit les coûts de 60-80% par rapport à un envoi par signalement.

Configuration par établissement

Chaque établissement peut configurer ses notifications depuis /dashboard/settings :

ParamètreTypeDéfaut
WhatsApp activébooleanfalse (nécessite un numéro)
Email activébooleantrue
In-app activébooleantrue
Fenêtre d'agrégationminutes5
Numéro WhatsAppstring
Emails supplémentairesstring[]

On this page