Skip to content

Add Analytics Pipeline for watched_50_percent Video Events #49

@adithya1012

Description

@adithya1012

📌 Description

We need to implement a scalable analytics pipeline to track video engagement events, starting with a watched_50_percent event.

The goal is to:

  • Detect when a user watches >50% of a video (single-shot)

  • Send analytics event from frontend to backend

  • Queue event in Redis

  • Process asynchronously via worker

  • Persist raw events in DB

  • Maintain aggregated metrics for admin analytics page

This should follow an event-driven architecture to ensure scalability and minimal API latency impact.


🏗 High-Level Architecture

Frontend
   ↓
POST /analytics (Fastify)
   ↓
Redis queue (queue:analytics)
   ↓
analytics-worker (background consumer)
   ↓
Persist to DB (video_events)
   ↓
Update aggregate table (video_metrics)

✅ Scope of Work

🔹 Frontend

1. video-player.tsx

  • Add required videoId prop.

  • Implement single-shot detection when playback crosses >50%.

  • Send POST request to analytics endpoint.

Payload:

{
  "videoId": "string",
  "event": "watched_50_percent",
  "ts": 1234567890,
  "userId": "string"
}
  • Ensure event fires only once per playback session.

2. page.tsx

  • Pass page-level videoId into VideoPlayer.

3. video-feed-card.tsx

  • Pass video.videoId into VideoPlayer for inline previews.

4. Auth / Session Helper

  • Ensure stable clientId or userId exists:

    • Logged-in users → use userId

    • Anonymous → generate UUID and persist in localStorage


🔹 Backend (PulseVault - Fastify)

1. routes/analytics.js

Add:

POST /analytics

Responsibilities:

  • Validate payload fields:

    • videoId

    • event

    • ts

    • userId

  • Accept only supported event types (watched_50_percent)

  • Push event into Redis queue:

    • queue:analytics
  • Implement deduplication key in Redis:

    • dedupe:video:{videoId}:user:{userId}:watched50

    • Use SET NX EX pattern


🔹 Worker

workers/analytics-worker.js (NEW)

Responsibilities:

  • Consume from queue:analytics (BLPOP or Redis Streams).

  • Persist raw event into video_events table.

  • Increment aggregate counter in video_metrics.

Should run independently (Docker service can be added later if needed).


🔹 Database (Prisma / Migrations)

Add table: video_events

Column | Type -- | -- id | UUID video_id | string event | string user_id | string ts | timestamp created_at | timestamp


📊 Admin Analytics

Future endpoint:

GET /admin/analytics/top

Should return videos sorted by highest watched_50_count.


🔐 Deduplication Strategy

To prevent double-counting:

Redis key format:

dedupe:video:{videoId}:user:{userId}:watched50

Use:

SET key 1 EX 86400 NX

If key already exists → ignore event.


📚 Documentation

Update README.md with:

  • Analytics endpoint description

  • Redis key structure

  • Worker behavior

  • Event schema


🧪 Tests (Optional but Recommended)

  • POST /analytics → assert Redis queue entry.

  • Assert dedupe behavior.

  • Worker test → ensure DB insert and aggregate increment.


🎯 Acceptance Criteria

  • 50% watch event fires only once per session.

  • Backend validates and queues analytics event.

  • Worker persists raw event.

  • Aggregate count increments correctly.

  • No noticeable latency added to video playback.

  • Deduplication prevents duplicate counting.


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions