Files
attune/crates/api/src/state.rs
2026-03-03 13:42:41 -06:00

73 lines
2.3 KiB
Rust

//! Application state shared across request handlers
use sqlx::PgPool;
use std::sync::Arc;
use tokio::sync::{broadcast, RwLock};
use crate::auth::jwt::JwtConfig;
use attune_common::{config::Config, mq::Publisher};
/// Shared application state
#[derive(Clone)]
pub struct AppState {
/// Database connection pool
pub db: PgPool,
/// JWT configuration
pub jwt_config: Arc<JwtConfig>,
/// CORS allowed origins
pub cors_origins: Vec<String>,
/// Application configuration
pub config: Arc<Config>,
/// Optional message queue publisher (shared, swappable after reconnection)
pub publisher: Arc<RwLock<Option<Arc<Publisher>>>>,
/// Broadcast channel for SSE notifications
pub broadcast_tx: broadcast::Sender<String>,
}
impl AppState {
/// Create new application state
pub fn new(db: PgPool, config: Config) -> Self {
let jwt_secret = config.security.jwt_secret.clone().unwrap_or_else(|| {
tracing::warn!(
"JWT_SECRET not set in config, using default (INSECURE for production!)"
);
"insecure_default_secret_change_in_production".to_string()
});
let jwt_config = JwtConfig {
secret: jwt_secret,
access_token_expiration: config.security.jwt_access_expiration as i64,
refresh_token_expiration: config.security.jwt_refresh_expiration as i64,
};
let cors_origins = config.server.cors_origins.clone();
// Create broadcast channel for SSE notifications (capacity 1000)
let (broadcast_tx, _) = broadcast::channel(1000);
Self {
db,
jwt_config: Arc::new(jwt_config),
cors_origins,
config: Arc::new(config),
publisher: Arc::new(RwLock::new(None)),
broadcast_tx,
}
}
/// Set the message queue publisher (called once at startup or after reconnection)
pub async fn set_publisher(&self, publisher: Arc<Publisher>) {
let mut guard = self.publisher.write().await;
*guard = Some(publisher);
}
/// Get a clone of the current publisher, if available
pub async fn get_publisher(&self) -> Option<Arc<Publisher>> {
self.publisher.read().await.clone()
}
}
/// Type alias for Arc-wrapped application state
/// Used by Axum handlers
pub type SharedState = Arc<AppState>;