ca8927834e
Move finished change directories to openspec/changes/archive/: - configurable-dashboard-widgets - decommission-monitoring-poller - service-registry - unify-tasks-on-services All associated implementation has been merged to main.
5.2 KiB
5.2 KiB
Apply Progress: Runtime Service Registry
Change: service-registry
Apply run: PRs #7–#10 (Slices 1–4a)
Date: 2026-06-19
Slices 1–3 (MERGED)
- Slice 1 (#7): backend service foundation — encryption, integrations registry,
services + service_task_runs tables,
/api/services*CRUD. - Slice 2 (#8): backend widget rebind — service_id + widget_kind, ServiceRecord adapters, built-ins, SSH run logging, retired old widget registry.
- Slice 3 (#9): frontend services runtime — types/API/hooks, frontend registry, ServicePage, route swap, reconciled widget components + config dialog.
Slice 4a — Cleanup + services admin UI + docs (this PR)
Completed tasks
- Removed addon pages (
/addons/:addonId,AddonPage.tsx,addons/*) — superseded by service pages. - Removed
grafana_url/prometheus_urlfromconfig.py, both compose files,.env.example, and README. (FrontendVITE_GRAFANA_URL/VITE_PROMETHEUS_URLdeep-link vars retained.) - Added a Services page (
/services) with create/list/delete and a nav entry, so service pages are reachable and services are configurable in the tool itself. - Registered
/servicesroute in both route trees + sidebar nav. - Updated
docs/REQUIREMENTS.md(service registry section) and addedCHANGELOG.mdwith the breaking-upgrade note.
Decision resolved mid-slice
"Full machine migration" was scoped into 4a (cleanup) + 4b (Jellyfin/Jellyseerr
migration) because removing machine-level Jellyfin/Jellyseerr fields is deeply
coupled to the Media/Users/Files pages (load-bearing) and there is no
jellyseerr service definition yet. 4a ships the safe cleanup + the services
admin UI; 4b does the machine-app-field migration as its own reviewable change.
Files changed (Slice 4a)
- Backend:
config.py(removed grafana_url/prometheus_url). - Compose/env/docs:
docker-compose.yml,docker-compose.dev.yml,.env.example,README.md,docs/REQUIREMENTS.md,CHANGELOG.md(new). - Frontend: new
pages/ServicesPage.tsx;App.tsx(routes + nav); removedpages/AddonPage.tsx,addons/*.
Verification (Slice 4a)
cd backend
.venv/bin/ruff check . # clean
PYTHONPATH=src .venv/bin/python -m pytest # 222 passed
cd ../frontend
npm run lint # 0 errors
npm run build # success
npm run test # 70 passed
Slice 4b — Jellyfin/Jellyseerr → services migration (in progress)
Completed (backend, this PR)
- Added
jellyseerrservice definition (integrations/jellyseerr.py) and registered it (6 service types total). - Added
user_idto the Jellyfin service config. dependencies.py: new_request_jellyfin_service_id+_service_record(decrypt-on-read). Rewroteget_jellyfin_client,get_jellyseerr_client, andget_user_idto resolve against the service registry via thejellyfin_service_idquery param (first enabled instance as fallback).- SSH/Files transport (
get_ssh_client) unchanged — still usesmachine_id. - 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
jellyfinServiceIdthrough Media / Applications / Dashboard / Users: listjellyfinservice instances instead ofuseMonitoringSettings()Jellyfin machines; passjellyfin_service_idto 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.pyonce the UI no longer writes them.
Frontend half (this PR)
api/client.ts: Jellyfin-backed calls (fetchCounts,fetchLibraries,fetchActivity,fetchUsers, Media status/build/stop/force-stop, andqueryMedia) now sendjellyfin_service_idinstead ofmachine_id.hooks/useDashboard.ts,hooks/useUsers.ts,hooks/useMedia.ts: renamed the selector param tojellyfinServiceId.pages/Media.tsx+pages/Applications.tsx: select ajellyfinservice instance viauseServiceInstances("jellyfin")and persistjellyfin_service_idin the URL.- Dashboard (widget-based) and Users (default-instance) need no selector change.
- Updated Applications + Media tests for the new hook/param.
Deferred (explicit follow-up)
- Remove machine-level Jellyfin/Jellyseerr fields from
settings_store.py,routers/settings.py, and the Settings UI. Low urgency now that the runtime reads from services; the machine fields are simply unused for Jellyfin.
Verification (backend half)
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)