fix(dashboard): augment Silently-costing card with transcode breakdowns#142
Merged
Conversation
| from __future__ import annotations | ||
|
|
||
| import datetime as _dt | ||
| from collections.abc import Iterable |
4 tasks
Replaces the single "top transcoded files" list with a richer
four-axis breakdown of WHAT is costing the operator:
* Top video + audio codecs forcing transcodes (video from
PlaybackEvent.source_codec; audio from MediaFile.audio_codec
via a join, since the event row doesn't carry it).
* Top devices triggering transcodes + each device's top
transcode reasons ("what this device doesn't like").
* Top transcode reasons overall.
* Average source bitrate split direct-play vs transcoded
(operators want the per-stream weight, not aggregate
traffic — transcoded streams that re-encode to a lower
bitrate dominate when the source is a fat remux).
Backend:
* New ``app/services/dashboard/transcode_insights.py`` service.
All four breakdowns + the totals + the bitrate split are
computed in a single service call so the card renders without
N round-trips. Bounded by ``?days=`` (1..365).
* New ``GET /api/v1/dashboard/transcode-insights`` endpoint.
* New ``TranscodeInsightsRead`` schema (plus the four nested
Read models).
Frontend:
* New ``useDashboardTranscodeInsights`` hook keyed off the
dashboard's existing range. ``All time`` is treated as 365
days so the backend COUNT(*) stays bounded.
* New ``TranscodeInsightsBlock`` sub-component rendered inside
the existing "Silently costing you" card, between the hero
copy + the trend chart. Hidden when the window has no
transcodes — the hero copy already explains a quiet library.
Tests:
* ``tests/integration/test_dashboard_transcode_insights_v111.py``
— 6 tests pin the contract (empty-window zero, codec
counting filters to transcodes only, audio codec joins
MediaFile, device top-reasons surface per-device failure
modes, bitrate split, ``?days=`` window bound).
* Frontend: ``tsc --noEmit`` clean; ``vitest run
src/features/dashboard`` — 40/40 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4357fe3 to
ccc18af
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Second of three planned PRs for the Dashboard overhaul. This one replaces the single "top transcoded files" list inside the Silently costing you card with a four-axis breakdown that tells the operator what is actually costing them:
PlaybackEvent.source_codec; audio joined fromMediaFile.audio_codec(the event row doesn't carry an audio codec column).Backend
app/services/dashboard/transcode_insights.pycomputes all four breakdowns + totals + bitrate split in a single service call.GET /api/v1/dashboard/transcode-insights?days=30endpoint (1..365 day window).TranscodeInsightsReadschema with four nested Read models.Frontend
useDashboardTranscodeInsightshook keyed off the dashboard's existing range; "All time" maps to 365 to keep the COUNT(*) bounded.TranscodeInsightsBlocksub-component inside the existing "Silently costing you" card, between the hero copy and the trend chart. Hidden when the window has no transcodes (the hero copy already explains a quiet library).Test plan
pytest backend/tests/integration/test_dashboard_transcode_insights_v111.py— 6 tests pass (empty window, codec counting filters to transcodes only, audio codec joins MediaFile, per-device top reasons, bitrate split,?days=window bound).npx tsc --noEmitclean.vitest run src/features/dashboard— 40/40 pass.7d/30d/90dselector at the top of the dashboard drives the same window.Next up
🤖 Generated with Claude Code