warmbox/docs/sprints/sprint-1.1.md

3.7 KiB
Raw Permalink Blame History

Sprint 1.1 — Domain Model, Grow Recipe, AI Validator

Status: Implemented
Epics: E1, E2 (Grow subset), E6

Goal

Campaign-centric warmup model with workspace scoping, Grow recipe schedules, and AI content validation — without campaign-aware sending yet.

Acceptance checklist

  • Default workspace exists; all inboxes scoped to workspace
  • Create primary + satellites via API with google_workspace provider preset
  • Create campaign; assign shared satellite across primaries in same workspace
  • POST /api/campaigns/:id/start generates durationDays DailySchedule rows
  • POST /api/recipes/preview returns Grow ramp
  • POST /api/campaigns/:id/pause / resume lifecycle
  • transitionToMaintenance() adds 20% maintenance schedule row
  • AI content validator rejects placeholders, spam triggers, URLs
  • Legacy flat dispatcher skipped when any campaign exists
  • npm run build and npm test pass

New API endpoints

Method Path
POST/GET/PATCH/DELETE /api/campaigns
POST /api/campaigns/:id/start
POST /api/campaigns/:id/pause
POST /api/campaigns/:id/resume
GET/POST/DELETE /api/campaigns/:id/satellites
POST /api/recipes/preview
GET /api/recipes/templates
POST /api/ai/test-generate
* /api/mailboxes (alias of /api/inboxes)

Manual QA script

# Start server
npm run dev

# 1. Primary (Google Workspace preset — any email)
curl -s -X POST http://localhost:3000/api/inboxes \
  -H "Content-Type: application/json" \
  -d '{
    "email": "hello@yourdomain.com",
    "provider": "google_workspace",
    "username": "hello@yourdomain.com",
    "password": "your-app-password",
    "role": "primary",
    "industry": "Childcare",
    "senderName": "Jon",
    "companyName": "FillCare"
  }'

# 2. Satellites (repeat for 2+ accounts)
curl -s -X POST http://localhost:3000/api/inboxes \
  -H "Content-Type: application/json" \
  -d '{
    "email": "satellite@gmail.com",
    "provider": "gmail",
    "username": "satellite@gmail.com",
    "password": "app-password",
    "role": "satellite"
  }'

# 3. Preview Grow ramp
curl -s -X POST http://localhost:3000/api/recipes/preview \
  -H "Content-Type: application/json" \
  -d '{"recipe":"grow","durationDays":30,"minEmailsPerDay":1,"maxEmailsPerDay":40,"replyRatePercent":30}'

# 4. Create campaign (use IDs from step 12)
curl -s -X POST http://localhost:3000/api/campaigns \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Primary warmup",
    "primaryMailboxId": "<PRIMARY_ID>",
    "recipe": "grow",
    "durationDays": 30,
    "satelliteMailboxIds": ["<SAT1_ID>", "<SAT2_ID>"]
  }'

# 5. Start campaign → verify 30 schedule rows
curl -s -X POST http://localhost:3000/api/campaigns/<CAMPAIGN_ID>/start
curl -s http://localhost:3000/api/campaigns/<CAMPAIGN_ID> | jq '.dailySchedules | length'

# 6. Pause
curl -s -X POST http://localhost:3000/api/campaigns/<CAMPAIGN_ID>/pause

# 7. Test AI validator (requires AI_API_KEY)
curl -s -X POST http://localhost:3000/api/ai/test-generate \
  -H "Content-Type: application/json" \
  -d '{"industry":"Childcare","senderName":"Jon","companyName":"FillCare"}'

Out of scope (Sprint 1.3+)

  • Campaign-aware dispatcher sends
  • Reply rate sampling
  • Statistics dashboard API
  • Flat / Randomized / Custom recipes

Key files