feat(web): real channel filter — multi-select of the user's channels
The free-text 'channel' filter was dead: it exact-matched SummaryRow.Channel,
which is just the provider ('youtube'), because videos never stored their source
channel. Now they do.
- migration 014: videos.channel_title (nullable; existing rows backfill on the
next discovery pass, pasted videos immediately).
- discovery (NewVideos) + paste (VideoByID) populate channel_title; UpsertVideo
persists it, preserving an existing title when an update arrives empty.
- store.DistinctChannels lists a user's channels (RLS-scoped); SummaryRow carries
ChannelTitle via the shared projection.
- Filter: single Channel -> Channels []string, matching on ChannelTitle; the feed
renders a multi-select of DistinctChannels (hidden until channels exist).
- migrate tests: 014 reversibility + fixed the relative-step counts in the 010/011
up/down tests (014 shifted the topology).
TDD throughout: channel persist + distinct, adapter channel wiring, multi-channel
filter match, handler channel filter, migration up/down.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,7 @@ func TestVideoByID(t *testing.T) {
|
||||
if got := r.URL.Query().Get("part"); got != "snippet" {
|
||||
t.Errorf("expected part=snippet, got %q", got)
|
||||
}
|
||||
_, _ = w.Write([]byte(`{"items":[{"snippet":{"title":"Never Gonna Give You Up","publishedAt":"2026-05-20T09:00:00Z"}}]}`))
|
||||
_, _ = w.Write([]byte(`{"items":[{"snippet":{"title":"Never Gonna Give You Up","channelTitle":"Rick Astley","publishedAt":"2026-05-20T09:00:00Z"}}]}`))
|
||||
})
|
||||
|
||||
v, err := a.VideoByID(context.Background(), "u1", id)
|
||||
@@ -34,6 +34,9 @@ func TestVideoByID(t *testing.T) {
|
||||
if v.ProviderVideoID != id || v.Title != "Never Gonna Give You Up" {
|
||||
t.Errorf("unexpected video: %+v", v)
|
||||
}
|
||||
if v.ChannelTitle != "Rick Astley" {
|
||||
t.Errorf("ChannelTitle = %q, want Rick Astley", v.ChannelTitle)
|
||||
}
|
||||
if v.Provider != domain.ProviderYouTube || v.URL != "https://www.youtube.com/watch?v="+id {
|
||||
t.Errorf("video not wired correctly: %+v", v)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user