refactor(server): plumb Arc<Settings> through workers and routes

Config sheds its 14 Bucket-B fields (retention, whisper, ollama, llm) and
gains a sibling Arc<Settings> in AppState, loaded from settings.toml at
startup via Settings::load_or_default. Workers (transcribe, analyze,
recovery, auto_trigger) and routes (health, bulk, case_actions,
user_web) take settings as a separate parameter or State<> extractor;
Config::llm_configured moves to Settings::llm_configured.

TestConfig::build_pair() returns (Arc<Config>, Arc<Settings>); the new
create_router_with_settings / create_router_and_session_store_with_settings
helpers wire both into integration tests that exercise LLM/Whisper/Ollama.
The legacy single-Arc create_router falls back to Settings::default()
so the 17 non-LLM tests stay untouched.

Verified: cargo build clean, clippy --all-targets clean, 318 tests pass.
This commit is contained in:
2026-04-27 11:48:41 +02:00
parent 6bbbf10f77
commit a510c20e75
21 changed files with 310 additions and 248 deletions
+25
View File
@@ -12,6 +12,7 @@ pub mod oneliner_locks;
pub mod paths;
pub mod retention;
pub mod routes;
pub mod settings;
pub mod transcribe;
pub mod web_session;
@@ -28,6 +29,7 @@ use config::Config;
use gazetteer::Gazetteer;
use magic_link::MagicLinkStore;
use oneliner_locks::OnelinerLocks;
use settings::Settings;
use transcribe::TranscribeSender;
use web_session::SessionStore;
@@ -88,6 +90,7 @@ pub struct PipelineState {
#[derive(Clone)]
pub struct AppState {
pub config: Arc<Config>,
pub settings: Arc<Settings>,
pub transcribe_tx: TranscribeSender,
pub analyze_tx: AnalyzeSender,
pub session_store: SessionStore,
@@ -107,6 +110,12 @@ impl FromRef<AppState> for Arc<Config> {
}
}
impl FromRef<AppState> for Arc<Settings> {
fn from_ref(state: &AppState) -> Self {
state.settings.clone()
}
}
impl FromRef<AppState> for TranscribeSender {
fn from_ref(state: &AppState) -> Self {
state.transcribe_tx.clone()
@@ -199,11 +208,27 @@ pub fn create_router(config: Arc<Config>) -> Router {
/// shared with the router (`Arc`), so any session created via `/web/login`
/// or `/web/magic` becomes observable through it.
pub fn create_router_and_session_store(config: Arc<Config>) -> (Router, SessionStore) {
create_router_and_session_store_with_settings(config, Arc::new(Settings::default()))
}
/// Variant of [`create_router`] that takes both `Config` and `Settings`.
/// Use from tests that exercise Bucket-B paths (LLM, Whisper, Ollama URLs);
/// otherwise the [`create_router`] convenience with default Settings is enough.
pub fn create_router_with_settings(config: Arc<Config>, settings: Arc<Settings>) -> Router {
create_router_and_session_store_with_settings(config, settings).0
}
/// Variant of [`create_router_and_session_store`] that takes both `Config` and `Settings`.
pub fn create_router_and_session_store_with_settings(
config: Arc<Config>,
settings: Arc<Settings>,
) -> (Router, SessionStore) {
let (transcribe_tx, _transcribe_rx) = transcribe::channel();
let (analyze_tx, _analyze_rx) = analyze::channel();
let session_store = web_session::new_store();
let router = create_router_with_state(AppState {
config,
settings,
transcribe_tx,
analyze_tx,
session_store: session_store.clone(),