feat(platform_playlist): CV-017 -- persistent canonical channel identity (Drift/SQLite)#921
Merged
Conversation
…ity (Drift/SQLite) Adds the last remaining piece of #821's framework scope: real, queryable persistence for canonical channel identities and provider aliases, backed by Drift/SQLite instead of the SharedPreferences-JSON pattern every other store in this repo uses. Schema (matches the issue's suggested data contract): - CanonicalChannels: canonicalChannelId, displayName, normalizedName, language, country, category, logoFingerprint, createdAt, updatedAt. - ProviderChannelAliases: sourceId + providerChannelId (composite PK), canonicalChannelId (nullable FK), providerName, normalizedProviderName, tvgId, groupTitle, streamUrlFingerprint, resolution, isVod/isRadio/isAdult, matchConfidence. CanonicalChannelRepository wraps the generated Drift database: upsert/get/list for canonical channels, upsert/lookup for aliases (by composite key, by canonical id, by tvg-id -- the last one mirrors CanonicalChannelMatcher's own high-confidence signal). ## Why Drift/SQLite over the existing SharedPreferences pattern Flat JSON-in-a-single-preference-key doesn't hold up at the scale this issue describes ("tens of thousands of channels") -- no indexing, no querying, and SharedPreferences has a hard per-value size ceiling this codebase has already hit in other stores' tests. A real SQL engine with indexes on canonical_channel_id and tvg_id is the right tool once alias counts get large. ## First-of-its-kind dependency -- flags for review This is the first Drift/SQLite usage anywhere in packages/. Two things a reviewer should weigh in on: 1. New dependency footprint: drift, drift_dev, build_runner, sqlite3, sqlite3_flutter_libs, path, path_provider -- binary size and build time impact on TV specifically should get a look (chief-performance- officer) alongside the usual license/maintenance checks (chief-open- source-officer). 2. Generated code (*.g.dart) is committed despite the repo-wide .gitignore rule (force-added) because no CI workflow currently runs `dart run build_runner build` for any package under packages/ -- only app/ has that step. Without checking in the generated file, this package would fail to compile anywhere that doesn't run codegen first. The real fix is wiring a per-package (or matrix) codegen step into CI; committing the artifact is a stopgap, not a long-term policy for future Drift schema changes in this package. ## Not in this slice - Wiring FavoriteChannelRemapper/CanonicalChannelMatcher to actually populate this database during a real playlist import -- this PR only adds the storage layer. - Migration strategy beyond schemaVersion 1 (no prior schema to migrate from yet).
Contributor
Plugin Module Size GatePolicy: modules over 3 MB must be delivered as plugins; plugin modules over 5 MB must document cache management.
|
Contributor
🚀 PR Quick Check Summary
|
|
Contributor
🚀 PR Quick Check Summary
|
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.



This is the first Drift/SQLite usage anywhere in
packages/. Twothings worth a second set of eyes:
drift,drift_dev,build_runner,sqlite3,sqlite3_flutter_libs,path,path_provider-- binarysize and build time impact on TV specifically should get a look
(chief-performance-officer) alongside the usual license/maintenance
checks (chief-open-source-officer).
*.g.dartisforce-added despite the repo-wide
.gitignorerule, because no CIworkflow currently runs
dart run build_runner buildfor anypackage under
packages/-- onlyapp/has that step. Withoutchecking in the generated file, this package fails to compile
anywhere that doesn't run codegen first. The real fix is wiring a
per-package (or matrix) codegen step into CI; committing the
artifact is a stopgap, not a long-term policy for future schema
changes here.
Summary
Part of #821 (CV-017, P0). Adds the last piece of the issue's
framework-owned scope: real, queryable persistence for canonical
channel identities and provider aliases.
Why Drift/SQLite over the existing SharedPreferences pattern
Every other store in this repo (
HiddenGroupsStorage,FavoriteChannelsStorage, etc.) uses flat JSON in a singleSharedPreferences key. That doesn't hold up at the scale this issue
describes ("tens of thousands of channels") -- no indexing, no
querying, and this codebase has already hit SharedPreferences' per-
value size ceiling in other stores' tests. A real SQL engine with
indexes on
canonical_channel_idandtvg_idis the right tool oncealias counts get large.
Schema (matches the issue's suggested data contract)
CanonicalChannels:canonicalChannelId,displayName,normalizedName,language,country,category,logoFingerprint,createdAt,updatedAt.ProviderChannelAliases:sourceId+providerChannelId(compositePK),
canonicalChannelId(nullable FK),providerName,normalizedProviderName,tvgId,groupTitle,streamUrlFingerprint,resolution,isVod/isRadio/isAdult,matchConfidence.CanonicalChannelRepositorywraps the generated Drift database:upsert/get/list for canonical channels, upsert/lookup for aliases (by
composite key, by canonical id, by tvg-id -- the last mirrors
CanonicalChannelMatcher's own high-confidence signal).Not in this slice
FavoriteChannelRemapper/CanonicalChannelMatchertoactually populate this database during a real playlist import --
this PR only adds the storage layer.
schemaVersion 1(no prior schema existsyet to migrate from).
Test plan
conflict, alias upsert/lookup by composite key, aliases-by-
canonical-id, aliases-by-tvg-id across providers, not-found cases
for both.
platform_playlistsuite green (111 tests), using anin-memory Drift database (
NativeDatabase.memory()) -- no diskI/O in tests.
flutter analyzeclean on changed files (one pre-existing,unrelated lint on the barrel file).
dart format --set-exit-if-changedclean on hand-written files(generated
.g.dartleft as the generator produced it).