Notificaciones y Recordatorios
1. Definición y Propósito
Orquesta el envío confiable y medible de notificaciones (email, SMS, push, in‑app) para eventos críticos: autenticación, agenda/citas, reseñas y validaciones.
- Contexto: Reducir no‑shows y mantener trazabilidad de eventos de seguridad (login, reset password).
- Valor: Mejora conversión, reduce ausentismo y aporta evidencia en disputas.
2. Arquitectura de Envío
| Componente | Rol | Tecnología |
|---|---|---|
| notification-worker | Cola y orquestación de plantillas | Go + Redis streams |
| provider-email | Envío transaccional | SES / SendGrid |
| provider-sms | OTP y recordatorios cortos | Twilio / Vonage |
| push-service | Notificaciones móviles | FCM / APNS |
Anti‑fragilidad: Retries exponenciales, DLQ para mensajes fallidos, idempotencia por message_id.
3. Tipos de Notificación
| Evento | Canal Primario | Canal Secundario | SLA de envío |
|---|---|---|---|
auth_otp | SMS | < 30s | |
reset_password | — | < 60s | |
appointment_created | Push | < 60s | |
appointment_reminder_T-24h | Push | ±5m | |
appointment_reminder_T-2h | SMS | Push | ±2m |
review_request | Push | ±10m |
4. Reglas de Negocio (BR)
- BR-NOT-01 (Idempotencia): Cada mensaje usa
message_idúnico; reintentos no deben duplicar envíos. - BR-NOT-02 (Rate Limits): Máx 3 OTP por 15 min por usuario/IP. Máx 2 recordatorios por cita.
- BR-NOT-03 (Fallback): Si canal primario falla 3 veces, usar canal secundario (si existe).
- BR-NOT-04 (Silenciamiento): Usuario puede desactivar push/email de marketing; transaccionales no se pueden silenciar.
- BR-NOT-05 (Plantillas versionadas): Toda plantilla lleva
template_version; cambios mayores requieren aprobación de UX/Legal.
5. Endpoints Propuestos
| Recurso | Método | Descripción | Roles |
|---|---|---|---|
/api/v1/notifications/send | POST | Enviar notificación directa (backoffice/support). | SUPERADMIN |
/api/v1/notifications/preferences | GET/PATCH | Leer/actualizar preferencias (push/email). | PATIENT, DOCTOR, ENTITY_ADMIN |
/api/v1/notifications/test | POST | Ping a proveedores (sandbox). | SUPERADMIN |
Contrato OpenAPI: documentado en static/openapi.yaml (acceso por /swagger y visor en /swagger.html).
Payload sugerido POST /api/v1/notifications/send:
{
"user_id": "uuid",
"channel": "EMAIL",
"template": "appointment_created_v1",
"data": {
"doctor_name": "Dra. López",
"date": "2026-03-01T14:00:00Z"
}
}
Implementación Backend (Go, DDD + Clean Architecture):
- Handlers en
interfaces/http/notificationsmapean DTOs a use casesSendNotification,UpdatePreferences,TestProvidersenapplication/notifications. - Repositorios
NotificationRepo,PreferenceRepo,TemplateReposon interfaces endomain/application; implementaciones eninfrastructure/persistence(Postgres/Redis) yinfrastructure/providers(email/SMS/push). - DTOs de OpenAPI son de interfaz; las entidades de dominio quedan desacopladas.
- Nomenclatura completa: ver
arquitectura-y-despliegue.md§7.1.
6. Observabilidad
- Métricas por canal: entregas, fallos, latencia P95, rebotes.
- Logging estructurado con
message_idytrace_id. - Alarmas si tasa de fallos >2% en 5 minutos por canal.
6.1 SLIs/SLOs y Alertas
| Métrica | SLO | Alerta |
|---|---|---|
notif_send_p95 | < 2s | Warn > 3s 5m |
notif_fail_rate | < 2% | Warn > 2%; Crit > 5% |
otp_delivery_success | > 98% | Crit < 95% |
sms_delivery_p95 | < 30s | Warn > 45s |
email_bounce_rate | < 1% | Warn > 2% |
dlq_depth | 0 | Crit si >0 por >5 min |
6.2 Ejemplos de Requests/Responses
- Send (POST /api/v1/notifications/send)
Request:{ "user_id":"uuid", "channel":"EMAIL", "template":"appointment_created_v1", "data":{...} }
202:{ "message":"queued" }
400:{ "message":"Datos inválidos" } - Preferences (PATCH /api/v1/notifications/preferences)
Request:{ "email_enabled": false, "push_enabled": true }
200:{ "email_enabled": false, "push_enabled": true, "sms_enabled": true, "marketing_opt_in": false }
7. Seguridad y Cumplimiento
- Plantillas sin PII sensible; no enviar tokens JWT por email/SMS.
- OTP y códigos de verificación expiran en 15 minutos; solo último código es válido.
- DKIM/SPF configurados; SMS con remitente registrado.
8. Control de Abuso/Fraude
- Rate limit OTP: 3 por 15 min por usuario/IP; bloquear si se excede y requerir captcha del lado de auth.
- Throttling de recordatorios: máx 2 por cita; rate limit por usuario para evitar spam.
- Validar destino: bloquear correos desechables conocidos; sanitizar data de template para evitar inyección.
9. Casos de Borde y Manejo de Errores
- Proveedor primario caído → fallback al secundario; si ambos fallan, DLQ y alerta.
- Plantilla inexistente o versión no encontrada → 422.
- Preferencias deshabilitadas por usuario → no enviar marketing; transaccional siempre se envía.
- OTP expirado → 401/422 y registrar intento fallido.
10. Checklist de QA / Testing
- Envío email y SMS exitoso (200/202) con contenido correcto.
- OTP: límite 3/15m; cuarto intento bloqueado.
- Fallback: simular fallo de proveedor y verificar reintento en canal secundario.
- Preferencias: PATCH desactiva marketing y se respeta en envíos.
- DLQ: mensajes fallidos aterrizan en DLQ y generan alerta.
11. Variables de Entorno (Front)
VITE_API_BASE=https://api.example.com/api/v1VITE_NOTIF_ENABLE_PUSH=true|falseVITE_NOTIF_TEST_MODE=true|false
12. Accesibilidad (A11y)
- Preferencias accesibles por teclado; toggles con labels claros.
- Mensajes de estado con
aria-liveal guardar preferencias.
13. Métricas de Producto (Funnel)
- OTP enviado → OTP entregado → OTP verificado.
- Recordatorio enviado → Recordatorio entregado → Cita atendida.
- Tasa de opt-out vs marketing vs transaccional.
14. Enlaces y Trazabilidad
- Swagger UI:
/swagger.html(acceso desde/swagger) y contrato YAML en/openapi.yaml. - Relacionados:
agenda-citas.md(recordatorios),autenticacion.md(OTP/reset),esquema-de-base-de-datos.md(tablasnotification_logs,notification_preferences),arquitectura-y-seguridad.md(observabilidad).
15. Dependencias
verification_tokens(OTP),appointments(recordatorios),audit_logs(trazabilidad),file_assets(adjuntos opcionales).