Files
analytics/PLAN.md
T

214 lines
10 KiB
Markdown
Raw Normal View History

2026-03-18 11:06:13 +02:00
# Analytics Platform — Implementation Plan
## Current State
The foundation is in place: 7 models with migrations (`Website`, `Visitor`, `AnalyticsSession`, `PageView`, `Event`, `Goal`, `GoalConversion`), a JavaScript tracker served dynamically per tracking ID, and a `POST /api/collect` endpoint that ingests page views and events. No authentication, no dashboard, no frontend yet.
---
## Phase 1: Authentication & Website Management
The platform needs user accounts and CRUD for tracked websites before anything else is usable.
2026-03-18 11:21:51 +02:00
- [x] Install Laravel Breeze (or Fortify) for registration, login, password reset, email verification
2026-03-18 11:40:20 +02:00
- [x] Build a `WebsiteController` with full CRUD (index, create, store, show, edit, update, destroy)
- [x] Create views/pages: list of websites, add/edit website form, website settings page
- [x] Build the "embed snippet" page — show the user the `<script>` tag to copy for each website
- [x] Add form request validation (`StoreWebsiteRequest`, `UpdateWebsiteRequest`)
- [x] Scope all website queries to `auth()->user()` (policy or middleware)
- [x] Add a `WebsitePolicy` to authorize show/edit/delete actions
2026-03-18 11:06:13 +02:00
---
## Phase 2: Dashboard — Real-Time Overview
The main dashboard a user sees after selecting a website, showing key metrics at a glance.
2026-03-18 12:18:07 +02:00
- [x] Create `DashboardController` scoped to a single website
- [x] Build a date-range picker component (today, last 7 days, last 30 days, custom range)
- [x] **Metric cards** — display for the selected period:
2026-03-18 11:06:13 +02:00
- Total page views
- Unique visitors
- Total sessions
- Bounce rate (% of sessions with 1 page view)
- Average session duration
- Average pages per session
2026-03-18 12:18:07 +02:00
- [x] **Visitors chart** — line/area chart of visitors and page views over time (daily or hourly granularity)
- [x] **Real-time widget** — show active visitors in the last 5 minutes (poll or WebSocket)
- [x] Create an `AnalyticsQueryService` (or similar) to encapsulate all aggregation queries, keeping controllers thin
2026-03-18 11:06:13 +02:00
---
## Phase 3: Detailed Reports
Individual report pages accessible from the dashboard sidebar.
### 3a — Audience Reports
2026-03-18 13:32:36 +02:00
- [x] **Geographic report** — visitors by country, region, city (table + world map visualization)
- [x] **Technology report** — breakdown by browser, OS, device type, screen resolution
- [x] **Language report** — visitors by browser language
- [x] **New vs. returning visitors** — segment visitors who have more than one session
2026-03-18 11:06:13 +02:00
### 3b — Acquisition Reports
2026-03-18 13:32:36 +02:00
- [x] **Traffic sources** — breakdown by referrer domain (direct, organic, referral, social)
- [x] **Campaigns (UTM)** — table of sessions grouped by `utm_source`, `utm_medium`, `utm_campaign`
- [x] **Referrers** — top referring URLs and domains
2026-03-18 11:06:13 +02:00
### 3c — Behavior Reports
2026-03-18 13:32:36 +02:00
- [x] **Pages report** — top pages by views, unique views, avg. time on page, bounce rate
- [x] **Landing pages** — top entry pages with session count and bounce rate
- [x] **Exit pages** — top exit pages
2026-03-18 11:06:13 +02:00
- [ ] **User flow** — simplified Sankey or funnel showing common page sequences (can be deferred)
### 3d — Events Report
2026-03-18 13:32:36 +02:00
- [x] **Events overview** — table of events grouped by name, category, action
- [x] **Event detail** — drill-down into a single event name with label/value breakdown
- [x] **Event trending** — chart of event counts over time
2026-03-18 11:06:13 +02:00
---
## Phase 4: Goals & Conversions
Allow users to define goals and track conversion rates.
2026-03-18 16:59:39 +02:00
- [x] Build `GoalController` CRUD (create, edit, delete goals per website)
- [x] Support goal types:
2026-03-18 11:06:13 +02:00
- **URL destination** — session visited a specific path
- **Event match** — a specific event name/category was fired
- **Duration** — session lasted longer than N seconds
- **Pages per session** — session hit N+ page views
2026-03-18 16:59:39 +02:00
- [x] Create a `GoalEvaluationService` that checks incoming data against active goals and records `GoalConversion` entries
- [x] Hook goal evaluation into `CollectController` after recording page view / event
- [x] Build a **Conversions report** — goal completion count, conversion rate (completions / sessions), goal value totals
- [x] Add goal completion sparklines to the main dashboard
2026-03-18 11:06:13 +02:00
---
## Phase 5: Collection Pipeline Hardening
The `CollectController` currently does synchronous DB writes. This won't scale under real traffic.
2026-03-19 12:21:01 +02:00
- [x] Move ingestion to a queued job (`ProcessTrackingPayload`) dispatched from the controller so the endpoint returns instantly
- [x] Add rate limiting middleware to `POST /api/collect` (e.g., 120 req/min per IP)
- [x] Add CORS headers to the collect endpoint so browsers allow cross-origin beacons
- [x] Validate the incoming `referrer` / `url` against the website's `domain` to reject spoofed traffic
- [x] Add IP-based geolocation (use MaxMind GeoLite2 via `stevebauman/location`) to populate `country`, `region`, `city` on the `Visitor`
- [x] Handle bot filtering — skip known bot user agents (using `jaybizzle/crawler-detect`)
- [x] Add a `tracking_pixel` endpoint (1x1 GIF) as a no-JS fallback
2026-03-18 11:06:13 +02:00
---
## Phase 6: Data Aggregation & Performance
Raw event tables grow fast. Pre-aggregate data for fast dashboard loads.
2026-03-19 14:53:54 +02:00
- [x] Create `daily_aggregates` table (migration + model):
2026-03-18 11:06:13 +02:00
- `website_id`, `date`, `visitors`, `sessions`, `page_views`, `bounce_count`, `total_duration`
2026-03-19 14:53:54 +02:00
- [x] Create `page_daily_aggregates` table:
2026-03-18 11:06:13 +02:00
- `website_id`, `date`, `path`, `views`, `unique_views`, `total_time_on_page`, `bounces`
2026-03-19 14:53:54 +02:00
- [x] Create a scheduled Artisan command (`analytics:aggregate`) that rolls up yesterday's raw data into aggregate tables — run daily via `schedule:run`
- [x] Refactor dashboard and report queries to read from aggregates for past days, and query raw tables only for "today"
- [x] Add database indexes review — ensure all date-range + website_id queries are covered
- [x] Add `data_retention_days` setting per website (stored in `settings` JSON) and a cleanup command (`analytics:purge`) to purge old raw rows
2026-03-18 11:06:13 +02:00
---
## Phase 7: Frontend & UI
Choose a frontend approach and build a polished interface.
2026-03-19 18:42:19 +02:00
- [x] Pick a stack:
- **Option A:** Blade + Alpine.js (server-rendered, simpler) — selected
- [x] Install Tailwind CSS (already in the Laravel scaffold via Vite) + Inter font
- [x] Build a **layout** with sidebar navigation (websites list, reports sections) and top bar (date picker, user menu)
- [x] Integrate a charting library (Chart.js + chartjs-chart-geo) for:
2026-03-18 11:06:13 +02:00
- Line charts (visitors over time)
2026-03-19 18:42:19 +02:00
- Bar charts (top pages, browsers, sources)
- Pie/donut charts (device type, traffic source split, new vs returning)
- World map (geographic report — choropleth)
- [x] Build **comparison mode** — compare current period vs. previous period with delta percentages on metric cards
- [x] Add loading states, empty states, and error handling throughout
- [x] Make the dashboard responsive (mobile-friendly) — collapsible sidebar with overlay on mobile
2026-03-18 11:06:13 +02:00
---
2026-03-19 18:42:19 +02:00
## Phase 8: API for Programmatic Access ✅
2026-03-18 11:06:13 +02:00
Let users pull their analytics data via an API.
2026-03-19 18:42:19 +02:00
- [x] Create API token management (Laravel Sanctum) — UI page to generate/revoke API tokens
- [x] Build versioned API routes (`/api/v1/...`)
- [x] Endpoints:
2026-03-18 11:06:13 +02:00
- `GET /api/v1/websites` — list websites
- `GET /api/v1/websites/{id}/stats` — summary metrics with date-range params
- `GET /api/v1/websites/{id}/pages` — top pages
- `GET /api/v1/websites/{id}/referrers` — traffic sources
- `GET /api/v1/websites/{id}/events` — events report
- `GET /api/v1/websites/{id}/visitors` — audience breakdown
2026-03-19 18:42:19 +02:00
- [x] Add API resource classes for consistent JSON formatting
- [x] Rate limit API endpoints per token
2026-03-18 11:06:13 +02:00
---
2026-03-19 18:42:19 +02:00
## Phase 9: Advanced Features ✅
2026-03-18 11:06:13 +02:00
Features that differentiate from a basic analytics tool.
2026-03-19 18:42:19 +02:00
- [x] **Funnels** — let users define a sequence of pages/events and visualize drop-off at each step
- [x] **Segments** — filter all reports by visitor attributes (e.g., mobile users from Germany)
- [x] **Custom dashboards** — let users pin specific widgets/reports to a custom overview
- [x] **Alerts / Notifications** — notify users when traffic spikes, drops, or a goal hits a threshold (email and/or in-app)
- [x] **Data export** — CSV/PDF export for any report
- [x] **UTM builder** — in-app tool to generate campaign URLs with UTM parameters
- [x] **Annotations** — let users add notes on specific dates (e.g., "launched ad campaign") visible on charts
2026-03-18 11:06:13 +02:00
---
2026-03-19 18:54:50 +02:00
## Phase 10: Testing & Quality ✅
- [x] Write Feature tests for `CollectController` (valid payloads, invalid tracking IDs, rate limiting)
- [x] Write Feature tests for `WebsiteController` CRUD and authorization
- [x] Write Unit tests for `AnalyticsQueryService` aggregation logic
- [x] Write Unit tests for `GoalEvaluationService`
- [ ] Write browser tests (Dusk) for dashboard interactions and date picker (deferred — requires Dusk package + browser driver)
- [x] Add CI pipeline (GitHub Actions): run tests, Pint linting, Larastan static analysis
- [x] Create model factories for all analytics models
- [x] Fix base Controller `AuthorizesRequests` trait
- [x] Fix DailyAggregate/PageDailyAggregate date cast for SQLite compatibility
2026-03-18 11:06:13 +02:00
---
## Phase 11: Deployment & Operations
- [ ] Set up production database (PostgreSQL recommended for analytical queries, or MySQL)
- [ ] Configure queue worker (Redis + Horizon) for async ingestion jobs
- [ ] Set up the scheduler (`php artisan schedule:run`) for daily aggregation
- [ ] Configure caching (Redis) for dashboard queries and script delivery
- [ ] Set up HTTPS and CDN for the tracker JS file
- [ ] Add application monitoring (Sentry or similar for error tracking)
- [ ] Configure backups for the database
- [ ] Write a deployment script or use Laravel Forge / Vapor
---
## Suggested Order of Execution
| Priority | Phase | Reason |
|----------|-------|--------|
| 1 | Phase 1 | Can't use anything without auth and website management |
| 2 | Phase 7 (partial) | Pick frontend stack and build layout early — everything else renders into it |
| 3 | Phase 2 | The dashboard is the core product |
| 4 | Phase 5 | Harden collection before driving real traffic |
| 5 | Phase 3 | Detailed reports give the platform actual value |
| 6 | Phase 4 | Goals & conversions are a key differentiator |
| 7 | Phase 6 | Aggregation becomes necessary as data grows |
| 8 | Phase 10 | Tests before shipping to production |
| 9 | Phase 8 | API access for power users |
| 10 | Phase 9 | Advanced features for product maturity |
| 11 | Phase 11 | Production deployment |