feat(podcasts): smart collections ride the unified filter engine — filter_tree column (item 3.2)
collections gains filter_tree JSONB (idempotent in-place; same qf DSL as saved filters — the scope key included). IsCollectionSmart is the ONE detection (tree OR legacy rules), and EvaluateSmartMembership is the ONE evaluator: tree-bearing collections run the composed engine via ComposedLiveMedia (full media rows, so the collection surfaces keep their episode-card stamping, feed positions for the replay chain, and the family lens rides the mandatory head), while legacy rule arrays keep per-item FieldMatches until rewritten — one call surface, two storage epochs. All smart surfaces (detail JSON, counts, detail page, reader chain) dispatch through it; the search service is injected into the collection subsystem (variadic — main.go builds one shared instance; the test harness mirrors it). Write path: CreateCollection/UpdateCollection accept the tree, validated against the engine grammar at the HANDLER (an invalid tree is a 400, never a stored render-time 500) and exposed in the envelope (pin widened in TestContractPin_CollectionsJSON + changelog). Update semantics: an edit form that doesn't send a tree keeps the stored one. RulesToFilterTree converts legacy rules + match mode at upgrade time: episode rules map mechanically (feed→in-list, played/downloaded→ booleans, published_within→published_date+within_days), tree root mode absorbs rule_match_mode, episode rules force the episodes scope, and legacy starts_with/ends_with fall back to contains (documented). Read-compat by design: nothing is migrated at boot — legacy arrays evaluate exactly as before until the collection is rewritten. Pinned by TestRulesToFilterTree (unit conversion) + TestEpisodeCollectionsFilterTree (a tree collection evaluates through the engine, the chain follows the tree's live membership, invalid trees 400 at write, the tree wins when legacy rules coexist, and an edit without a tree keeps it).
This commit is contained in:
1 parent
56871b65ed
commit
6b2125a45a
17 files changed
+524
-55
No files matched your search
@@ -596,9 +596,12 @@ func setupTestServer(t *testing.T) *TestServerSetup {
|
||||
worker := services.NewWorker(3, connManager)
|
||||
services.WorkerInstance = worker
|
||||
jobsHandler := handlers.NewJobsHandler(queries, worker)
|
||||
collectionHandler := handlers.NewCollectionHandler(queries, libraryService, connManager)
|
||||
// One composed-engine service for search AND the collection
|
||||
// subsystem (item 3.2 — mirrors main.go).
|
||||
collectionSearchService := services.NewSearchService(queries, scopedDB)
|
||||
collectionHandler := handlers.NewCollectionHandler(queries, libraryService, connManager, collectionSearchService)
|
||||
filtersHandler := handlers.NewFiltersHandler(queries)
|
||||
dashboardService := services.NewDashboardService(queries)
|
||||
dashboardService := services.NewDashboardService(queries, collectionSearchService)
|
||||
dashboardHandler := handlers.NewDashboardHandler(queries)
|
||||
statisticsService := services.NewStatisticsService(queries)
|
||||
statsHandler := handlers.NewStatsHandler(statisticsService)
|
||||
|
||||
Reference in new issue
Block a user