Overview
:::info Source
Sourced from services/notification-service/SERVICE_OVERVIEW.md in the documentation repo.
:::
Mission
Deliver the right message to the right user, on the right channel, in the right locale, at the right time - without spamming them, without leaking PII, and without blocking the event loop of any other service.
Value Proposition
The notification-service is the single mouth of the Ghasi-edTech platform. No other service directly emails, SMSes, pushes, or webhooks a user. All user-facing communication flows through this service so that:
- Preference gating is enforced uniformly (quiet hours, channel opt-outs, unsubscribes, regulatory holds).
- Templating, localization, and branding stay consistent across all 19 services.
- Digest and throttling can collapse "notification storms" (e.g., 40 assignments posted at once become one digest email).
- Provider abstraction lets us swap SES ↔ Mailgun, Twilio ↔ Africa's Talking, FCM ↔ APNs without touching business logic.
- Audit trail of every message sent is preserved for compliance (GDPR, COPPA, FERPA right-to-know).
Bounded Context
- Context Name: Notification
- Classification: Generic subdomain (reliable commodity)
- Strategic Pattern: Shared Kernel with Identity (for user contact info), Customer/Supplier with every publishing service
- Core Competency: Reliable multi-channel fan-out with preference enforcement
Channels Supported (by slice)
| Channel | Slice | Provider (Primary) | Provider (Fallback) | Latency SLO |
|---|---|---|---|---|
| S0 | AWS SES | Mailgun | p95 < 60s enqueue→delivered | |
| In-app | S0 | Self-hosted (WS + REST) | - | p95 < 2s |
| SMS | S3 | Twilio | Africa's Talking | p95 < 30s |
| Push (mobile) | S1 | FCM | APNs (iOS native) | p95 < 10s |
| Push (web) | S1 | Web Push (VAPID) | - | p95 < 10s |
| Webhook (outbound) | S2 | HTTPS POST (HMAC-signed) | - | p95 < 5s, 3 retries |
| S6+ | Twilio WhatsApp API | Meta Cloud API | p95 < 30s | |
| Voice call | S6+ | Twilio Voice | - | N/A (scheduled) |
Core Capabilities
1. Template Registry
- Namespaced template keys:
{service}.{event}.{channel}(e.g.,enrollment.created.email). - Versioned with semver; active + deprecated states.
- Multi-locale bodies (en, fr, sw, es, ar, hi, pt - expandable).
- MJML for email, plain Markdown for in-app, plain text with interpolation for SMS.
- Handlebars-compatible syntax with safe helpers only (no arbitrary JS eval).
- Preview + test-send endpoint for authors.
2. Preference Management
- Per-user, per-category, per-channel matrix.
- Categories:
academic(assignments, grades),billing,marketing,security,social,system. - Quiet hours respecting user's timezone.
- Global unsubscribe + per-category unsubscribe.
- Regulatory overrides: security notifications (MFA, password reset) and legal notices cannot be opted out.
- Parent/guardian contact routing for minors (COPPA compliance).
3. Digest & Throttling
- Rolling 15-min window per (user, category).
- If >N notifications of same category arrive in window, collapse into digest.
- Time-bucket delivery: daily digest at user-configured time (default 08:00 local).
- Rate limits per tenant per channel (prevents runaway billing from bad integration).
4. Webhook Management (outbound)
- Customers register webhook endpoints with event filters.
- HMAC-SHA256 signed bodies.
- Exponential backoff with DLQ after 6 failed attempts.
- Signing key rotation every 90 days.
5. Compliance Trail
- Every message stored 90 days (full body) + 7 years (metadata only).
- Right-to-erasure: scrub body, keep hashed audit stub.
- Unsubscribe tokens are signed, single-use, revocable.
What This Service Does NOT Do
- Does not generate notification content from AI (AI copy is produced by calling services via ai-gateway; we render & send).
- Does not own user contact info - we read it from identity-service via event projection.
- Does not store course or assignment data - we receive everything we need via events.
- Does not deliver in-app notifications as persistent feed entries beyond 30 days (moved to analytics-service cold storage).
Inputs & Outputs at a Glance
Ownership & Team
- Team: Platform Services squad (shared with media-service, search-service).
- On-call rotation: Platform Services PagerDuty schedule.
- SLA tier: Tier 2 (user-facing but not login-critical; degrades to "email-only" mode under pressure).
Cross-References
- DOMAIN_MODEL.md - aggregates, VOs, invariants
- EVENT_SCHEMAS.md - published + consumed event contracts
- API_CONTRACTS.md - REST endpoints
- SERVICE_READINESS.md - L0-L5 roadmap