--- id: TASK-17 title: Add Rybbit audit analytics dashboard status: In Progress assignee: [] created_date: '2026-06-03 19:14' updated_date: '2026-06-05 19:49' labels: - mvp - analytics - rybbit dependencies: - TASK-12 references: - PRD.md priority: medium ordinal: 17000 --- ## Description Display anonymous analytics for generated public audit pages inside the internal dashboard using the self-hosted Rybbit API. The internal dashboard itself is not tracked. Rybbit data is fetched per API on demand rather than regularly synchronized into Convex. ## Acceptance Criteria - [x] #1 Rybbit tracking runs only on public audit pages, not on internal dashboard routes - [x] #2 Dashboard can fetch Rybbit API data for pageviews, custom events, and outbound link clicks for audit pages - [x] #3 Per-audit analytics show opened yes/no, view count, last view, CTA clicks, website-link clicks, and device type where available - [ ] #4 Campaign analytics aggregate audit opens and CTA activity by campaign, niche, region, and timeframe - [x] #5 Rybbit API failures are shown gracefully and do not break the rest of the dashboard ## Implementation Plan 1. Add Rybbit tracking snippet or event calls only to public audit pages. 2. Add server-side Rybbit API client using secrets. 3. Build per-audit analytics panel in the dashboard. 4. Build campaign-level analytics summaries. 5. Add graceful loading, caching if useful, and error states for API failures. ## Implementation Notes Started implementation pass for Rybbit public-audit tracking and dashboard analytics surfaces. Implemented public-audit-only Rybbit tracking, on-demand Rybbit API routes for audit/campaign activity, per-audit summary helper, dashboard Rybbit error handling, and campaign-level overall Rybbit signals. AC4 remains open for full grouping by campaign/niche/region/timeframe because Rybbit events still need a stronger audit-to-campaign join model. Verification: pnpm test 305/305; pnpm lint 0 errors.