From d92d629fbc2021e246f9a42fcd382dca4a0696b5 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Fri, 20 Mar 2026 00:23:25 +0100 Subject: [PATCH] feat(api): wire library_repo, app_settings_repo, library_sync_adapter into AppState; start scheduler --- k-tv-backend/api/src/main.rs | 17 ++++++++++- k-tv-backend/api/src/state.rs | 11 ++++++- k-tv-backend/infra/src/factory.rs | 32 ++++++++++++++++++++- k-tv-backend/infra/src/provider_registry.rs | 8 ++++++ 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/k-tv-backend/api/src/main.rs b/k-tv-backend/api/src/main.rs index 06b3623..88425c8 100644 --- a/k-tv-backend/api/src/main.rs +++ b/k-tv-backend/api/src/main.rs @@ -7,12 +7,13 @@ use std::sync::Arc; use tracing::info; use domain::{ChannelService, IProviderRegistry, ScheduleEngineService, UserService}; -use infra::factory::{build_activity_log_repository, build_channel_repository, build_provider_config_repository, build_schedule_repository, build_user_repository}; +use infra::factory::{build_activity_log_repository, build_app_settings_repository, build_channel_repository, build_library_repository, build_provider_config_repository, build_schedule_repository, build_user_repository}; #[cfg(feature = "local-files")] use infra::factory::build_transcode_settings_repository; mod config; mod database; +mod library_scheduler; mod provider_registry; mod dto; mod error; @@ -80,6 +81,11 @@ async fn main() -> anyhow::Result<()> { #[cfg(feature = "local-files")] let transcode_settings_repo = build_transcode_settings_repository(&db_pool).await.ok(); + let library_repo = build_library_repository(&db_pool).await?; + let app_settings_repo = build_app_settings_repository(&db_pool).await?; + let library_sync_adapter: Arc = + Arc::new(infra::FullSyncAdapter::new(Arc::clone(&library_repo))); + #[allow(unused_mut)] let mut state = AppState::new( user_service, @@ -93,6 +99,9 @@ async fn main() -> anyhow::Result<()> { handles.log_history, activity_log_repo, db_pool, + library_repo, + library_sync_adapter, + app_settings_repo, #[cfg(feature = "local-files")] transcode_settings_repo, ) @@ -113,5 +122,11 @@ async fn main() -> anyhow::Result<()> { event_tx, ); + tokio::spawn(library_scheduler::run_library_sync( + Arc::clone(&state.library_sync_adapter), + Arc::clone(&state.provider_registry), + Arc::clone(&state.app_settings_repo), + )); + server::build_and_serve(state, &config).await } diff --git a/k-tv-backend/api/src/state.rs b/k-tv-backend/api/src/state.rs index 64e37f9..3a8a522 100644 --- a/k-tv-backend/api/src/state.rs +++ b/k-tv-backend/api/src/state.rs @@ -17,7 +17,7 @@ use tokio::sync::broadcast; use crate::config::Config; use crate::events::EventBus; use crate::log_layer::LogLine; -use domain::{ActivityLogRepository, ChannelService, ProviderConfigRepository, ScheduleEngineService, UserService}; +use domain::{ActivityLogRepository, ChannelService, IAppSettingsRepository, ILibraryRepository, LibrarySyncAdapter, ProviderConfigRepository, ScheduleEngineService, UserService}; #[cfg(feature = "local-files")] use domain::TranscodeSettingsRepository; use k_core::db::DatabasePool; @@ -53,6 +53,9 @@ pub struct AppState { pub transcode_settings_repo: Option>, /// Database pool — used by infra factory functions for hot-reload. pub db_pool: Arc, + pub library_repo: Arc, + pub library_sync_adapter: Arc, + pub app_settings_repo: Arc, } impl AppState { @@ -69,6 +72,9 @@ impl AppState { log_history: Arc>>, activity_log_repo: Arc, db_pool: Arc, + library_repo: Arc, + library_sync_adapter: Arc, + app_settings_repo: Arc, #[cfg(feature = "local-files")] transcode_settings_repo: Option>, ) -> anyhow::Result { @@ -155,6 +161,9 @@ impl AppState { #[cfg(feature = "local-files")] transcode_settings_repo, db_pool, + library_repo, + library_sync_adapter, + app_settings_repo, }) } } diff --git a/k-tv-backend/infra/src/factory.rs b/k-tv-backend/infra/src/factory.rs index 472a495..d3ba331 100644 --- a/k-tv-backend/infra/src/factory.rs +++ b/k-tv-backend/infra/src/factory.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use crate::db::DatabasePool; -use domain::{ActivityLogRepository, ChannelRepository, ProviderConfigRepository, ScheduleRepository, TranscodeSettingsRepository, UserRepository}; +use domain::{ActivityLogRepository, ChannelRepository, IAppSettingsRepository, ILibraryRepository, ProviderConfigRepository, ScheduleRepository, TranscodeSettingsRepository, UserRepository}; #[derive(Debug, thiserror::Error)] pub enum FactoryError { @@ -119,6 +119,36 @@ pub async fn build_transcode_settings_repository( } } +pub async fn build_library_repository( + pool: &DatabasePool, +) -> FactoryResult> { + match pool { + #[cfg(feature = "sqlite")] + DatabasePool::Sqlite(pool) => Ok(Arc::new( + crate::library_repository::SqliteLibraryRepository::new(pool.clone()), + )), + #[allow(unreachable_patterns)] + _ => Err(FactoryError::NotImplemented( + "LibraryRepository not implemented for this database".to_string(), + )), + } +} + +pub async fn build_app_settings_repository( + pool: &DatabasePool, +) -> FactoryResult> { + match pool { + #[cfg(feature = "sqlite")] + DatabasePool::Sqlite(pool) => Ok(Arc::new( + crate::app_settings_repository::SqliteAppSettingsRepository::new(pool.clone()), + )), + #[allow(unreachable_patterns)] + _ => Err(FactoryError::NotImplemented( + "AppSettingsRepository not implemented for this database".to_string(), + )), + } +} + #[cfg(feature = "local-files")] pub struct LocalFilesBundle { pub provider: Arc, diff --git a/k-tv-backend/infra/src/provider_registry.rs b/k-tv-backend/infra/src/provider_registry.rs index 038473f..c893b73 100644 --- a/k-tv-backend/infra/src/provider_registry.rs +++ b/k-tv-backend/infra/src/provider_registry.rs @@ -42,6 +42,14 @@ impl ProviderRegistry { self.providers.is_empty() } + /// Return the provider registered under `id`, if any. + pub fn get_provider(&self, id: &str) -> Option> { + self.providers + .iter() + .find(|(pid, _)| pid == id) + .map(|(_, p)| Arc::clone(p)) + } + // ------------------------------------------------------------------------- // Internal helpers // -------------------------------------------------------------------------