warmbox/docs/12-architecture.md

4 KiB
Raw Blame History

System Architecture

Deployment model (hybrid)

Phase 12: Self-hosted single-tenant (FillCare) with web UI
Phase 3+: Multi-tenant SaaS on shared infrastructure

Design all entities with optional workspaceId from day one.

High-level architecture

flowchart TB
    subgraph client [Client Layer]
        WebUI[Web Dashboard]
        API_Consumers[API / CLI]
    end

    subgraph app [Application Layer]
        API[Express API]
        Auth[Auth Middleware]
        CampaignSvc[Campaign Service]
        RecipeSvc[Recipe Engine]
        StatsSvc[Statistics Service]
        ContentSvc[AI Content Service]
    end

    subgraph workers [Worker Layer]
        Scheduler[Cron Scheduler]
        SendWorker[Send Queue Worker]
        RescueWorker[Rescuer Worker]
        StatsWorker[Stats Rollup Worker]
    end

    subgraph connectors [Connectors]
        SMTP[nodemailer]
        IMAP[imapflow]
        AI[OpenRouter]
    end

    subgraph data [Data Layer]
        DB[(SQLite → Postgres)]
        Queue[(Job Queue)]
    end

    WebUI --> API
    API_Consumers --> API
    API --> Auth
    API --> CampaignSvc
    API --> StatsSvc
    Scheduler --> SendWorker
    Scheduler --> RescueWorker
    SendWorker --> SMTP
    SendWorker --> ContentSvc
    ContentSvc --> AI
    RescueWorker --> IMAP
    RescueWorker --> ContentSvc
    workers --> DB
    API --> DB
    SendWorker --> Queue

Component responsibilities

Component Responsibility
API CRUD mailboxes, campaigns, settings; stats queries
Campaign Service Lifecycle: draft → active → paused → completed
Recipe Engine Compute DailySchedule from recipe params
Dispatcher / Send Worker Enqueue sends with jitter; role-aware pairing
Rescuer Worker IMAP spam scan, rescue, reply sampling
AI Content Service Generate + validate email bodies
Stats Service Aggregations, rollups, on-track calculation
Scheduler Cron triggers; reload on settings change

Data store evolution

Phase Database Queue
MVP (now) SQLite In-process cron
Phase 2 SQLite SQLite-backed queue or BullMQ
SaaS PostgreSQL Redis + BullMQ

Use Prisma driver adapters; swap datasource URL for Postgres.

Multi-tenant (future)

flowchart LR
    subgraph tenantA [Workspace A]
        A1[Primary]
        A2[Satellites]
    end
    subgraph tenantB [Workspace B]
        B1[Primary]
        B2[Satellites]
    end
    API --> tenantA
    API --> tenantB
  • Row-level isolation via workspaceId
  • JWT auth with workspace scope
  • Encrypted credentials per workspace key (KMS in SaaS)
Layer Tech options
Framework Next.js or Vite + React
UI shadcn/ui + Tailwind
Data TanStack Query
Charts Recharts
Auth Clerk / Auth.js (SaaS)

Serve as separate app or static build proxied by Express.

Observability

Concern Tool
Logs Pino (existing)
Errors Sentry
Metrics Prometheus / Grafana (SaaS)
Job tracing Correlation ID per send

Security boundaries

  • Credentials encrypted at rest (AES-256-GCM)
  • API key (self-hosted) → JWT (SaaS)
  • No plaintext passwords in logs
  • IMAP/SMTP connections TLS-only

Integration points (external)

System Integration Phase
Instantly / Smartlead Read-only: pause warmup when they send 3
Google Postmaster Pull domain stats 3
Webhooks Campaign events 2
Stripe Billing per primary SaaS

Directory structure (target)

warmbox/
├── apps/
│   ├── api/          # Express (current src/)
│   └── web/          # Dashboard
├── packages/
│   ├── database/     # Prisma schema
│   ├── recipe-engine/
│   └── content-validator/
├── docs/
└── prisma/

Monorepo optional; single package acceptable through phase 2.