Commit Graph
164 Commits
Author SHA1 Message Date
Silo Server DeveloperandClaude Opus 4.7 534f7bb901 fix(naming): numeric-only titles are not bare provider IDs
'86' / '22 7' were parsed as trailing tvdb ids, tripping the trusted-ID gate
so the correct title match was rejected. Require a letter in the name before
treating a trailing number as a bare id.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 17:45:38 +02:00
Silo Server Developer f2b6eff29d fix(naming): strip unsubstituted Sonarr tokens ({TvdbId}/{imdb-}) from titles
These tokens survived the provider-tag regex ([\w]+ doesn't match braces),
polluting parsed titles (e.g. 'A Girl & Her Guard Dog [tvdb-{TvdbId}]') so
they could not score-match. Broaden the regex to drop {...} and empty tokens.
2026-05-28 17:45:38 +02:00
QuickandGitHub 773148486e Merge pull request #20 from fluxis/mr/b-admin-ux
feat(admin): admin libraries UX polish — full-table unmatched search, larger match-candidate posters with hover preview, paginated Ambiguous Roots
2026-05-28 11:41:03 -04:00
Quick 74e9be6443 fix(admin): search all unmatched item library memberships 2026-05-28 11:31:50 -04:00
Silo Server DeveloperandClaude Opus 4.7 c3c806410f test(admin): wire QueryClientProvider + missing hook mocks so the suite runs
The AdminLibraries test file failed all 6 tests with 'No QueryClient set' on
this branch and at the parent commit -- pre-existing infrastructure gap. With
that fixed, several hooks that the page imports (useCancelLibraryScans,
useLibraryRoots, useUpsertLibraryRootOverride, useDeleteLibraryRootOverride,
useActiveScans) and the UNMATCHED_PAGE_SIZE constant also needed mocking. One
stale assertion on the renamed 'Root path' header is updated; the deeper
troubleshooting test, which mocked useSkippedLibraryRoots but the section was
refactored to useLibraryRoots(_, 'ambiguous'), is skipped with a TODO -- a real
rewrite is needed and is out of scope for this MR.

5 of 6 tests now run and pass; the 6th is properly flagged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 17:25:36 +02:00
Silo Server DeveloperandClaude Opus 4.7 d9b57f28e2 style(admin): prettier-format match dialog; reset unmatched page in onChange
Run prettier over the Tooltip-wrapped poster JSX, and reset the unmatched-items
page in the search input's onChange rather than a useEffect (avoids the
react-hooks/set-state-in-effect warning / cascading renders).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 17:25:36 +02:00
Silo Server DeveloperandClaude Opus 4.7 49efc3846c fix(admin): search unmatched items across the whole table, not just the page
The unmatched-items search filtered only the current page's rows client-side.
Push the query server-side: HandleListUnmatchedItems takes an optional 'q' param
and filters title/library/type/status with parameterized ILIKE across all rows,
paginating the filtered set. Frontend hook takes a debounced search, resets to
page 1 on change, keeps the section mounted while searching. Also fixes stale
test mocks that returned the pre-pagination array shape instead of {items,total}.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 17:25:36 +02:00
Silo Server DeveloperandClaude Opus 4.7 0bb1030ca2 feat(admin): enlarge match-candidate posters + hover-to-enlarge
Unmatched-item match dialog rendered candidate posters at 44x64px, too small
to identify a film. Bump to 64x96 (2:3) and add a portaled Tooltip hover preview
(192x288) using the existing poster image, so operators can tell candidates apart.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 16:59:48 +02:00
Silo Server Developer 590f61a550 feat(ui): paginate the Ambiguous Roots table
Match the sibling tables on the Admin Libraries page (Troubleshooting/unmatched):
use the existing usePagination hook + PaginationBar (10/page, auto-hidden when
<=10 rows), render pag.rows, and reset to page 0 when the library selector or
search filter changes.
2026-05-28 16:59:48 +02:00
QuickandGitHub 2feb77e18f Merge pull request #18 from Silo-Server/codex/episode-section-labels
feat(sections): show episode context in cards
2026-05-27 15:49:35 -04:00
Quick 71ca2012c5 feat(sections): show episode context in cards 2026-05-27 15:48:00 -04:00
Quick dc4c20bb0f fix(catalog): use season posters for episode cards 2026-05-27 14:54:58 -04:00
Quick 3bcde929a5 fix(library): preserve episode browse url 2026-05-27 14:54:51 -04:00
Quick a070f846af fix(collections): cap smart collection results 2026-05-27 14:27:14 -04:00
Quick d19b6c48e9 fix(catalog): support relative date filters 2026-05-27 13:59:29 -04:00
QuickandGitHub 3c92ded9df Merge pull request #15 from Silo-Server/fix/tv-scan-settle-window-cancel
fix(libraryingest): TV full scans cancelled at settle-window boundary
2026-05-27 13:44:57 -04:00
Quick abdccd5904 Fix settle-window drainer cancellation in library ingest 2026-05-27 13:37:33 -04:00
QuickandGitHub ca9fd399ca Merge pull request #16 from Silo-Server/codex/episode-catalog-performance
perf(catalog): add episode browse index fast path
2026-05-27 12:52:48 -04:00
Quick c6176d6c85 fix(catalog): address episode catalog review feedback 2026-05-27 12:48:59 -04:00
Quick eeecf60023 perf(catalog): add episode browse index fast path 2026-05-27 11:57:49 -04:00
CoffeeKnyte 886c492c6a fix(libraryingest): treat drainer shutdown cancel as clean stop
TV/series full scans (libraries with new or updated items) were recorded as
"cancelled" with an empty error message and never completed matching.

