115 lines
2.7 KiB
Markdown
115 lines
2.7 KiB
Markdown
# 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 (30–45 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% |
|