Imoutotv Hot < Proven - 2027 >
| Week | Deliverable | Owner(s) |
|------|-------------|----------|
| 1 | • Define event schema (likes, watch, comments).
• Set up Kafka topics & test producers. | Data Engineering |
| 2 | • Build Spark/F
Same as above, but type=personal. The server will compute similarity on‑the‑fly using pre‑computed embeddings stored in a vector DB (e.g., Milvus, Pinecone). imoutotv hot
| Goal | Success Metric | |------|----------------| | Surface the most engaging content to keep users on‑site longer. | ↑ Average session length (≥ +10 % in the first 4 weeks). | | Drive discoverability of new creators and fresh videos. | ↑ Number of unique videos viewed from the Hot feed (≥ +15 %). | | Encourage community interaction (likes, comments, shares). | ↑ Engagement rate on Hot items (likes + comments + shares) vs baseline (≥ +12 %). | | Provide a real‑time sense of what’s “hot”. | ≤ 5 min latency between a video’s activity spike and its appearance in Hot. | | Goal | Success Metric | |------|----------------| |
| Category | Requirement |
|----------|-------------|
| Performance | End‑to‑end latency (API → UI) < 200 ms for cached responses. |
| Scalability | Able to compute hot scores for ≥ 10 M videos within a 5‑minute window. Use distributed Spark/Flink job or serverless map‑reduce. |
| Reliability | Cache fallback to DB if Redis unavailable (graceful degradation). |
| Observability | Metrics: hot_score_job.duration, hot_api.latency, hot_api.error_rate, hot_score.spike.alerts. |
| Security | Only expose public video metadata; never leak private user data via the Hot endpoint. |
| Compliance | Respect GDPR/CCPA: if a user exercises “right to be forgotten”, purge their videos from Hot lists instantly. |
| Internationalization | Hot badge text (“Hot”, “Trending”) should be i18n‑ready. | "items": [
"rank": 1
| ID | Requirement | Details |
|----|-------------|---------|
| FR‑1 | Hot Feed API | GET /api/v1/hot?type=global|personal&limit=20&offset=0 Returns an ordered list of video IDs with meta (title, thumbnail, creator, hotScore, rank). |
| FR‑2 | Hot Score Calculation | Run a batch job every 5 min (or stream via Kafka) that computes a hotScore per video: hotScore = Σ (w_i * signal_i) * decay(age)
Signals:
- likes (w=1)
- comments (w=1.2)
- watchTimeSec (w=0.8)
- shares (w=1.5)
Decay: exp(-ageHours / τ) (τ ≈ 24 h). |
| FR‑3 | Creator Caps | No more than 3 videos from the same creator in the top‑20 global Hot list. |
| FR‑4 | Safety Filter | Only videos with moderationStatus = approved are eligible. If a video’s hotScore > threshold and moderationStatus = pending, auto‑escalate to moderation queue. |
| FR‑5 | Cache Layer | Store the latest Hot list in a Redis Sorted Set (ZADD hot:global score videoId). TTL = 5 min. API reads from cache for sub‑second latency. |
| FR‑6 | Personalization Slice | Compute a “personal” hot list by intersecting global Hot with a similarity filter: similarity(user, video) = cosine( userEmbedding, videoEmbedding ). Return top‑N after similarity ranking. |
| FR‑7 | Analytics & Auditing | Log every Hot list generation event (timestamp, algorithm version, top‑10 IDs) to a Kafka topic for downstream BI. |
| FR‑8 | Front‑end UI | • Horizontal carousel (mobile) and grid (desktop).
• Each tile shows thumbnail, hotScore badge (e.g., 🔥 1.2k), creator avatar.
• “Refresh” button to reload the list. |
| FR‑9 | A/B Testing Hook | Enable toggling of the Hot feature per‑user via feature flag (hot_enabled). Allows rollout experiments. |
| FR‑10 | Rate‑limit | API limited to 30 req/min per user/IP to protect the cache. |
GET /api/v1/hot?type=global&limit=20&offset=0
Headers:
Authorization: Bearer <jwt>
X-Feature-Flag: hot_enabled=1
Response (200):
"type": "global",
"generatedAt": "2026-04-12T08:45:00Z",
"items": [
"rank": 1,
"videoId": "v_7a9f2c",
"title": "Epic Sword Battle",
"thumbnailUrl": "https://cdn.imoutotv.com/thumbs/v_7a9f2c.jpg",
"creator":
"id": "c_1234",
"name": "NekoBlade",
"avatarUrl": "https://cdn.imoutotv.com/avatars/c_1234.png"
,
"hotScore": 1284.3,
"stats":
"likes": 540,
"comments": 87,
"watchTimeSec": 25400,
"shares": 30
,
…
],
"paging":
"limit": 20,
"offset": 0,
"total": 1234