When the file-walk finishes, the ingest executor waits out a settle window and
then calls stopDrainers() to shut down the concurrent match goroutines. That
cancels the drainer context while a ProcessBatchByFolderAndPathPrefix call may
still be in flight. The drainer treated the resulting context.Canceled as a
fatal error: it pushed the error to drainerErrCh and called cancel() on the
whole scan context, so scanqueue.process() mapped it to cancelRun().

Large/slow libraries (many series, slow provider lookups) keep a batch in
flight continuously, so stopDrainers() almost always landed mid-call and the
scan was cancelled; small/fast libraries were usually idle at that instant and
completed normally.

Treat a cancelled drainer context as a deliberate shutdown: return cleanly
without escalating. Genuine external cancellation still reaches the run via the
main goroutine's scanCtx checks, so real cancels are not swallowed.

Adds a regression test (settle window made injectable) that fails against the
old handler with 'concurrent match scope ...: context canceled' and passes
with the fix.
2026-05-27 15:46:24 +00:00
Quick e4f3f6d5f7 Optimize episode added_at sorting 2026-05-27 10:11:58 -04:00
Quick 673a0e6c55 fix(metadata): accept exact cross-provider match ties 2026-05-27 09:13:30 -04:00
QuickandGitHub 6eb4c9edc6 Merge pull request #14 from Silo-Server/t3code/116da365
feat(jellycompat): sign image tags and accept them without session
2026-05-26 22:31:23 -04:00
Quick 101aa8c429 fix(jellycompat): stabilize signed image tags across restarts
{"subject":"fix(jellycompat): stabilize signed image tags across restarts","body":"- Sign library poster and episode parent series image tags from canonical paths/thumbhashes instead of presigned URLs so tags survive restarts\n- Accept signed canonical tags in the image handler without a session and fall back to legacy URL-derived cache tags\n- Always fetch series detail for episodes to build stable parent image tags"}
2026-05-26 22:29:49 -04:00
Quick f930c4f96a fix(jellycompat): harden signed image tags 2026-05-26 21:50:10 -04:00
Quick 93ed484cf6 feat(jellycompat): sign image tags and accept them without session
- HMAC-sign image tags using the configured JWT secret
- Serve item/season/episode images via signed tag without requiring a session or cache hit
2026-05-26 21:34:44 -04:00
QuickandGitHub 1b8a38a7cc Merge pull request #13 from Silo-Server/t3code/2f7d918d
feat(episode-carousel): highlight currently viewed episode
2026-05-26 21:29:37 -04:00
QuickandGitHub 90b04db4a9 Merge pull request #12 from Silo-Server/t3code/5155230b
feat(ui): shared PageBack component for consistent back navigation
2026-05-26 21:29:27 -04:00
Quick 19d9b5c75d feat(episode-carousel): highlight currently viewed episode
- Add "Now Viewing" badge with pulsing indicator on current episode
- Replace border with primary-color ring for current episode card
- Set aria-current="page" on links to the current episode
2026-05-26 21:29:11 -04:00
Quick 602fc5b413 fix(ui): make PageBack destinations deterministic 2026-05-26 21:18:39 -04:00
Quick a8ef653c11 feat(ui): add floating variant to PageBack for sticky nav
- Add `floating` prop to pin PageBack to viewport on lg+ screens
- Switch styling from glass-subtle to glass with shadow for better contrast
- Use floating variant on SettingsLayout
2026-05-26 20:51:52 -04:00
QuickandClaude Opus 4.7 f7cae960c4 feat(ui): add shared PageBack component for consistent back navigation
Replace the eight inconsistent back affordances across user-facing pages
with a single absolute-positioned chevron pill, so the control lives in
the same screen position regardless of title length or hero content.

