refactor(db): GetCollectionItemsForDashboard embeds the media row; excluded filter moves into SQL; third converter dies

SELECT mi.*, ci.excluded forced every caller to filter tombstone
exclusions in Go over a 69-field row, then a 45-field hand converter
(getCollectionItemsRowToMediaItems) copied it field-by-field into
MediaItems for BuildSections. The query now filters
(ci.excluded IS NOT TRUE) itself and returns sqlc.embed(mi) — callers
consume .MediaItems directly, the Go filter loops die in both
collection-detail ladders (JSON + SSR), and the converter is deleted.

Pins, H1/H3 tests, unit suites green.
This commit is contained in:
John O'Keefe committed 2026-10-17 16:51:30 -04:00
1 parent 18727fef93
commit 77cf0b827b
7 files changed
+102 -218

No files matched your search

+5 -1
View File
@@ -2791,12 +2791,16 @@ ORDER BY mi.created_at DESC
LIMIT sqlc.narg('limit');
-- name: GetCollectionItemsForDashboard :many
SELECT mi.*, ci.excluded FROM media_items mi
-- The excluded filter lives here (was: callers filtered ci.excluded in
-- Go over a 69-field row + a 45-field converter to MediaItems; embed
-- returns the real row so neither exists).
SELECT sqlc.embed(mi) FROM media_items mi
INNER JOIN collection_items ci ON ci.media_item_id = mi.id
WHERE ci.collection_id = sqlc.narg('collection_id')
AND (sqlc.narg('library_id')::uuid IS NULL OR mi.library_id = sqlc.narg('library_id')::uuid)
AND mi.archived_at IS NULL
AND mi.missing_scan_count = 0
AND (ci.excluded IS NOT TRUE)
ORDER BY ci.added_at DESC
LIMIT sqlc.narg('limit');