feat(services): resolve Jellyfin/Jellyseerr from the service registry (backend)

Slice 4b backend half. Jellyfin and Jellyseerr clients are now resolved from
service instances instead of machine-level app config.

- Add jellyseerr service definition (6 service types total); add user_id to
  the Jellyfin service config.
- dependencies.py: jellyfin_service_id query param + _service_record
  (decrypt-on-read); get_jellyfin_client / get_jellyseerr_client / get_user_id
  resolve against the service registry (first enabled instance as fallback).
- SSH/Files transport (get_ssh_client) unchanged; still uses machine_id.
- Update service-registry tests for 6 types.

Selection model: split params — ?jellyfin_service_id= for Jellyfin/Jellyseerr,
?machine_id= for SSH/Files. Frontend threading follows in the next PR.

Verification: backend ruff clean, pytest 222 passed; frontend green (unchanged).
This commit is contained in:
Developer
2026-06-23 11:43:33 +00:00
parent d998e6ab0c
commit 8ff735d644
5 changed files with 155 additions and 45 deletions
@@ -57,10 +57,43 @@ npm run build # success
npm run test # 70 passed
```
## Remaining work
## Slice 4b — Jellyfin/Jellyseerr → services migration (in progress)
- Slice 4b: add `jellyseerr` service definition; rewire `dependencies.py`
Jellyfin/Jellyseerr resolution to the service registry; migrate the
Media/Users/Files/Dashboard selector from machine_id to service instance;
remove machine-level Jellyfin/Jellyseerr fields from `settings_store.py`,
`routers/settings.py`, and the Settings UI.
### Completed (backend, this PR)
- [x] Added `jellyseerr` service definition (`integrations/jellyseerr.py`) and
registered it (6 service types total).
- [x] Added `user_id` to the Jellyfin service config.
- [x] `dependencies.py`: new `_request_jellyfin_service_id` + `_service_record`
(decrypt-on-read). Rewrote `get_jellyfin_client`, `get_jellyseerr_client`,
and `get_user_id` to resolve against the service registry via the
`jellyfin_service_id` query param (first enabled instance as fallback).
- [x] SSH/Files transport (`get_ssh_client`) unchanged — still uses
`machine_id`.
- [x] Updated service-registry tests for 6 types.
### Selection model (decided)
Split query params: `?jellyfin_service_id=` selects the Jellyfin/Jellyseerr
instance; `?machine_id=` selects SSH/Files transport. Pages that need both pass
both.
### Remaining (frontend, next PR)
- Thread `jellyfinServiceId` through Media / Applications / Dashboard / Users:
list `jellyfin` service instances instead of `useMonitoringSettings()`
Jellyfin machines; pass `jellyfin_service_id` to Jellyfin API calls.
- Files page keeps `machine_id`.
- Settings UI: remove machine-level Jellyfin/Jellyseerr fields.
- Remove machine app fields from `settings_store.py` + `routers/settings.py`
once the UI no longer writes them.
### Verification (backend half)
```bash
cd backend
.venv/bin/ruff check . # clean
PYTHONPATH=src .venv/bin/python -m pytest # 222 passed
cd ../frontend
npm run lint && npm run build && npm run test # green (unchanged)
```