1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//! Shared application state for all routes. Model is reloadable after package install.
use crate::authrs::AuthrsClient;
use crate::config::ResolvedModel;
use crate::db::{pool::Pool, Dialect};
use crate::events::DecisionHubClient;
use crate::storage::StorageProvider;
use crate::tenant::TenantRegistry;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
#[derive(Clone)]
pub struct AppState {
/// Default/central pool (from DATABASE_URL).
pub pool: Pool,
/// Default/active model (used for /api/v1/:path_segment). Reloaded after package install.
pub model: Arc<RwLock<ResolvedModel>>,
/// Resolved model per package_id. For database tenants, key is "package_id:tenant_id".
pub package_models: Arc<RwLock<HashMap<String, ResolvedModel>>>,
/// Pools for database-strategy tenants, keyed by tenant_id.
pub tenant_pools: Arc<RwLock<HashMap<String, Pool>>>,
/// Tenant registry (strategy + config per tenant), loaded from central DB at startup.
pub tenant_registry: Arc<TenantRegistry>,
/// Optional blob storage provider for asset columns.
pub storage: Option<Arc<dyn StorageProvider>>,
/// Optional decision-hub client. None when DECISION_HUB_URL is not set.
pub event_client: Option<Arc<DecisionHubClient>>,
/// Optional authrs permission-check client. None when AUTHRS_URL or SERVICE_NAME is not set.
pub authrs_client: Option<Arc<AuthrsClient>>,
/// Active database dialect (set at startup via `db::active_dialect()`).
pub dialect: Arc<dyn Dialect>,
/// Per-tenant extensible-field registry cache (read-through, TTL-bounded, evicted on write).
/// Construct with `Default::default()`.
pub extensible_cache: crate::extensible_fields::RegistryCache,
/// Cached cross-package include index, built lazily from all installed package configs and
/// invalidated (set to `None`) on model reload and package install/uninstall. Initialize with
/// `Arc::new(RwLock::new(None))`.
pub cross_package_index: Arc<RwLock<Option<Arc<crate::config::CrossPackageIndex>>>>,
}