From 6919158012b72ed38c46fabc1e80393a2b04f701 Mon Sep 17 00:00:00 2001 From: Developer Date: Wed, 24 Jun 2026 14:56:25 +0000 Subject: [PATCH] docs: complete Jellyfin migration, archive jellyfin-service-registry Slice 3 (final) of jellyfin-service-registry. Documents the completed migration and archives the SDD change. - docs/REQUIREMENTS.md: marked the machine-level Jellyfin follow-up resolved; added a decision-log entry (Jellyfin no longer a machine service, dead media_root/path_prefix removed; global config + path_utils retained for Jellyfin->SSH path resolution). - CHANGELOG.md: struck through the old follow-up note; added a Follow-up #2 section describing the machine field + service removal. - Archived openspec/changes/jellyfin-service-registry (no active SDD changes remain). Backend ruff clean / 239 tests pass; frontend 0 lint errors / build clean / 72 tests pass. --- .pi-map.index.md | 2 +- .pi-map.md | 4 ++-- CHANGELOG.md | 20 ++++++++++++++++--- docs/REQUIREMENTS.md | 7 +++++++ frontend/.pi-map.index.md | 2 +- frontend/.pi-map.md | 4 ++-- frontend/src/.pi-map.index.md | 2 +- frontend/src/.pi-map.md | 4 ++-- frontend/src/pages/.pi-map.index.md | 2 +- frontend/src/pages/.pi-map.md | 8 ++++---- frontend/src/types/.pi-map.index.md | 2 +- frontend/src/types/.pi-map.md | 8 ++++---- .../.pi-map.index.md | 0 .../jellyfin-service-registry/.pi-map.md | 0 .../jellyfin-service-registry/design.md | 0 .../jellyfin-service-registry/proposal.md | 0 .../jellyfin-service-registry/tasks.md | 0 17 files changed, 43 insertions(+), 22 deletions(-) rename openspec/changes/{ => archive}/jellyfin-service-registry/.pi-map.index.md (100%) rename openspec/changes/{ => archive}/jellyfin-service-registry/.pi-map.md (100%) rename openspec/changes/{ => archive}/jellyfin-service-registry/design.md (100%) rename openspec/changes/{ => archive}/jellyfin-service-registry/proposal.md (100%) rename openspec/changes/{ => archive}/jellyfin-service-registry/tasks.md (100%) diff --git a/.pi-map.index.md b/.pi-map.index.md index d45be33..4079c7b 100644 --- a/.pi-map.index.md +++ b/.pi-map.index.md @@ -16,7 +16,7 @@ dir: . Trust boundary: index routes, map orients, source decides. ## role -Root project directory for "Manage," a media and server operations tool providing documentation, container orchestration, and environment configuration for a FastAPI + React application with optional observability stack. +Root project directory for "Manage," a media library viewer and server operations tool with a FastAPI backend and React frontend. ## parent - ## children diff --git a/.pi-map.md b/.pi-map.md index d4031e8..049d3b0 100644 --- a/.pi-map.md +++ b/.pi-map.md @@ -18,7 +18,7 @@ index: ./.pi-map.index.md Trust boundary: index routes, map orients, source decides. ## role -Root project directory for "Manage," a media and server operations tool providing documentation, container orchestration, and environment configuration for a FastAPI + React application with optional observability stack. +Root project directory for "Manage," a media library viewer and server operations tool with a FastAPI backend and React frontend. ## files - .dockerignore | Specifies files and directories to exclude from Docker build context to reduce image size and improve build performance | dep: Docker - .env.example | Provides a template of environment variables for configuring application hosts, backend settings, OIDC authentication, SMTP, Grafana, and alerting across a Docker Compose deployment. @@ -34,7 +34,7 @@ Root project directory for "Manage," a media and server operations tool providin - docker-compose.yml | Defines a Docker Compose production stack for a backend and frontend application with OIDC authentication, Traefik reverse proxy routing, and Prometheus metrics exposure. | dep: Traefik, OIDC provider, Docker, SMTP server, external observability stack (Prometheus/Grafana/Loki/Alertmanager) - token-usage-output.txt | Displays a detailed token usage and cost analysis report for an AI coding session, including breakdowns by category, tool usage, cache efficiency, subagent costs, and pricing comparisons. ## arch -Containerized full-stack architecture using Docker Compose for orchestration, Traefik as reverse proxy, separate dev/production configurations, OIDC authentication, and an optional observability layer (Prometheus, Grafana, Loki, Alertmanager). +Containerized full-stack architecture using Docker Compose for orchestration, Traefik for reverse proxy routing, OIDC for authentication, and an optional observability stack (Prometheus, Grafana, Loki, Alertmanager). ## tags docker, grafana, application, compose, fastapi, prometheus, alertmanager, loki ## symbols diff --git a/CHANGELOG.md b/CHANGELOG.md index eca4568..2ab41cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -99,9 +99,23 @@ All notable changes to Manage. Breaking changes are marked with **BREAKING**. ### Notes / follow-ups -- Machine-level Jellyfin/Jellyseerr app config still powers the Media/Users/Files - pages. Migrating those onto the service registry is a separate follow-up change - (see `openspec/changes/service-registry/design.md` §12.5). +- ~~Machine-level Jellyfin/Jellyseerr app config still powers the Media/Users/Files + pages. Migrating those onto the service registry is a separate follow-up change.~~ + **Done (2026-06-23):** Jellyfin is no longer a machine service, and the dead + machine-level `media_root`/`path_prefix` fields were removed. See the + Jellyfin migration entry in `docs/REQUIREMENTS.md`. + +## Follow-up #2 — remove dead machine `media_root`/`path_prefix` + Jellyfin service + +Completes the Jellyfin migration onto the service registry. Jellyfin is no +longer a machine `services` tag (`DEFAULT_SERVICES` is now `["monitoring", +"files"]`), and the dead machine-level `media_root`/`path_prefix` fields were +removed from the settings store, `MonitoringMachineInput`, frontend types, and +the Settings UI. Jellyfin is configured exclusively as a service-registry +instance. The global `REMOTE_MEDIA_ROOT`/`REMOTE_PATH_PREFIX` config properties +and `path_utils.py` remain (files/media-index still use them for Jellyfin→SSH +path resolution). Existing DB rows may still carry these keys in `config_json`; +they are inert and get dropped on the next machine save. ## Follow-up #1 — remove dead machine Jellyfin/Jellyseerr fields diff --git a/docs/REQUIREMENTS.md b/docs/REQUIREMENTS.md index 252d95f..47ce7bd 100644 --- a/docs/REQUIREMENTS.md +++ b/docs/REQUIREMENTS.md @@ -328,9 +328,16 @@ the widget/addon-pages model were removed. `MANAGE_ENCRYPTION_KEY` is now requir > config still powers the Media/Users/Files pages. Migrating those onto the > service registry (and removing the machine app fields) is a separate change; > see `openspec/changes/service-registry/design.md` §12.5. +> +> **Update (2026-06-23):** this follow-up is now complete — Jellyfin is no +> longer a machine service, and the dead machine-level `media_root`/`path_prefix` +> fields were removed. Jellyfin is configured exclusively via the service +> registry. The global `REMOTE_MEDIA_ROOT`/`REMOTE_PATH_PREFIX` config and +> `path_utils.py` remain for Jellyfin→SSH path resolution. ## Decision Log +- 2026-06-23: Completed the Jellyfin migration onto the service registry. Jellyfin is no longer a machine `services` tag (`DEFAULT_SERVICES` is now `["monitoring", "files"]`), and the dead machine-level `media_root`/`path_prefix` fields were removed from the settings store, `MonitoringMachineInput`, frontend types, and the Settings UI. Jellyfin is configured exclusively as a service-registry instance. The global `REMOTE_MEDIA_ROOT`/`REMOTE_PATH_PREFIX` config properties and `path_utils.py` are unchanged — `routers/files.py` and the media index still use them for Jellyfin→SSH path resolution. See `openspec/changes/jellyfin-service-registry/`. - 2026-06-23: Made all observability integration service-registry first-class with zero service env config. Alertmanager is now a 6th service type (`integrations/alertmanager.py`) with an `active_alerts` widget, mirroring Grafana/Prometheus. The monitoring router resolves alertmanager/grafana/prometheus from service records (first-enabled-instance default, optional `?service_id=`); added `/api/monitoring/grafana-status` and `/prometheus-status` health probes. The Observability page discovers services from the registry (dropped `import.meta.env.VITE_GRAFANA_URL`) and renders health cards; the dashboard gained an `active_alerts` widget. Removed the backend `alertmanager_url`/`alertmanager_webhook_url` fields and the frontend `VITE_GRAFANA_URL`/`VITE_PROMETHEUS_URL` build args — observability services are configured in the UI only. Removed the `PROMETHEUS_FILE_SD_DIR` shared-file bridge + `write_prometheus_targets` file writer; external Prometheus now uses `http_sd_configs` against `GET /api/monitoring/prometheus-targets` (`build_node_exporter_targets` + that endpoint stay). The webhook receiver is log-only (dropped the outbound forward). The only observability env var remaining is `PROMETHEUS_ENABLED` (Manage's own `/metrics` toggle). See `openspec/changes/observability-service-registry/`. - 2026-06-23: Removed all observability services from the root Compose files. `docker-compose.yml` and `docker-compose.dev.yml` now deploy **only** the backend and frontend; the `monitoring` network and the `prometheus`/`loki`/`alloy`/`grafana`/`alertmanager`/`node-exporter` services and their named volumes were deleted, and the `GRAFANA_APP_HOST` Traefik rule was removed. Manage connects to **existing** Grafana/Prometheus/Alertmanager instances and does not deploy them itself. The backend `alertmanager_url` default is now empty, and the `/api/monitoring/alerts` and `/alertmanager-status` endpoints return graceful "not configured" responses when `ALERTMANAGER_URL` is unset. The previous in-compose stack is preserved as an optional standalone example in `docker-compose.observability.yml` (config under `monitoring/`, documented in `docs/observability-runbooks.md`). (The `VITE_GRAFANA_URL`/`VITE_PROMETHEUS_URL` overrides were later removed entirely — see the service-registry entry above.) - 2026-06-17: Decommissioned the legacy Manage-side system-metric scraping. Removed the backend `MonitoringPoller` (SSH-ran `df` on every machine every 5 min into a local SQLite `monitoring_machine_actions` table), the entire `services/monitoring_actions.py` module, the `/api/monitoring/poller`, `/api/monitoring/machines/{id}/actions`, and `/api/monitoring/disk` endpoints, the `monitoring_machine_actions` table (DROP on startup), the three `monitoring_poll_*` / `monitoring_action_retention_days` config knobs, and the orphaned frontend `DiskSpaceCard` + `DiskSpace` type. System metrics are now owned exclusively by Prometheus + node_exporter + Grafana. Kept the Alertmanager proxy (`/alerts`, `/alertmanager-status`, `/alertmanager-webhook`), `/prometheus-targets`, `/machines`, the `node_exporter_*` machine fields, and the on-demand `disk_usage` job template. diff --git a/frontend/.pi-map.index.md b/frontend/.pi-map.index.md index 3ea7566..0aad0ec 100644 --- a/frontend/.pi-map.index.md +++ b/frontend/.pi-map.index.md @@ -2,7 +2,7 @@ dir: frontend ## role -React-based single-page application frontend for the "Manage" project, providing the user interface with Vite tooling, Tailwind CSS styling, and OIDC authentication. +React-based single-page application frontend for the "Manage" project, built with Vite, TypeScript, Tailwind CSS, and shadcn/ui. ## parent index: ./.pi-map.index.md map: ./.pi-map.md diff --git a/frontend/.pi-map.md b/frontend/.pi-map.md index c024731..0b3a4a4 100644 --- a/frontend/.pi-map.md +++ b/frontend/.pi-map.md @@ -4,7 +4,7 @@ dir: frontend index: frontend/.pi-map.index.md ## role -React-based single-page application frontend for the "Manage" project, providing the user interface with Vite tooling, Tailwind CSS styling, and OIDC authentication. +React-based single-page application frontend for the "Manage" project, built with Vite, TypeScript, Tailwind CSS, and shadcn/ui. ## files - .gitignore | Specifies files and directories for Git to ignore in a Node.js/frontend project - Dockerfile | Multi-stage Dockerfile for building and serving a Vite-based frontend application with separate production (nginx) and development (node dev server) targets | dep: node:22-alpine, nginx:1.27-alpine, npm, vite @@ -23,7 +23,7 @@ React-based single-page application frontend for the "Manage" project, providing - vite.config.ts | Configures Vite build tool with React, Tailwind CSS, environment-based API proxying, and path aliasing for a frontend application. | dep: path, vite, @vitejs/plugin-react, @tailwindcss/vite - vitest.config.ts | Configures Vitest test runner for a React project with jsdom environment, path aliasing, and scoped test file inclusion. | dep: path, vitest/config, @vitejs/plugin-react, vitest, jsdom ## arch -SPA architecture using React with Vite for bundling/HMR, shadcn/ui component library with Tailwind CSS for styling, TypeScript with strict type checking, Vitest for testing, and Docker multi-stage builds (nginx for production serving, Node for development). +Component-driven SPA architecture using Vite for build tooling, PostCSS/Tailwind for styling, OIDC for authentication, Vitest for testing, with multi-stage Docker deployment supporting both nginx (production) and Node dev server (development) targets. ## tags react, @babel, vite, helper, typescript, project, css, eslint ## symbols diff --git a/frontend/src/.pi-map.index.md b/frontend/src/.pi-map.index.md index 8cfdca2..f220f65 100644 --- a/frontend/src/.pi-map.index.md +++ b/frontend/src/.pi-map.index.md @@ -2,7 +2,7 @@ dir: frontend/src ## role -Frontend entry point and shared utilities for a React-based admin dashboard with OIDC authentication, user state management, and Tailwind CSS theming. +Frontend application entry point and core infrastructure providing routing, OIDC authentication, global state, and styling for a React-based admin dashboard. ## parent index: frontend/.pi-map.index.md map: frontend/.pi-map.md diff --git a/frontend/src/.pi-map.md b/frontend/src/.pi-map.md index 1eba476..7290f9b 100644 --- a/frontend/src/.pi-map.md +++ b/frontend/src/.pi-map.md @@ -4,7 +4,7 @@ dir: frontend/src index: frontend/src/.pi-map.index.md ## role -Frontend entry point and shared utilities for a React-based admin dashboard with OIDC authentication, user state management, and Tailwind CSS theming. +Frontend application entry point and core infrastructure providing routing, OIDC authentication, global state, and styling for a React-based admin dashboard. ## files - App.tsx | Main application component that renders a responsive admin dashboard with OIDC authentication, dark mode, collapsible sidebar navigation, and route-based page rendering. | exp: func:App() | dep: react-router-dom, @tanstack/react-query, react, react-oidc-context, ./pages/Dashboard, ./pages/Applications, ./pages/Settings, ./pages/Users, ./pages/FileBrowser, ./pages/Actions, ./components/BackupsPage, ./components/ObservabilityPage, ./pages/ServicePage, ./pages/ServicesPage, ./auth, ./api/client, ./version, ./hooks/usePersistentState, @/components/ui/button, @/components/ui/tooltip, @/components/ui/sheet, lucide-react, ./pages/*, ./components/* - auth.ts | Manages OIDC authentication configuration and access token retrieval for a browser-based application. | exp: func:isOidcConfigured() → boolean, call:(import.meta.env.VITE_OIDC_ENABLED ?? "true").toLowerCase, call:Boolean, func:getOidcConfig(), call:window.history.replaceState, func:setAccessToken(token: string | null | undefined), func:getAccessToken() → string | null, call:getStoredAccessToken | dep: oidc-client-ts @@ -16,7 +16,7 @@ Frontend entry point and shared utilities for a React-based admin dashboard with - users.js | Transforms raw user data into a structured UI model for a user details drawer component. | exp: func:buildUserDrawerModel(user), call:displayName, call:splitValues, call:String, call:user.role.charAt(0).toUpperCase, call:user.role.slice, call:permissions.join, call:syncStatus - version.ts | Exports frontend version and build info constants with a formatter for semantic version labels | exp: FRONTEND_VERSION, FRONTEND_BUILD_INFO, FRONTEND_VERSION_LABEL, func:formatVersionLabel(version: string, buildInfo: string) → string, call:version.trim, call:buildInfo.trim ## arch -React SPA architecture with TypeScript type definitions alongside JavaScript implementations, declarative component composition, and centralized authentication/state helper modules. +React SPA architecture using component-based UI with StrictMode bootstrapping, TypeScript type definitions paired with JavaScript logic modules, and Tailwind CSS v4 theming with dark mode support. ## tags user, activity, version, state, react, pages, users, oidc ## symbols diff --git a/frontend/src/pages/.pi-map.index.md b/frontend/src/pages/.pi-map.index.md index 72b28c1..26ae96c 100644 --- a/frontend/src/pages/.pi-map.index.md +++ b/frontend/src/pages/.pi-map.index.md @@ -2,7 +2,7 @@ dir: frontend/src/pages ## role -Top-level page components constituting the primary routed views of the frontend application, each encapsulating a distinct feature domain (dashboard, media, services, actions, files, settings, users). +Top-level page components for the application's main navigation routes, each encapsulating a full-feature UI for managing services, media, files, users, settings, and system actions. ## parent index: frontend/src/.pi-map.index.md map: frontend/src/.pi-map.md diff --git a/frontend/src/pages/.pi-map.md b/frontend/src/pages/.pi-map.md index bd1c94e..9c03d67 100644 --- a/frontend/src/pages/.pi-map.md +++ b/frontend/src/pages/.pi-map.md @@ -4,7 +4,7 @@ dir: frontend/src/pages index: frontend/src/pages/.pi-map.index.md ## role -Top-level page components constituting the primary routed views of the frontend application, each encapsulating a distinct feature domain (dashboard, media, services, actions, files, settings, users). +Top-level page components for the application's main navigation routes, each encapsulating a full-feature UI for managing services, media, files, users, settings, and system actions. ## files - Actions.tsx | Provides a React component for managing reusable server tasks (shell/python actions) with CRUD operations, service selection, and execution history display. | exp: func:Actions(), call:useServiceInstances, call:useTasks, call:useSaveTask, call:useDeleteTask, call:useRunTask, call:useState, call:emptyTask, call:useMemo, call:tasks.find, call:useTaskRuns, call:setDraft, call:setDraftBaseline, call:setEditOpen, call:setRunServiceId, call:saveTask.mutateAsync, call:setTab, call:String, call:tasks.map, call:openEdit, call:initialFromTask, call:runTask.mutateAsync, call:sshServices.map, call:selectedRuns.data.items.map, call:new Date(run.created_at * 1000).toLocaleString, call:deleteTask.mutate | dep: react, ../types, ../hooks/useSettings, ../hooks/useServices, ../components/DialogFooter, ../components/HoverEditButton, ../components/SectionCard, ../components/SelectionRailCard, @/components/ui/alert, @/components/ui/badge, @/components/ui/button, @/components/ui/card, @/components/ui/dialog, @/components/ui/input, @/components/ui/label, @/components/ui/select, @/components/ui/separator, @/components/ui/tabs, @/components/ui/textarea - Applications.tsx | Renders a tabbed Applications dashboard with Jellyfin library statistics and media management, plus a placeholder for future Nextcloud support. | exp: func:Applications(), call:useState | dep: react, react-router-dom, @/components/ui/alert, @/components/ui/badge, @/components/ui/tabs, ./Media, ../hooks/useDashboard, ../hooks/useServices, ../components/SectionCard, ../components/TabbedCard @@ -14,13 +14,13 @@ Top-level page components constituting the primary routed views of the frontend - Media.tsx | A React component for managing and browsing Jellyfin media libraries with server-driven pagination, index building controls, and responsive data table display. | exp: func:Media(), call:useNavigate, call:useSearchParams, call:usePrefersSmallScreen, call:useServiceInstances, call:searchParams.get, call:jellyfinServices.find, call:useCounts, call:useLibraries, call:useMediaStatus, call:useBuildIndex, call:useStopBuildIndex, call:useForceStopBuildIndex, call:usePersistentState, call:defaultMediaTabState, call:setMediaState, call:useState, call:useEffect, call:setSearchParams, call:next.set, call:useMediaDataQuery, call:Math.floor, call:updater, call:useMemo, call:navigate, call:encodeURIComponent, call:Math.max, call:Math.ceil, call:formatDuration, call:jellyfinServices.map, call:status.item_count.toLocaleString, call:counts.movies.toLocaleString, call:counts.series.toLocaleString, call:counts.episodes.toLocaleString, call:(libraries?.length ?? 0).toLocaleString, call:buildIndex.mutate, call:stopBuildIndex.mutate, call:forceStopBuildIndex.mutate, call:Math.round, call:status?.build_items_processed?.toLocaleString, call:status?.build_items_total?.toLocaleString, call:status?.build_library_items_processed?.toLocaleString, call:status?.build_library_items_total?.toLocaleString, call:updateMediaState, call:total.toLocaleString | dep: react, react-router-dom, @tanstack/react-table, @/components/ui/data-table, @/components/ui/alert, @/components/ui/button, @/components/ui/card, @/components/ui/input, @/components/ui/label, @/components/ui/progress, @/components/ui/select, ../hooks/useMedia, ../hooks/usePersistentState, ../types, ../hooks/useServices, ../hooks/useDashboard, @/components/ui (data-table, alert, button, card, input, label, progress, select) - ServicePage.tsx | Provides a UI for viewing and editing a service instance's configuration, secrets, and widget bindings, with save and delete functionality. | exp: func:ServicePage(), call:useParams, call:useServiceInstances, call:useSaveServiceInstance, call:useDeleteServiceInstance, call:useMemo, call:services.find, call:getServiceBinding, call:useState, call:setName, call:setEnabled, call:setHydrated, call:saveService.mutateAsync, call:buildInput, call:setDeleteOpen, call:binding.widgets.map, call:deleteService.mutate | dep: react, react-router-dom, @/components/ui/alert, @/components/ui/badge, @/components/ui/button, @/components/ui/input, @/components/ui/label, @/components/ui/switch, ../hooks/useServices, ../types, ../components/SectionCard, ../components/ConfirmDialog, ../integrations/registry, @/components/ui/* - ServicesPage.tsx | A React page component for managing external service instances, allowing users to view, create, and delete service configurations with dynamic form fields based on service type schemas. | exp: func:ServicesPage(), call:useNavigate, call:useServiceInstances, call:useServiceTypes, call:useDeleteServiceInstance, call:useState, call:useMemo, call:map.get, call:list.push, call:map.set, call:[...map.entries()].sort, call:map.entries, call:a[0].localeCompare, call:types.find, call:getServiceBinding, call:setCreateOpen, call:grouped.map, call:typeName, call:instances.map, call:Object.entries(s.secrets_set).some, call:navigate, call:setDeleteId, call:Boolean, call:deleteService.mutate | dep: react, react-router-dom, @/components/ui/alert, @/components/ui/badge, @/components/ui/button, @/components/ui/input, @/components/ui/label, @/components/ui/switch, @/components/ui/dialog, lucide-react, ../hooks/useServices, ../types, ../components/SectionCard, ../components/ConfirmDialog, ../components/DialogFooter, ../integrations/registry, @/components/ui (alert, badge, button, input, label, switch, dialog) -- Settings.tsx | A React settings page component for managing monitoring machines, SSH keys, and dangerous operations with tabbed navigation, forms, and confirmation dialogs. | exp: func:Settings(), call:useMonitoringSettings, call:useSSHKeys, call:useSaveMonitoringMachine, call:useDeleteMonitoringMachine, call:useTestMonitoringMachineSSH, call:useState, call:emptyMachine, call:useMemo, call:orderedMachines.find, call:setSSHValidationMessage, call:setSSHValidationError, call:setSSHValidationStatus, call:clearSSHValidation, call:setMachineDraft, call:setEditingMachine, call:setMachineDialogOpen, call:saveMachine.mutateAsync, call:testMachineSSH.mutateAsync, call:String, call:message.toLowerCase, call:lowered.includes, call:setTab, call:orderedMachines.map, call:setSelectedMachineId, call:cn, call:openEditMachine, call:setDeleteMachineId, call:closeMachineDialog, call:saveMachineDraft, call:machineDraft.host.trim, call:Boolean, call:deleteMachine.mutate | dep: react, ../types, ../hooks/useSettings, ../components/DialogFooter, ../components/HoverEditButton, ../components/SectionCard, ../components/SelectionRailCard, ../components/TabbedCard, ../components/ConfirmDialog, @/lib/utils, @/components/ui/alert, @/components/ui/badge, @/components/ui/button, @/components/ui/card, @/components/ui/checkbox, @/components/ui/dialog, @/components/ui/input, @/components/ui/label, @/components/ui/select, @/components/ui/switch, @/components/ui/tabs, @/components/ui/textarea +- Settings.tsx | This file provides the UI components and form logic for managing application settings, including configuring monitoring machines via SSH and managing SSH keys. | exp: func:Settings(), call:useMonitoringSettings, call:useSSHKeys, call:useSaveMonitoringMachine, call:useDeleteMonitoringMachine, call:useTestMonitoringMachineSSH, call:useState, call:emptyMachine, call:useMemo, call:orderedMachines.find, call:setSSHValidationMessage, call:setSSHValidationError, call:setSSHValidationStatus, call:clearSSHValidation, call:setMachineDraft, call:setEditingMachine, call:setMachineDialogOpen, call:saveMachine.mutateAsync, call:testMachineSSH.mutateAsync, call:String, call:message.toLowerCase, call:lowered.includes, call:setTab, call:orderedMachines.map, call:setSelectedMachineId, call:cn, call:openEditMachine, call:setDeleteMachineId, call:closeMachineDialog, call:saveMachineDraft, call:machineDraft.host.trim, call:Boolean, call:deleteMachine.mutate | dep: react, ../types, ../hooks/useSettings, ../components/DialogFooter, ../components/HoverEditButton, ../components/SectionCard, ../components/SelectionRailCard, ../components/TabbedCard, ../components/ConfirmDialog, @/lib/utils, @/components/ui/alert, @/components/ui/badge, @/components/ui/button, @/components/ui/card, @/components/ui/checkbox, @/components/ui/dialog, @/components/ui/input, @/components/ui/label, @/components/ui/select, @/components/ui/switch, @/components/ui/tabs, @/components/ui/textarea - Users.tsx | Re-exports the UsersPage component from its implementation file to provide a cleaner import interface. | dep: ./UsersPage.impl - UsersPage.impl.tsx | A React page component for managing and messaging Jellyfin users with Jellyseerr enrichment, featuring a searchable directory table, user selection, email composition dialog, and queue status monitoring. | exp: func:UsersPage(), call:useUsers, call:useActivity, call:useUserMessageQueueStatus, call:useSendUserMessage, call:useIsMobile, call:useState, call:useSearchParams, call:useRef, call:useMemo, call:mergeUsersWithActivity, call:search.trim().toLowerCase, call:rows.filter, call:[ row.username, row.display_name, row.email, row.email_source, row.avatar_source, row.name_source, row.access_source, row.user_type_label, row.role, row.permissions_label, row.jellyseerr_username, row.activity_label, row.activity_summary, row.activity.primary_session?.title || "", String(row.jellyseerr_user_id ?? ""), ].some, call:String, call:value.toLowerCase().includes, call:queueStatus.active_request_id.slice, call:selectedIdSet.has, call:selectedRows.filter, call:filteredRows.filter, call:setSelectedUserIds, call:current.includes, call:current.filter, call:filteredRows.forEach, call:next.add, call:next.delete, call:Array.from, call:searchParams.get, call:resolveUserSelection, call:buildUserDrawerModel, call:sendUserMessage.reset, call:subject.trim, call:setSubject, call:htmlBody.trim, call:setHtmlBody, call:setComposeOpen, call:htmlBody.slice, call:requestAnimationFrame, call:textarea.focus, call:textarea.setSelectionRange, call:window.prompt, call:insertMarkup, call:setAttachments, call:formData.append, call:JSON.stringify, call:allSelectedRows.map, call:attachments.forEach, call:sendUserMessage.mutateAsync, call:setSearch, call:cn, call:toggleVisibleSelection, call:filteredRows.map, call:setSearchParams, call:event.stopPropagation, call:toggleUserSelected, call:userLabel(row).charAt(0).toUpperCase, call:activityBadgeVariant, call:Boolean, call:drawerModel.title.charAt(0).toUpperCase, call:drawerModel.identity.map, call:drawerModel.contactActions.map, call:drawerModel.contactActions .map((action) => action.hint) .join, call:drawerModel.permissions.map, call:closeCompose, call:sendUserMessage.data.request_id.slice, call:selectedDeliverableRows.map, call:attachments.map, call:removeAttachment | dep: react, react-router-dom, lucide-react, @/components/ui/dialog, @/components/ui/input, @/components/ui/textarea, @/components/ui/separator, @/components/ui/label, @/components/ui/avatar, @/components/ui/badge, @/components/ui/button, @/components/ui/checkbox, @/components/ui/alert, @/components/ui/progress, @/components/ui/tooltip, @/components/ui/sheet, @/components/ui/table, @/lib/utils, ../components/MetricCard, ../components/SessionActivityPanel, ../hooks/useUsers, ../hooks/useDashboard, ../hooks/useSendUserMessage, ../hooks/useUserMessageQueueStatus, ../types, ../users, ../userState, @/components/ui (dialog, input, textarea, separator, label, avatar, badge, button, checkbox, alert, progress, tooltip, sheet, table) ## arch -React functional component pages organized by feature domain, employing implementation/re-export file pairs for complex views, with each page composing CRUD operations, tabbed navigation, dynamic forms, and data tables against backend service APIs. +React functional component pattern with lazy-loaded implementations (`.impl.tsx`) behind clean re-export facades (e.g., `FileBrowser.tsx`, `Users.tsx`), using dynamic service-type schemas and tabbed dashboard composition. ## tags -call:use, components, ui, call:set, state, service, react, machine +call:use, components, ui, call:set, state, service, machine, react ## symbols - Actions - Applications diff --git a/frontend/src/types/.pi-map.index.md b/frontend/src/types/.pi-map.index.md index 1647e9b..838219a 100644 --- a/frontend/src/types/.pi-map.index.md +++ b/frontend/src/types/.pi-map.index.md @@ -2,7 +2,7 @@ dir: frontend/src/types ## role -Central TypeScript type definitions providing shared data contracts and API response interfaces for the frontend application. +Central TypeScript type definition module that provides shared interfaces and type contracts for the frontend application's API interactions and domain models. ## parent index: frontend/src/.pi-map.index.md map: frontend/src/.pi-map.md diff --git a/frontend/src/types/.pi-map.md b/frontend/src/types/.pi-map.md index ccf41e2..84980a7 100644 --- a/frontend/src/types/.pi-map.md +++ b/frontend/src/types/.pi-map.md @@ -4,14 +4,14 @@ dir: frontend/src/types index: frontend/src/types/.pi-map.index.md ## role -Central TypeScript type definitions providing shared data contracts and API response interfaces for the frontend application. +Central TypeScript type definition module that provides shared interfaces and type contracts for the frontend application's API interactions and domain models. ## files - backups.ts | Defines TypeScript interfaces for a backup system including jobs, runs, alerts, and dashboard summaries. | exp: BackupJob, BackupRun, BackupAlert, BackupDashboardSummary -- index.ts | Defines shared TypeScript interfaces for API response types used across a media server management dashboard application. | exp: MediaCounts, LibraryCount, UserDirectoryItem, UserDirectoryResponse, UserMessageResponse, UserMessageQueueStatus, NowPlayingSession, SSHKey, SSHKeyInput, SSHKeyGenerated, SavedTask, SavedTaskInput, SavedTaskRun, MonitoringMachine, MonitoringMachineInput, ResetLocalDatabaseInput, ResetLocalDatabaseResponse, SSHValidationResult, AppVersionInfo, MediaIndexStatus, MediaIndexActionResponse, MediaItem, MediaQueryResponse, FileEntry, DirectoryListing, JobTemplate, JobResult, ResolvedPath, DashboardShortcut, DashboardShortcutInput, AlertmanagerAlert, AlertmanagerAlertSummary, AlertmanagerStatus, GrafanaStatus, PrometheusStatus, PrometheusTarget, WidgetInstance, WidgetInstanceInput, WidgetDataResponse, SecretFieldInfo, ServiceWidgetKindInfo, ServiceTypeInfo, ServiceInstance, ServiceInstanceInput, BuiltinWidgetKindInfo +- index.ts | Defines shared TypeScript interfaces for API responses covering media management, monitoring, SSH keys, tasks, widgets, and system administration. | exp: MediaCounts, LibraryCount, UserDirectoryItem, UserDirectoryResponse, UserMessageResponse, UserMessageQueueStatus, NowPlayingSession, SSHKey, SSHKeyInput, SSHKeyGenerated, SavedTask, SavedTaskInput, SavedTaskRun, MonitoringMachine, MonitoringMachineInput, ResetLocalDatabaseInput, ResetLocalDatabaseResponse, SSHValidationResult, AppVersionInfo, MediaIndexStatus, MediaIndexActionResponse, MediaItem, MediaQueryResponse, FileEntry, DirectoryListing, JobTemplate, JobResult, ResolvedPath, DashboardShortcut, DashboardShortcutInput, AlertmanagerAlert, AlertmanagerAlertSummary, AlertmanagerStatus, GrafanaStatus, PrometheusStatus, PrometheusTarget, WidgetInstance, WidgetInstanceInput, WidgetDataResponse, SecretFieldInfo, ServiceWidgetKindInfo, ServiceTypeInfo, ServiceInstance, ServiceInstanceInput, BuiltinWidgetKindInfo ## arch -Flat module pattern of plain TypeScript interfaces/types with a barrel index.ts export, serving as the single source of truth for data shapes across the UI. +Flat type library pattern with domain-based file organization (backups vs. general types) and a barrel export structure via index.ts, enabling consistent type-safety across UI components and API layers. ## tags -input, response, media, status, info, widget, backup, dashboard +input, response, media, status, info, widget, backup, user ## symbols - BackupJob - BackupRun diff --git a/openspec/changes/jellyfin-service-registry/.pi-map.index.md b/openspec/changes/archive/jellyfin-service-registry/.pi-map.index.md similarity index 100% rename from openspec/changes/jellyfin-service-registry/.pi-map.index.md rename to openspec/changes/archive/jellyfin-service-registry/.pi-map.index.md diff --git a/openspec/changes/jellyfin-service-registry/.pi-map.md b/openspec/changes/archive/jellyfin-service-registry/.pi-map.md similarity index 100% rename from openspec/changes/jellyfin-service-registry/.pi-map.md rename to openspec/changes/archive/jellyfin-service-registry/.pi-map.md diff --git a/openspec/changes/jellyfin-service-registry/design.md b/openspec/changes/archive/jellyfin-service-registry/design.md similarity index 100% rename from openspec/changes/jellyfin-service-registry/design.md rename to openspec/changes/archive/jellyfin-service-registry/design.md diff --git a/openspec/changes/jellyfin-service-registry/proposal.md b/openspec/changes/archive/jellyfin-service-registry/proposal.md similarity index 100% rename from openspec/changes/jellyfin-service-registry/proposal.md rename to openspec/changes/archive/jellyfin-service-registry/proposal.md diff --git a/openspec/changes/jellyfin-service-registry/tasks.md b/openspec/changes/archive/jellyfin-service-registry/tasks.md similarity index 100% rename from openspec/changes/jellyfin-service-registry/tasks.md rename to openspec/changes/archive/jellyfin-service-registry/tasks.md