0.5.1-pre.006

This commit is contained in:
2026-08-10 02:44:24 +02:00
parent b6a286a4df
commit 34a670eaec
72 changed files with 5589 additions and 1932 deletions

View File

@@ -1,143 +1,118 @@
<!-- file: ks-config/USAGE.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# Utilisation de ks-config
## Chargement recommandé
## 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 config_result = ks_config::read_config_json_file_with_environment(
std::path::Path::new("config/app.config.json"),
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("."),
);
let config = match config_result {
) {
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),
};
```
Cette API charge lenvironnement du workspace, résout les placeholders puis applique successivement le schéma JSON général, la désérialisation typée et les invariants métier.
Le chargeur :
Le fichier chargé par défaut par le desktop est `config/app.config.json`. `KS_CONFIG_PATH` permet de remplacer explicitement ce chemin.
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.
## Chargement de lenvironnement
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),
};
if let Some(path) = report.loaded_path {
println!("environment file: {}", path.display());
}
```
`EnvironmentLoadReport` indique le fichier chargé. Par défaut, `ks-config` sélectionne `.env`; `KS_ENV_FILE` permet den choisir un autre sans écraser les variables déjà présentes dans le processus.
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.
Les contrats denvironnement utilisent `KS_*` pour Khadhroony Solana et `KB_*` pour les besoins réellement propres au Bot.
## Résolution explicite des placeholders
## 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"));
```
Cette API retourne encore une chaîne ordinaire pouvant contenir des secrets résolus. Elle reste strictement backend jusquà lintroduction de la représentation sensible de `0.5.1-pre.006`.
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.
## Validation et parsing
## Contrat runtime résolu
```rust
if let Err(error) = ks_config::validate_config_json_schema(raw_json) {
return Err(error);
}
let config = match ks_config::parse_config_json(raw_json) {
Ok(value) => value,
Err(error) => return Err(error),
};
if let Err(error) = ks_config::validate_config(&config) {
return Err(error);
}
```
`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.
`parse_config_json` effectue déjà les deux validations ; les appels séparés servent aux outils de diagnostic.
## Schéma embarqué
```rust
let schema_text = ks_config::config_json_schema_text();
let schema_value = match ks_config::config_json_schema_value() {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("embedded app schema bytes={}", schema_text.len());
assert!(schema_value.is_object());
```
Le schéma actif est [`../config/schemas/app.config.schema.json`](../config/schemas/app.config.schema.json). Les fichiers [`../config/app.config.json`](../config/app.config.json) et [`../config/example.app.config.json`](../config/example.app.config.json) doivent tous deux être conformes.
## Sélection du profil actif
```rust
let profile = match ks_config::active_profile(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("active profile: {}", profile.name);
println!("http endpoints: {}", profile.solana.http_endpoints.len());
println!("websocket endpoints: {}", profile.solana.ws_endpoints.len());
```
Le profil applicatif ne contient plus de configuration logging. Le document logging et son `active_profile` sont chargés par `ks-logging`.
## Sérialisation
```rust
let pretty = match ks_config::serialize_config_json_pretty(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
let write_result = std::fs::write("config/generated.app.config.json", pretty);
if let Err(error) = write_result {
return Err(ks_core::Error::new(
"config_write_failed",
format!("cannot write generated configuration: {error}"),
));
}
```
La configuration est validée avant sérialisation.
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
- `AppConfig`, `ProfileConfig`, `AppSectionConfig` ;
- `DatabaseConfig`, `PostgresConfig`, `SqliteConfig`, `DataConfig` ;
- `SolanaConfig`, `HttpEndpointConfig`, `WsEndpointConfig`, `EndpointRoleConfig` ;
- `CompositionConfigDocument`, `CompositionProfileConfig`, `CompositionConfigSources` ;
- `TransportConfigDocument`, `TransportProfileConfig` ;
- `ListenersConfigDocument`, `ListenersProfileConfig` ;
- `AppConfig`, `ProfileConfig` comme contrat runtime de transition ;
- `HttpEndpointConfig`, `WsEndpointConfig`, `EndpointRoleConfig` ;
- `ListenerConfig` et ses variantes ;
- `WalletConfig`, `ExecutionConfig`, `DemoConfig`.
- `DatabaseConfig`, `WalletConfig`, `ExecutionConfig` jusqu'à leur split dédié.
Les types logging ne font plus partie de `ks-config`.
Les types logging appartiennent à `ks-logging`.
## Erreurs et invariants
## Prochaine frontière
Les erreurs utilisent `ks_core::Error` avec un code stable. Les validations couvrent notamment lunicité des profils, lexistence du profil actif, les URLs, les rôles dendpoints, les limites dexécution et les contraintes wallet.
## Tests instructifs
Les tests vérifient séparément `app.config.json` et `example.app.config.json`, le roundtrip du document général et les invariants `parser_rejects_*` / `schema_rejects_*`.
## Limites
- format JSON uniquement ;
- aucune connexion externe nest ouverte par la crate ;
- la politique de camouflage des valeurs résolues appartient à `0.5.1-pre.006`.
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.