# Utilisation de ks-config ## Rôle de la crate `ks-config` fournit les types, validations et chargeurs des configurations Khadhroony Solana partagées. Un binaire choisit son propre fichier de composition et combine les profils spécialisés dont il a besoin. `ks-config` ne doit pas connaître la liste des futurs workers ou applications. ## Chargement d'une composition ```rust let composed = match ks_config::read_composed_app_config_with_environment( std::path::Path::new("config/kb-app-demo-desktop.default.config.json"), std::path::Path::new("."), ) { Ok(value) => value, Err(error) => return Err(error), }; let config = composed.app_config; let profile = match ks_config::active_profile(&config) { Ok(value) => value, Err(error) => return Err(error), }; ``` Le chargeur : 1. charge l'environnement du workspace ; 2. valide la composition ; 3. résout les chemins `transport` et `listeners` déclarés par la composition ; 4. charge et valide les deux documents spécialisés ; 5. sélectionne les profils référencés ; 6. reconstruit le contrat runtime `AppConfig/ProfileConfig` ; 7. applique les invariants métier existants. Le logging reste chargé par `ks-logging`, car son type runtime appartient à cette crate. La composition fournit néanmoins le chemin et le nom de profil à sélectionner. ## Configuration transport indépendante ```rust let transport = match ks_config::read_transport_json_file_with_environment( std::path::Path::new("config/transport.config.json"), std::path::Path::new("."), ) { Ok(value) => value, Err(error) => return Err(error), }; let profile = match ks_config::transport_profile(&transport, "mainnet_research") { Ok(value) => value, Err(error) => return Err(error), }; ``` Le document expose `TransportConfigDocument` et `TransportProfileConfig` avec les endpoints HTTP/WebSocket et leurs rôles. ## Configuration listeners indépendante ```rust let listeners = match ks_config::read_listeners_json_file_with_environment( std::path::Path::new("config/listeners.config.json"), std::path::Path::new("."), ) { Ok(value) => value, Err(error) => return Err(error), }; let profile = match ks_config::listeners_profile(&listeners, "mainnet_research") { Ok(value) => value, Err(error) => return Err(error), }; ``` `resolved_listener_config` convertit ce profil spécialisé vers le contrat runtime `ListenerConfig` utilisé pendant la phase de transition. ## Chargement de l'environnement ```rust let report = match ks_config::load_workspace_environment(std::path::Path::new(".")) { Ok(value) => value, Err(error) => return Err(error), }; ``` Par défaut, `ks-config` sélectionne `.env`; `KS_ENV_FILE` permet d'en choisir un autre sans écraser les variables déjà présentes dans le processus. ## Résolution des placeholders ```rust let raw = r#"{"databaseUrl":"${KS_SECRET_POSTGRES_DEVNET_URL:-postgres://localhost/ks}"}"#; let resolved = ks_config::resolve_environment_placeholders(raw); assert!(resolved.contains("databaseUrl")); ``` La chaîne résolue peut encore contenir des secrets. Elle reste strictement backend jusqu'à l'introduction de la représentation sensible dédiée. ## Contrat runtime résolu `AppConfig` et `ProfileConfig` restent provisoirement le contrat runtime commun afin de ne pas casser tous les consommateurs pendant les splits successifs. Ils ne correspondent plus à un fichier `config/app.config.json` chargé directement. Le schéma de ce contrat résolu est `config/schemas/resolved.app.config.schema.json`. Les fixtures correspondantes sont sous `test-fixtures/config/` et ne sont pas des configurations runtime. ## Types publics importants - `CompositionConfigDocument`, `CompositionProfileConfig`, `CompositionConfigSources` ; - `TransportConfigDocument`, `TransportProfileConfig` ; - `ListenersConfigDocument`, `ListenersProfileConfig` ; - `AppConfig`, `ProfileConfig` comme contrat runtime de transition ; - `HttpEndpointConfig`, `WsEndpointConfig`, `EndpointRoleConfig` ; - `ListenerConfig` et ses variantes ; - `DatabaseConfig`, `WalletConfig`, `ExecutionConfig` jusqu'à leur split dédié. Les types logging appartiennent à `ks-logging`. ## Prochaine frontière Les sections store/data, wallet, execution et desktop seront sorties de la composition dans la prerelease suivante. Une fois cette décomposition terminée, les surfaces source/runtime/public/diagnostic et le camouflage des secrets pourront être définis sur des responsabilités stables.