DetailBreadcrumb keeps its textual hierarchy path but no longer owns the
back chevron; PageBack does. DetailHero gains a topNav slot consumed by
Movie/Series/Season/Episode/Request detail pages. Non-hero pages drop
their bespoke back buttons and add PageBack inside a relative wrapper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 20:18:05 -04:00
Quick bba3177fc9 fix(metadata): break duplicate provider candidate ties
- Score candidate metadata completeness and auto-match the richer duplicate when title/year/type tie
- Enrich near-duplicate candidates via the provider chain before initial match selection
- Seed both movie and series match queues for mixed-type libraries and wait for TV queue settle
- Add taskmanager worker test coverage and a plan doc for the tie-breaker work
2026-05-26 20:07:43 -04:00
Quick 332d1346e3 Merge branch 'main' of https://github.com/Silo-Server/silo-server 2026-05-26 20:05:38 -04:00
QuickandGitHub 7e142f8fa5 Merge pull request #11 from Silo-Server/t3code/eb3dedf1
feat(auth): add metadata curation permission
2026-05-26 20:05:29 -04:00
Quick a7f62020fd fix(auth): gate media file paths on metadata curation permission
- Allow curators (not just admins) to view media file paths and locations
- Apply library access filter to file-level access checks
2026-05-26 20:04:54 -04:00
Quick 6c0983c34e docs: add PageBack component design spec 2026-05-26 19:56:45 -04:00
Quick 3d791e2e9f test(auth): expand session revocation coverage 2026-05-26 19:41:55 -04:00
Quick ce6b4eee0d docs: add metadata curation permission plan 2026-05-26 19:40:00 -04:00
Quick c7d69e9ea2 fix(auth): tighten curator job response review fixes 2026-05-26 19:34:16 -04:00
Quick 21e318dc16 fix(auth): address metadata curation review issues 2026-05-26 19:27:56 -04:00
Quick c6bccd358e feat(web): show metadata tools to curators 2026-05-26 18:24:39 -04:00
Quick afaac04edf fix(web): keep device profile hooks unconditional 2026-05-26 18:24:13 -04:00
Quick 96d90b6d06 feat(web): assign metadata curation permission 2026-05-26 18:21:16 -04:00
Quick 99c2bfd1ce feat(web): add permission helpers 2026-05-26 18:18:55 -04:00
Quick 6c030d6b76 feat(api): route metadata curation by permission 2026-05-26 18:18:19 -04:00
Quick 6004dd2ddd feat(api): authorize item metadata curation 2026-05-26 18:15:05 -04:00
Quick 6f783a4a6e feat(auth): expose user permissions 2026-05-26 18:13:32 -04:00
Quick f48fd41d85 feat(auth): add assignable user permissions 2026-05-26 18:12:20 -04:00