5.2 KiB
Enterprise migration: @suaveplan/sms
- Change ID:
enterprise-sms - Status: PROPOSED
- Capability:
sms - Target package:
@suaveplan/smsat0.1.0 - Target path:
packages/communication/messaging/sms/ - Design: ./design.md
- Spec delta: ./specs/sms/spec.md
- Source on main:
/mnt/s/web/suaveplan/packages/server/sms(~1389 LOC) - Enterprise plan:
/mnt/s/web/suaveplan/enterprise/sms.md
Why
@suaveplan/sms is the universal SMS core: a provider-agnostic
sending pipeline with template rendering, opt-out management, rate
limiting, scheduling, retry, and delivery tracking. Providers
(Twilio, Vonage, MessageBird, AWS SNS, in-house gateways) plug into
the abstract SmsProvider contract.
The upstream package (v1.0.2) is functionally narrow — provider
seam, template render, opt-out list, four events — but is missing
every enterprise lever the genesis tree commits to:
BaseErrorlegacy hierarchy instead ofdefineCodes("SMS", [...]).- No Zod boundary on
SmsMessage,SmsTemplate,SmsProviderinputs. - No OpenTelemetry counters or histograms.
- No retry/backoff on transient provider failures.
- No scheduling (
sendAt) or batched dispatch. - No rate limiting per provider / per recipient.
- No delivery-receipt ingest pipeline; status is fetched on demand.
- No
AbortSignalpropagation on send / scheduler / status pulls. - No in-memory test provider; tests use ad-hoc anonymous mocks.
- One global event-emitter shape; no typed
EventBusbridge. - Tests pass with vi-mocks (
@suaveplan/testingvi.fn()) — fine for unit harnesses, but the package never exercises a real provider round-trip end-to-end.
This change rewrites the package on genesis at enterprise quality
while preserving every upstream export, then layers the SMS-core
features (MessageScheduler, RateLimiter, DeliveryTracker,
RetryPolicy, OTel instruments, Zod boundaries, abort signals,
EventBus bridge, in-memory test provider).
Parity Checklist
| Capability | Upstream | Migrated | Notes |
|---|---|---|---|
SmsService send / template render / opt-out |
✅ | ✅ | Preserved verbatim, plus rate-limit + abort + retry on top. |
SmsProvider abstract contract |
✅ | ✅ | Preserved (name, send, getStatus). |
SmsTemplate ({{var}} substitution) |
✅ | ✅ | Preserved + defaults map + escape pass. |
SmsMessage / SmsDeliveryReport / SmsDeliveryStatus |
✅ | ✅ | Preserved + Zod schemas. |
OptOutEntry registry |
✅ | ✅ | Preserved + bulk import / export. |
SmsEventMap (sms.sent/delivered/failed/opted_out/opted_in) |
✅ | ✅ | Preserved + new sms.scheduled / sms.retry / sms.rate_limited. |
Legacy EventEmitter surface (on/off/emit) |
✅ | ✅ | Preserved (delegates to typed EventBus). |
SmsError legacy class + factory methods |
✅ | ✅ | Preserved as back-compat alias over genesis defineCodes family. |
respondProblemJson Hono helper |
✅ | ✅ | Preserved. |
registerSmsErrorCodes / SMS_ERROR_METADATA |
✅ | ✅ | Preserved via genesis ErrorCodes.registerMany. |
Stable SMS.* defineCodes registry |
🚫 (legacy BaseError) |
⬆️ | Genesis addition. |
| Zod boundary on every public input | 🚫 | ⬆️ | Genesis addition. |
| OTel counters + histogram | 🚫 | ⬆️ | Genesis addition (4 instruments). |
MessageScheduler (sendAt + cancel) |
🚫 | ⬆️ | Genesis addition. |
RateLimiter (token bucket per recipient) |
🚫 | ⬆️ | Genesis addition. |
DeliveryTracker (receipt ingest + cache) |
🚫 | ⬆️ | Genesis addition. |
RetryPolicy (exponential backoff w/ jitter) |
🚫 | ⬆️ | Genesis addition. |
InMemorySmsProvider (test provider) |
🚫 | ⬆️ | Genesis addition; replaces ad-hoc test mocks. |
AbortSignal propagation |
🚫 | ⬆️ | Genesis addition. |
| 100/100/100/100 coverage | 🚫 | ⬆️ | Genesis gate. |
What
A net-new package at packages/communication/messaging/sms/ at
0.1.0, universal tier (no Node/Bun-only APIs), Zod-validated
boundaries, OTel-instrumented, with the full upstream public
surface plus the genesis enterprise additions.
This is the SMS core — not the providers package. The abstract
SmsProvider interface ships with an in-memory test provider
(InMemorySmsProvider) so consumers and integration tests can run
without external services. Concrete provider integrations
(Twilio, Vonage, AWS SNS) ship in the sibling @suaveplan/sms-providers
package next wave.
Impact
Affected dependents
Run bunx turbo ls --filter=...@suaveplan/sms to enumerate.
No genesis package currently imports @suaveplan/sms:
@suaveplan/sms-providers— pending migration, will consume this asworkspace:^0.1.0. [x] no action needed (reason: package not yet on genesis)@suaveplan/api-plugin-messaging— pending migration. [x] no action needed (reason: package not yet on genesis)
Foundation deps (@suaveplan/error, @suaveplan/events,
@suaveplan/types) are read-only consumers; no change required.
Out of scope
Nothing. Per feedback_no_deferrals_on_migration.md and AGENTS §2b,
no "phase 2" is permitted. The whole upstream surface plus the
enterprise additions land here, feature-complete, with
100/100/100/100 coverage.