//! Server wiring: configuration and startup. mod config; pub use config::Config; use anyhow::Context; use api::{AppState, build_app}; use db::Db; use tokio::net::TcpListener; /// Connect dependencies from `config` and serve until shutdown. pub async fn run(config: Config) -> anyhow::Result<()> { let db = Db::connect(&config.database_url) .await .context("connecting to the database")?; db.migrate().await.context("running database migrations")?; let state = AppState { db, app_name: config.app_name.clone(), // Wired to config in the auth CLI task; Secure by default. cookie_secure: true, }; let listener = TcpListener::bind(&config.bind_addr) .await .with_context(|| format!("binding to {}", config.bind_addr))?; tracing::info!(addr = %config.bind_addr, "server listening"); serve(listener, state).await } /// Serve the API on an already-bound listener (used by `run` and tests). pub async fn serve(listener: TcpListener, state: AppState) -> anyhow::Result<()> { let app = build_app(state); axum::serve(listener, app) .await .context("running the HTTP server")?; Ok(()) }