Plan: VID-2 — DB Migration: add hot_score, is_hot, hot_rank to video_sources¶
Jira: VID-2 Epic: VID-34 Trending Videos Size: Small (< 1 day) Decision type: Two-Way Door (columns with defaults, reversible via DROP COLUMN) Depends on: nothing Blocks: VID-4 (HotVideoService), VID-1 (recordAccess)
Exploration Findings¶
| Finding | Detail |
|---|---|
| Active video table | video_sources (not youtube_video) |
| Current entity fields | id, videoId, sourceType, sourceId, sourceUrl, credentialsRef, title, desc, isHide, thumbnailPath, status |
| Mapper: VideoSource → VideoDto | StreamVideoServiceImpl.toDto() line 108 |
| Mapper: VideoSource → AdminVideoDto | AdminVideoServiceImpl.toDto() line 68 — NOT in scope |
| Migration style | Pure SQL, alphabetical ordering, naming: YYYYMMDDNNNN-description.sql |
| BigDecimal usage | None yet in codebase — new import needed |
video_access_stats.video_id index |
Does not yet exist — add it here |
Implementation Steps¶
Step 1 — Liquibase migration¶
File: api/src/main/resources/db/changelog/sql/202605160001-add-hot-score-to-video-sources.sql
ALTER TABLE video_sources
ADD COLUMN IF NOT EXISTS hot_score DECIMAL(5,4) DEFAULT 0,
ADD COLUMN IF NOT EXISTS is_hot BOOLEAN DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS hot_rank INT DEFAULT NULL;
CREATE INDEX IF NOT EXISTS idx_video_sources_hot_score
ON video_sources(hot_score DESC) WHERE is_hot = TRUE;
CREATE INDEX IF NOT EXISTS idx_video_access_stats_video_id
ON video_access_stats(video_id);
Step 2 — Update VideoSource.java entity¶
File: api/src/main/java/com/canhlabs/funnyapp/entity/VideoSource.java
Add after thumbnailPath field:
@Column(name = "hot_score", precision = 5, scale = 4)
private BigDecimal hotScore = BigDecimal.ZERO;
@Column(name = "is_hot", nullable = false)
private boolean isHot = false;
@Column(name = "hot_rank")
private Integer hotRank;
Add import: java.math.BigDecimal
Step 3 — Update VideoDto.java¶
File: api/src/main/java/com/canhlabs/funnyapp/dto/VideoDto.java
Add fields:
Add import: java.math.BigDecimal
Step 4 — Update StreamVideoServiceImpl.toDto() mapper¶
File: api/src/main/java/com/canhlabs/funnyapp/service/impl/StreamVideoServiceImpl.java line 108
Map the new fields so VideoDto is populated correctly:
dto.setHotScore(source.getHotScore());
dto.setIsHot(source.isHot());
dto.setRank(source.getHotRank());
AdminVideoServiceImpl.toDto()maps toAdminVideoDto(notVideoDto) — out of scope.
Acceptance Criteria¶
- [ ] Migration file
202605160001-add-hot-score-to-video-sources.sqlexists and runs cleanly - [ ] Migration is idempotent (
IF NOT EXISTSguards on columns and indexes) - [ ]
VideoSource.javacompiles withhotScore,isHot,hotRank - [ ]
VideoDto.javacompiles withhotScore,isHot,rank - [ ]
StreamVideoServiceImpl.toDto()maps new fields - [ ]
./unittest.shpasses — no regressions - [ ] Existing queries on
video_sourcesunaffected (new columns are nullable/defaulted)
Out of Scope¶
- Hot score computation logic (VID-4)
- Trending API endpoints (VID-5, VID-6)
- Scheduler for recomputing scores (VID-7)
- Frontend changes (VID-8, VID-9)
AdminVideoDto/AdminVideoServiceImpl— uses separate DTO
Handoff¶
Ready for /swarm-execute or direct implementation. All 4 files are known:
| # | File | Action |
|---|---|---|
| 1 | db/changelog/sql/202605160001-add-hot-score-to-video-sources.sql |
Create |
| 2 | entity/VideoSource.java |
Edit — add 3 fields |
| 3 | dto/VideoDto.java |
Edit — add 3 fields |
| 4 | service/impl/StreamVideoServiceImpl.java |
Edit — update toDto() |