44 lines
1.4 KiB
Markdown
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`
|