feat: multi-instance provider support

- provider_configs: add id TEXT PK; migrate existing rows (provider_type becomes id)
- local_files_index: add provider_id column + index; scope all queries per instance
- ProviderConfigRow: add id field; add get_by_id to trait
- LocalIndex:🆕 add provider_id param; all SQL scoped by provider_id
- factory: thread provider_id through build_local_files_bundle
- AppState.local_index: Option<Arc<LocalIndex>> → HashMap<String, Arc<LocalIndex>>
- admin_providers: restructured routes (POST /admin/providers create, PUT/DELETE /{id}, POST /test)
- admin_providers: use row.id as registry key for jellyfin and local_files
- files.rescan: optional ?provider=<id> query param
- frontend: add id to ProviderConfig, update api/hooks, new multi-instance panel UX
This commit is contained in:
2026-03-19 22:54:41 +01:00
parent 373e1c7c0a
commit 311fdd4006
14 changed files with 563 additions and 111 deletions

View File

@@ -9,6 +9,8 @@ use infra::auth::jwt::{JwtConfig, JwtValidator};
#[cfg(feature = "auth-oidc")]
use infra::auth::oidc::OidcService;
use std::collections::VecDeque;
#[cfg(feature = "local-files")]
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use tokio::sync::broadcast;
@@ -40,9 +42,9 @@ pub struct AppState {
pub log_history: Arc<Mutex<VecDeque<LogLine>>>,
/// Repository for persisted in-app activity events.
pub activity_log_repo: Arc<dyn ActivityLogRepository>,
/// Index for the local-files provider, used by the rescan route.
/// Indexes for local-files provider instances, keyed by provider instance id.
#[cfg(feature = "local-files")]
pub local_index: Arc<tokio::sync::RwLock<Option<Arc<infra::LocalIndex>>>>,
pub local_index: Arc<tokio::sync::RwLock<HashMap<String, Arc<infra::LocalIndex>>>>,
/// TranscodeManager for FFmpeg HLS transcoding (requires TRANSCODE_DIR).
#[cfg(feature = "local-files")]
pub transcode_manager: Arc<tokio::sync::RwLock<Option<Arc<infra::TranscodeManager>>>>,
@@ -147,7 +149,7 @@ impl AppState {
log_history,
activity_log_repo,
#[cfg(feature = "local-files")]
local_index: Arc::new(tokio::sync::RwLock::new(None)),
local_index: Arc::new(tokio::sync::RwLock::new(HashMap::new())),
#[cfg(feature = "local-files")]
transcode_manager: Arc::new(tokio::sync::RwLock::new(None)),
#[cfg(feature = "local-files")]