118 lines
3.4 KiB
Rust
118 lines
3.4 KiB
Rust
//! API Server Entry Point
|
|
//!
|
|
//! Configures and starts the HTTP server with JWT-based authentication.
|
|
|
|
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};
|
|
#[cfg(feature = "local-files")]
|
|
use infra::factory::build_transcode_settings_repository;
|
|
|
|
mod config;
|
|
mod database;
|
|
mod provider_registry;
|
|
mod dto;
|
|
mod error;
|
|
mod events;
|
|
mod extractors;
|
|
mod log_layer;
|
|
mod poller;
|
|
mod routes;
|
|
mod scheduler;
|
|
mod server;
|
|
mod startup;
|
|
mod state;
|
|
mod telemetry;
|
|
mod webhook;
|
|
|
|
use crate::config::Config;
|
|
use crate::state::AppState;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> anyhow::Result<()> {
|
|
let handles = telemetry::init_tracing();
|
|
|
|
let config = Config::from_env();
|
|
|
|
info!("Starting server on {}:{}", config.host, config.port);
|
|
|
|
// Setup database
|
|
let db_pool = database::init_database(&config).await?;
|
|
|
|
let user_repo = build_user_repository(&db_pool).await?;
|
|
let channel_repo = build_channel_repository(&db_pool).await?;
|
|
let schedule_repo = build_schedule_repository(&db_pool).await?;
|
|
let activity_log_repo = build_activity_log_repository(&db_pool).await?;
|
|
|
|
let user_service = UserService::new(user_repo);
|
|
let channel_service = ChannelService::new(channel_repo.clone());
|
|
|
|
// Build provider registry — all configured providers are registered simultaneously.
|
|
let provider_config_repo = build_provider_config_repository(&db_pool).await?;
|
|
|
|
let bundle = provider_registry::build_provider_registry(
|
|
&config, &db_pool, &provider_config_repo,
|
|
).await?;
|
|
|
|
let registry_arc = bundle.registry;
|
|
let provider_registry: Arc<tokio::sync::RwLock<Arc<infra::ProviderRegistry>>> =
|
|
Arc::new(tokio::sync::RwLock::new(Arc::clone(®istry_arc)));
|
|
|
|
let (event_tx, event_rx) = tokio::sync::broadcast::channel::<domain::DomainEvent>(64);
|
|
|
|
let bg_channel_repo = channel_repo.clone();
|
|
let webhook_channel_repo = channel_repo.clone();
|
|
tokio::spawn(webhook::run_webhook_consumer(
|
|
event_rx,
|
|
webhook_channel_repo,
|
|
reqwest::Client::new(),
|
|
));
|
|
|
|
let schedule_engine = ScheduleEngineService::new(
|
|
Arc::clone(®istry_arc) as Arc<dyn IProviderRegistry>,
|
|
channel_repo,
|
|
schedule_repo,
|
|
);
|
|
|
|
#[cfg(feature = "local-files")]
|
|
let transcode_settings_repo = build_transcode_settings_repository(&db_pool).await.ok();
|
|
|
|
#[allow(unused_mut)]
|
|
let mut state = AppState::new(
|
|
user_service,
|
|
channel_service,
|
|
schedule_engine,
|
|
provider_registry,
|
|
provider_config_repo,
|
|
config.clone(),
|
|
event_tx.clone(),
|
|
handles.log_tx,
|
|
handles.log_history,
|
|
activity_log_repo,
|
|
db_pool,
|
|
#[cfg(feature = "local-files")]
|
|
transcode_settings_repo,
|
|
)
|
|
.await?;
|
|
|
|
#[cfg(feature = "local-files")]
|
|
if let Some(idx) = bundle.local_index {
|
|
*state.local_index.write().await = Some(idx);
|
|
}
|
|
#[cfg(feature = "local-files")]
|
|
if let Some(tm) = bundle.transcode_manager {
|
|
*state.transcode_manager.write().await = Some(tm);
|
|
}
|
|
|
|
startup::spawn_background_tasks(
|
|
Arc::clone(&state.schedule_engine),
|
|
bg_channel_repo,
|
|
event_tx,
|
|
);
|
|
|
|
server::build_and_serve(state, &config).await
|
|
}
|