Include Loyalty/Communication/Sports Center backends and registry updates alongside production nginx and compose wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
171 lines
7.6 KiB
Markdown
171 lines
7.6 KiB
Markdown
# Phase 8 — Enterprise Communication Platform
|
||
|
||
| Field | Value |
|
||
| --- | --- |
|
||
| Status | Complete (validated) |
|
||
| Module | communication |
|
||
| Version | 0.8.10.1 |
|
||
| Database | `communication_db` |
|
||
| API Port | 8005 |
|
||
| ADR | ADR-001, ADR-003, ADR-006, ADR-012 |
|
||
|
||
## Goal
|
||
|
||
Build an **independent Enterprise Communication Platform** as shared infrastructure for the SuperApp.
|
||
|
||
Any tenant may activate **only** this service without subscribing to CRM, Loyalty, Restaurant, Sports, or other business modules.
|
||
|
||
All communication consumers interact exclusively through this service’s APIs and events. No module may talk to external providers directly.
|
||
|
||
## Scope Completed (8.0–8.10) + Validation Hardening
|
||
|
||
| Sub-phase | Deliverable |
|
||
| --- | --- |
|
||
| 8.0 Foundation | Service scaffold, health/capability APIs, permissions, events, repositories, DTOs, validators |
|
||
| 8.1 SMS Providers | Registry, priority, failover, retry, balance, sender numbers, **enforced** rate limits, circuit breaker |
|
||
| 8.2 Template Engine | Templates, variables, localization, approval, versioning, preview, rendering |
|
||
| 8.3 Dynamic Contact Sources | Manual, CSV, CRM/Loyalty/**Sports**/Restaurant/Marketplace/Accounting/Website/External REST — resolve only |
|
||
| 8.4 Queue Engine | Async queue, scheduling, priority, backoff retry, DLQ, batch, claim without burning attempts on rate-limit deferral |
|
||
| 8.5 Delivery Tracking | queued → sent → delivered / failed / expired / cancelled + timeline + provider logs |
|
||
| 8.6 OTP Platform | Business OTP only; Core auth OTP isolated; reserved purpose rejection |
|
||
| 8.7 Webhooks | Signature over canonical JSON body; external_id dedupe; delivery updates |
|
||
| 8.8 Multi Channel | Common API + unified router; SMS active; stubs for email/push/whatsapp/telegram/rubika/voice |
|
||
| 8.9 Monitoring | `/health`, `/health/ready`, `/capabilities`, `/metrics`, `/api/v1/monitoring/stats|metrics` |
|
||
| 8.10 + Validation | Idempotency (`correlation_id`+`to_address`), permission enforcement, indexes, GUID typing, enterprise test suite |
|
||
|
||
## Architecture
|
||
|
||
```
|
||
Business Modules ──API/Events──▶ Communication Service ──Provider Adapters──▶ External Gateways
|
||
│
|
||
├── Provider Framework
|
||
├── Communication Router (failover)
|
||
├── Template Engine
|
||
├── Contact Resolver (dynamic)
|
||
├── Queue Engine + DLQ + Rate Limit
|
||
├── Delivery Timeline + Metrics
|
||
└── OTP Platform (non-auth)
|
||
```
|
||
|
||
Layering: `API → Services → Repositories → Models`.
|
||
|
||
Database-per-service: `communication_db` only (ADR-001). Row-level `tenant_id` (ADR-003).
|
||
|
||
## Provider Framework
|
||
|
||
- Protocol: `ChannelProvider` (`send`, `get_balance`, `health_check`)
|
||
- Registry maps `provider_kind` → adapter
|
||
- Active SMS adapters: `mock`, `payamak`
|
||
- Stub adapters for future channels (no provider-specific code outside this service)
|
||
- Disable/fail one provider → router selects next by priority; queue continues; no duplicate on `correlation_id`
|
||
|
||
## Router Flow
|
||
|
||
1. Resolve body (raw or approved template)
|
||
2. Resolve destinations (manual and/or dynamic contact source)
|
||
3. Idempotency check on `(tenant_id, correlation_id, to_address)`
|
||
4. Enqueue message(s)
|
||
5. Claim by priority / `available_at` (Postgres `SKIP LOCKED`)
|
||
6. Apply channel rate limit (strictest provider limit); defer without burning attempts
|
||
7. Try providers ordered by `priority` (circuit-open skipped)
|
||
8. On failure → next provider (failover event)
|
||
9. Exhausted → failed; retries → DLQ
|
||
|
||
## Health, Capability & Metrics
|
||
|
||
| Method | Path | Notes |
|
||
| --- | --- | --- |
|
||
| GET | `/health` | Liveness |
|
||
| GET | `/health/ready` | DB readiness |
|
||
| GET | `/capabilities` | Channels, features, contact source types, independence |
|
||
| GET | `/metrics` | Service feature summary |
|
||
| GET | `/api/v1/providers/status` | Provider health/circuit |
|
||
| GET | `/api/v1/monitoring/stats` | Message/queue/provider snapshot |
|
||
| GET | `/api/v1/monitoring/metrics` | Latency, failure rate, rate-limit deferrals |
|
||
|
||
## Business Rules
|
||
|
||
1. Communication is completely independent.
|
||
2. Business modules communicate only through APIs and events.
|
||
3. No provider-specific code outside this service.
|
||
4. Dynamic contact sources never duplicate business data.
|
||
5. Provider failover is automatic.
|
||
6. Communication failures must never stop business transactions.
|
||
7. Health, Capability, and Metrics APIs are mandatory.
|
||
8. Tenant-specific providers, credentials, templates, and sender numbers.
|
||
9. Audit log for every message send.
|
||
10. Auth OTP stays on Core; Communication OTP rejects reserved Core purposes.
|
||
11. Reused `correlation_id` + destination is idempotent (no duplicate send).
|
||
|
||
## Events
|
||
|
||
| Event | Meaning |
|
||
| --- | --- |
|
||
| `communication.message.queued` | Enqueued (+ channel/to/correlation) |
|
||
| `communication.message.sent` | Accepted by provider |
|
||
| `communication.message.delivered` | Delivery confirmed |
|
||
| `communication.message.failed` | Terminal send failure |
|
||
| `communication.provider.failover` | Switched provider |
|
||
| `communication.otp.*` | OTP lifecycle |
|
||
| `communication.queue.dead_letter` | DLQ |
|
||
| `communication.webhook.received` | Inbound webhook |
|
||
|
||
## Permissions
|
||
|
||
Enforced via `require_permissions` (admin roles bypass). Trees under `communication.*`.
|
||
|
||
## APIs (selected)
|
||
|
||
| Area | Prefix |
|
||
| --- | --- |
|
||
| Providers / senders | `/api/v1/providers` |
|
||
| Templates | `/api/v1/templates` |
|
||
| Contacts / sources | `/api/v1/contacts` |
|
||
| Messages / queue | `/api/v1/messages` |
|
||
| OTP | `/api/v1/otp` |
|
||
| Webhooks | `/api/v1/webhooks` |
|
||
| Monitoring | `/api/v1/monitoring` |
|
||
|
||
## Tests
|
||
|
||
Architecture, health/ready/security, providers/SMS/failover cascade, queue/DLQ, rate limit, idempotency, templates, dynamic contacts (incl. sports), OTP isolation, webhooks, metrics, concurrency, validators, migration, permissions, documentation — **42 passing**.
|
||
|
||
## Integration Boundaries
|
||
|
||
| Consumer | Integration |
|
||
| --- | --- |
|
||
| Core / Identity | Auth OTP remains on Core; no shared OTP tables |
|
||
| CRM / Loyalty / Sports / Restaurant / Marketplace / Accounting | Contact resolve via HTTP APIs only; messaging via Communication APIs/events |
|
||
| AI / Storage / Notification | No ownership; Notification may later consume Communication events |
|
||
| Future modules | Pluggable via public APIs + events; no internal code changes required |
|
||
|
||
## Known Limitations
|
||
|
||
- Email / Push / WhatsApp / Telegram / Rubika / Voice remain architecture-ready stubs.
|
||
- Continuous Celery worker drain is optional ops work (API/`process_immediately` covers correctness).
|
||
- Real message bus consumers not wired (publish-only envelopes).
|
||
- Sender unique constraint is not soft-delete-aware (recreate after soft-delete may conflict).
|
||
|
||
## Audit Report
|
||
|
||
See [communication-phase-8-audit.md](communication-phase-8-audit.md).
|
||
|
||
## Completion Checklist
|
||
|
||
- [x] Code completed (8.0–8.10)
|
||
- [x] Enterprise validation + self-heal cycle
|
||
- [x] Tests passed (42)
|
||
- [x] Documentation updated
|
||
- [x] ADR-012 referenced
|
||
- [x] Module Registry updated
|
||
- [x] Progress updated
|
||
- [x] No TODO remains
|
||
|
||
## Related Documents
|
||
|
||
- [Progress](progress.md)
|
||
- [Module Registry](module-registry.md)
|
||
- [Audit Report](communication-phase-8-audit.md)
|
||
- [ADR-012](architecture/adr/ADR-012.md)
|
||
- [Service README](../backend/services/communication/README.md)
|