fix(music-lab): revenue avg_rpm 공식 수정 + UNIQUE 제약 + 테스트 보강
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -131,7 +131,8 @@ def init_db() -> None:
|
|||||||
rpm_usd REAL NOT NULL DEFAULT 0.0,
|
rpm_usd REAL NOT NULL DEFAULT 0.0,
|
||||||
country TEXT NOT NULL DEFAULT '',
|
country TEXT NOT NULL DEFAULT '',
|
||||||
source TEXT NOT NULL DEFAULT 'manual',
|
source TEXT NOT NULL DEFAULT 'manual',
|
||||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
||||||
|
UNIQUE(yt_video_id, record_month, country)
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
conn.execute("CREATE INDEX IF NOT EXISTS idx_rr_month ON revenue_records(record_month DESC)")
|
conn.execute("CREATE INDEX IF NOT EXISTS idx_rr_month ON revenue_records(record_month DESC)")
|
||||||
@@ -567,7 +568,7 @@ def get_revenue_dashboard() -> dict:
|
|||||||
).fetchone()
|
).fetchone()
|
||||||
by_month = conn.execute(
|
by_month = conn.execute(
|
||||||
"""SELECT record_month, SUM(revenue_usd) as revenue, SUM(views) as views,
|
"""SELECT record_month, SUM(revenue_usd) as revenue, SUM(views) as views,
|
||||||
AVG(rpm_usd) as avg_rpm FROM revenue_records
|
CASE WHEN SUM(views) > 0 THEN ROUND(SUM(revenue_usd) / SUM(views) * 1000, 4) ELSE 0.0 END as avg_rpm FROM revenue_records
|
||||||
GROUP BY record_month ORDER BY record_month DESC LIMIT 12"""
|
GROUP BY record_month ORDER BY record_month DESC LIMIT 12"""
|
||||||
).fetchall()
|
).fetchall()
|
||||||
by_country = conn.execute(
|
by_country = conn.execute(
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
def test_create_and_get_video_project(tmp_db):
|
def test_create_and_get_video_project(tmp_db):
|
||||||
from app.db import init_db, create_video_project, get_video_project
|
from app.db import init_db, create_video_project, get_video_project
|
||||||
init_db()
|
init_db()
|
||||||
@@ -62,7 +65,6 @@ def test_create_revenue_record(tmp_db):
|
|||||||
|
|
||||||
def test_revenue_dashboard(tmp_db):
|
def test_revenue_dashboard(tmp_db):
|
||||||
from app.db import init_db, create_revenue_record, get_revenue_dashboard
|
from app.db import init_db, create_revenue_record, get_revenue_dashboard
|
||||||
import pytest
|
|
||||||
init_db()
|
init_db()
|
||||||
create_revenue_record({"yt_video_id": "v1", "record_month": "2026-04", "views": 5000, "revenue_usd": 10.0})
|
create_revenue_record({"yt_video_id": "v1", "record_month": "2026-04", "views": 5000, "revenue_usd": 10.0})
|
||||||
create_revenue_record({"yt_video_id": "v2", "record_month": "2026-04", "views": 5000, "revenue_usd": 15.0})
|
create_revenue_record({"yt_video_id": "v2", "record_month": "2026-04", "views": 5000, "revenue_usd": 15.0})
|
||||||
@@ -70,3 +72,54 @@ def test_revenue_dashboard(tmp_db):
|
|||||||
assert dash["total_revenue_usd"] == pytest.approx(25.0)
|
assert dash["total_revenue_usd"] == pytest.approx(25.0)
|
||||||
assert dash["total_views"] == 10000
|
assert dash["total_views"] == 10000
|
||||||
assert len(dash["by_month"]) == 1
|
assert len(dash["by_month"]) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_revenue_record_zero_views(tmp_db):
|
||||||
|
from app.db import init_db, create_revenue_record
|
||||||
|
init_db()
|
||||||
|
rec = create_revenue_record({
|
||||||
|
"yt_video_id": "zero",
|
||||||
|
"record_month": "2026-04",
|
||||||
|
"views": 0,
|
||||||
|
"revenue_usd": 0.0,
|
||||||
|
})
|
||||||
|
assert rec["rpm_usd"] == 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_revenue_record(tmp_db):
|
||||||
|
from app.db import init_db, create_revenue_record, update_revenue_record
|
||||||
|
init_db()
|
||||||
|
create_revenue_record({"yt_video_id": "x", "record_month": "2026-04", "views": 1000, "revenue_usd": 5.0})
|
||||||
|
updated = update_revenue_record(1, {"views": 2000, "revenue_usd": 8.0})
|
||||||
|
assert updated["rpm_usd"] == pytest.approx(4.0)
|
||||||
|
assert update_revenue_record(999, {}) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_delete_revenue_record(tmp_db):
|
||||||
|
from app.db import init_db, create_revenue_record, delete_revenue_record, get_all_revenue_records
|
||||||
|
init_db()
|
||||||
|
create_revenue_record({"yt_video_id": "del", "record_month": "2026-04", "views": 100, "revenue_usd": 1.0})
|
||||||
|
assert delete_revenue_record(1) is True
|
||||||
|
assert delete_revenue_record(99) is False
|
||||||
|
assert get_all_revenue_records(yt_video_id="del") == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_video_project_status_failed(tmp_db):
|
||||||
|
from app.db import init_db, create_video_project, update_video_project_status, get_video_project
|
||||||
|
init_db()
|
||||||
|
create_video_project({"track_id": 1, "format": "visualizer"})
|
||||||
|
update_video_project_status(1, "failed", error="FFmpeg error")
|
||||||
|
proj = get_video_project(1)
|
||||||
|
assert proj["status"] == "failed"
|
||||||
|
assert proj["completed_at"] is not None
|
||||||
|
assert proj["error"] == "FFmpeg error"
|
||||||
|
|
||||||
|
|
||||||
|
def test_video_project_status_rendering_no_completed_at(tmp_db):
|
||||||
|
from app.db import init_db, create_video_project, update_video_project_status, get_video_project
|
||||||
|
init_db()
|
||||||
|
create_video_project({"track_id": 1, "format": "visualizer"})
|
||||||
|
update_video_project_status(1, "rendering")
|
||||||
|
proj = get_video_project(1)
|
||||||
|
assert proj["status"] == "rendering"
|
||||||
|
assert proj["completed_at"] is None
|
||||||
|
|||||||
Reference in New Issue
Block a user