warmbox/docs/10-statistics-and-reporting.md

115 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Statistics & Reporting
## Operator questions the dashboard must answer
1. How many emails are **scheduled** today for each primary?
2. How many were **sent** today?
3. How many were **replied** today?
4. How many landed in **spam** vs inbox?
5. Is warmup **on track** for the recipe?
6. Are any mailboxes in **error**?
## Per-primary campaign dashboard
### Summary cards
| Card | Source |
|------|--------|
| Campaign day | `currentDay / durationDays` |
| Today's sends | `actualSends / plannedSends` |
| Today's replies | `actualReplies / plannedReplies` |
| Inbox rate (7d) | `DailyStat` rollup |
| Spam rescues (7d) | Sum `spamRescued` |
| Status | active / paused / error |
### Time series charts (3045 day window)
| Chart | Series |
|-------|--------|
| Volume | planned vs actual sends |
| Engagement | replies, rescues |
| Placement | inbox % vs spam % |
| Ramp progress | cumulative sends vs recipe curve |
### Tables
| Table | Columns |
|-------|---------|
| Recent activity | time, satellite, subject, status, placement |
| Satellite health | email, status, last send, last error |
| Daily breakdown | date, sent, replied, spam, inbox rate |
## API endpoints (target)
```
GET /api/campaigns/:id/stats?range=7d|30d|all
GET /api/campaigns/:id/stats/today
GET /api/campaigns/:id/stats/daily?from=&to=
GET /api/mailboxes/:id/stats
GET /api/workspace/overview
```
### Response example (`/stats/today`)
```json
{
"campaignId": "...",
"date": "2026-06-20",
"dayIndex": 12,
"planned": { "sends": 18, "replies": 6 },
"actual": { "sends": 15, "replies": 5, "spamDetected": 2, "spamRescued": 2 },
"rates": { "reply": 33.3, "inbox": 86.7 },
"recipe": "grow",
"onTrack": true
}
```
## Aggregation strategy
### Real-time counters
Update `DailySchedule.actualSends` on each successful send (transactional).
### Nightly rollup
Job at 00:05 campaign TZ:
- Finalize yesterday's `DailyStat`
- Compute 7d rolling averages
- Evaluate auto-pause rules
### Materialized vs computed
| Metric | Strategy |
|--------|----------|
| Today's counts | Real-time counters |
| Historical | `DailyStat` table |
| Inbox rate | `PlacementEvent` aggregation |
| Recipe curve overlay | Computed from `DailySchedule` |
## Export
- CSV export of daily stats
- JSON export for BI (future)
## Alerts (phase 2)
| Alert | Channel |
|-------|---------|
| Spam rate threshold | Email, webhook |
| Mailbox error | Email, in-app |
| Campaign completed | In-app |
| Ramp behind schedule | In-app |
## FillCare example view
**hello@fillcareapp.com — Day 12/30 — Grow**
| Metric | Value |
|--------|-------|
| Scheduled today | 18 |
| Sent | 15 |
| Replied | 5 (33%) |
| Spam detected | 2 |
| Spam rescued | 2 |
| Inbox rate (7d) | 94% |