Files
2026-05-27 23:29:53 +01:00

45 lines
1.8 KiB
Markdown

# OpenSpec Change: enterprise-suppression
- **Change ID**: enterprise-suppression
- **Package**: `@suaveplan/suppression`
- **Category**: universal
- **Target path**: `universal/email/suppression`
- **Status**: PROPOSED
- **Date**: 2026-04-19
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/suppression.md`
## Summary
Email suppression list manager — classifies bounces, records unsubscribes, filters outgoing sends, and generates signed one-click unsubscribe links per RFC 8058. Pluggable store.
## Current-state audit (genesis)
Package does not exist yet — fresh build.
## Dependencies
- Workspace: `@suaveplan/error`, `@suaveplan/events`, `@suaveplan/types`
- External (via catalog): `zod`, `tslib`, `@opentelemetry/api`
- Dev (via catalog): `vitest`, `@vitest/coverage-istanbul`, `fast-check`, `mitata`
## Preserved public surface (star-exported from main)
- `BounceClassifier`, `classifyBounce`, `BounceType`
- `SuppressionFilter` — filters an outgoing send list against the store.
- `SuppressionManager` — CRUD over suppressions with reason tagging.
- `UnsubscribeLink` — `generateLink`, `verifyLink`, `rotateSecret`.
- `SuppressionStore` interface + `MemorySuppressionStore`.
- Types: `SuppressionReason`, `SuppressionEntry`, `BounceReport`, `FilterResult`, `LinkOptions`.
## New genesis additions
- Codes: `SUPPRESSION.INVALID_ADDRESS`, `SUPPRESSION.STORE_ERROR`, `SUPPRESSION.LINK_EXPIRED`, `SUPPRESSION.LINK_INVALID_SIGNATURE`.
- Zod schemas for every type.
- OTel counter `suppression.filter.total{outcome}`, `suppression.suppressed.total{reason}`.
- Property tests: every classified hard bounce remains suppressed; round-trip of `generateLink → verifyLink`.
## Impact
- Adds one new package: `universal/email/suppression`
- Adds one new spec capability: `suppression`