New 1:N email-campaign module (newsletters / announcements). M1 scope:
- types (LocalCampaign / LocalBroadcastTemplate / LocalBroadcastSettings),
constants (STATUS_LABELS, BROADCAST_SETTINGS_ID, rate-limit hints)
- collections.ts: Dexie table refs, no guest seed (a demo campaign that
might accidentally hit real SMTP felt wrong)
- module.config registered in module-registry
- Dexie v32 wired in (already in tree from a parallel Spaces commit
picking it up via lint-staged — matches what the module expects)
- encryption registry entries for all three tables (type-safe via
entry<T>), content + audience always encrypted because the recipient
graph is a leakable business secret
- app entry (requiredTier: alpha) + megaphone gradient icon
(indigo→cyan, sits between mail and invoices in the comm family)
- route /broadcasts mounts ListView with empty-state placeholder
Status machine defined: draft → scheduled → sending → sent, with
cancelled as the off-ramp from draft/scheduled. No CRUD yet — that's M2.
Plan: docs/plans/broadcast-module.md.
Next: M2 AudienceBuilder + Tiptap editor.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>