Architecture boundaries
- Keep contacts and campaign leads separated.
- Keep campaign CRM state out of the master contacts database.
- Preserve the lightweight MVP direction: no Celery, Redis, WebSockets, or persistent background workers for now.
- Prefer centered app modals, CSS toasts, inline updates, and dynamic table rendering over full-page jumps for simple actions.
API patterns
Frontend JavaScript should consume predictable route patterns.
/api/contacts/
/api/contacts/upload/
/api/campaigns/
/api/campaigns/{id}/launch/
/api/campaigns/{id}/fetch-replies/
/api/mailboxes/{id}/test-smtp/
/api/billing/change-plan/
Future notes
- Open-rate tracking uses a small per-message tracking pixel and records the first open against the campaign activity.
- Dodo webhooks should be added when the app has a public domain.
- Third-party contact imports can be added after core upload flows are stable.
- Future API access and team support belong to Pro-level product expansion.