3.7 KiB
3.7 KiB
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_workspaceprovider preset - Create campaign; assign shared satellite across primaries in same workspace
POST /api/campaigns/:id/startgeneratesdurationDaysDailySchedule rowsPOST /api/recipes/previewreturns Grow rampPOST /api/campaigns/:id/pause/resumelifecycletransitionToMaintenance()adds 20% maintenance schedule row- AI content validator rejects placeholders, spam triggers, URLs
- Legacy flat dispatcher skipped when any campaign exists
npm run buildandnpm testpass
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 1–2)
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