warmbox/docs/sprints/sprint-1.5.md

44 lines
1.4 KiB
Markdown

# Sprint 1.5 — Stats API
Operator-visible campaign metrics via REST, backed by real-time `DailySchedule` counters and nightly `DailyStat` rollups.
## What shipped
- **`DailyStat` model** — materialized daily rollups with `replyRateActual`, `inboxPlacementRate`
- **`stats.service.ts`** — today, daily time series, range summary, workspace overview
- **Stats routes:**
- `GET /api/campaigns/:id/stats/today`
- `GET /api/campaigns/:id/stats/daily?from=&to=`
- `GET /api/campaigns/:id/stats?range=7d|30d|all`
- `GET /api/workspace/overview`
- **`stats-rollup.job.ts`** — hourly cron, finalizes yesterday at 00:xx campaign TZ
- **`POST /api/jobs/rollup/run`** — manual rollup trigger
- **Logs filter** — `GET /api/logs?campaignId=`
## Response example (`/stats/today`)
```json
{
"campaignId": "...",
"date": "2026-06-25",
"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
}
```
## FillCare manual QA
1. Active Grow campaign with sends in progress
2. `GET /api/campaigns/:id/stats/today` — verify planned vs actual
3. `GET /api/workspace/overview` — see hello@ primary at a glance
4. Compare stats counts to `GET /api/logs?campaignId=:id`
## Key files
- `src/services/stats.service.ts`
- `src/jobs/stats-rollup.job.ts`
- `src/routes/stats.routes.ts`