0.5.1-pre.002

This commit is contained in:
2026-08-09 19:34:08 +02:00
parent 816eee59a9
commit 6a680767ae
767 changed files with 12257 additions and 12195 deletions

68
ks-config/CHANGELOG.md Normal file
View File

@@ -0,0 +1,68 @@
<!-- file: ks-config/CHANGELOG.md -->
<!-- version: 12 -->
# CHANGELOG — ks-config
## `0.5.1-pre.002`
- renomme `kb-config` en `ks-config` et l'identifiant Rust `kb_config` en `ks_config` ;
- met à jour les chemins TS-RS source vers `frontend/ts/bindings/ks_config` sans livrer les bindings générés ;
- conserve le format de configuration et les variables d'environnement historiques jusqu'aux prereleases dédiées.
## `0.5.0-pre.002`
- confirme pour `0.5.1` le split de la configuration générale et du logging en documents et schémas distincts ;
- fixe la convention cible `KS_SECRET_*` / `KS_PUBLIC_*` / `KS_*` pour les variables denvironnement propres au projet ;
- documente la séparation future source/runtime/public et interdit lusage diagnostic du JSON résolu complet ;
- précise les tâches de migration, tests externes et non-divulgation sans modifier encore le contrat runtime `0.4.8`.
## 0.4.6
- alignement de la crate sur la version fonctionnelle bot3 `0.4.6` ;
- clôture des tâches de migration applicables et report explicite des évolutions ultérieures dans le TODO.
## 0.1.0-pre.075
- validation statique que `ks-config` reste lunique propriétaire direct de `dotenvy` ;
## 0.1.0-pre.073
- ajout du guide transversal [`docs/guides/CONFIGURATION.md`](../docs/guides/CONFIGURATION.md) ;
## 0.1.0-pre.072
- reclassement du TODO selon les blocants avant `0.4.6`, les travaux `0.4.7`, les versions ultérieures et les dépendances conditionnelles.
## 0.1.0-pre.070
- enrichissement de `USAGE.md` avec plusieurs exemples couvrant les familles dAPI publiques significatives.
## 0.1.0-pre.069
### Documentation
- création de `TODO.md`, `USAGE.md` et du changelog détaillé ;
- réécriture du README selon larchitecture bot3 ;
- suppression de la section `Non publié`, incompatible avec le rôle chronologique du changelog ;
- retrait des limitations et travaux futurs, désormais maintenus dans `TODO.md` ou `USAGE.md` selon leur nature ;
- clarification de la séparation entre historique de prerelease et objectifs futurs ;
- réécriture de `TODO.md` sous forme de tâches uniquement ;
- correction des exemples de `USAGE.md` afin de ne pas utiliser lopérateur `?`.
## 0.1.0
### Migré
- migration et consolidation de la configuration typée bot2 dans `ks-config` ;
- conservation du schéma JSON, des profils, endpoints, listeners, paramètres de stockage, logging, wallet et exécution.
### Modifié
- adoption des règles Rust 2024 et Khadhroony ;
- export TypeScript contrôlé des types destinés au frontend ;
- validation structurée par `ks_core::Error`.
### Validation
- validation de lexemple contre le schéma ;
- tests de round-trip, profils actifs, placeholders, URLs, rôles et invariants opérationnels.

20
ks-config/Cargo.toml Normal file
View File

@@ -0,0 +1,20 @@
# file: ks-config/Cargo.toml
# version: 4
[package]
name = "ks-config"
version.workspace = true
edition.workspace = true
license.workspace = true
publish.workspace = true
[dependencies]
dotenvy.workspace = true
ks-core = { path = "../ks-core" }
jsonschema.workspace = true
serde.workspace = true
serde_json.workspace = true
ts-rs.workspace = true
[lints]
workspace = true

41
ks-config/README.md Normal file
View File

@@ -0,0 +1,41 @@
<!-- file: ks-config/README.md -->
<!-- version: 6 -->
# ks-config
`ks-config` définit le contrat de configuration typé du workspace, son schéma JSON embarqué et les fonctions de chargement, résolution denvironnement, validation et sérialisation.
## Responsabilités
- exposer `AppConfig` et les sections de configuration publiques ;
- valider le JSON contre le schéma embarqué ;
- appliquer les invariants métier après désérialisation ;
- charger `.env` et `.env.local` depuis la racine du workspace ;
- résoudre les placeholders `${NAME}` et `${NAME:-fallback}` ;
- sélectionner le profil actif ;
- exporter les types nécessaires au frontend avec `ts-rs`.
## Hors périmètre
La crate ninitialise ni le logging, ni PostgreSQL, ni les transports et ne manipule aucun secret de wallet. Elle fournit uniquement la configuration validée à ces consommateurs.
## Surface publique
Les principales fonctions sont `read_config_json_file_with_environment`, `parse_config_json`, `validate_config`, `validate_config_json_schema`, `active_profile` et les sérialiseurs JSON. Les types publics couvrent les profils, endpoints, listeners, logging, base de données, wallet, exécution et démonstration.
## Relations
- dépend de `ks-core` pour les erreurs structurées ;
- alimente `ks-logging`, `ks-store`, `ks-onchain-transport`, `ks-pipeline`, `ks-wallet` et les applications ;
- utilise [`../config/example.config.json`](../config/example.config.json) et [`../config/schema.config.json`](../config/schema.config.json) comme exemple utilisateur et contrat de schéma actifs.
## Statut
La configuration actuelle est fonctionnelle et validée, mais son format `0.4.8` reste monolithique. Le cadrage `0.5.0-pre.002` confirme que `0.5.1` séparera la configuration générale et le logging en documents et schémas distincts, introduira le namespace denvironnement `KS_*` et séparera les représentations source, runtime et publiques afin quaucun secret résolu ne soit exposé.
## Documents
- [Utilisation](USAGE.md)
- [Travaux restants](TODO.md)
- [Historique](CHANGELOG.md)
- [Architecture](../docs/architecture/ARCHITECTURE.md)

20
ks-config/TODO.md Normal file
View File

@@ -0,0 +1,20 @@
<!-- file: ks-config/TODO.md -->
<!-- version: 5 -->
# TODO — ks-config
## Série `0.5.x`
- [ ] `0.5.1` - séparer la configuration générale et le logging en documents et schémas JSON distincts.
- [ ] `0.5.1` - rendre la sélection du profil logging indépendante du profil généraliste.
- [ ] `0.5.1` - définir un propriétaire unique du contrat source logging et supprimer la conversion manuelle du desktop.
- [ ] `0.5.1` - migrer toutes les variables denvironnement propres au projet vers le namespace `KS_*`.
- [ ] `0.5.1` - appliquer les classes `KS_SECRET_*`, `KS_PUBLIC_*` et `KS_*` interne avec propagation de sensibilité aux valeurs composées.
- [ ] `0.5.1` - séparer les représentations source, runtime résolue, publique et diagnostic.
- [ ] `0.5.1` - interdire quun secret résolu soit sérialisé, loggé, inclus dans une erreur ou transmis via Tauri.
- [ ] `0.5.1` - supprimer lexposition frontend de `AppConfig` et `ProfileConfig` résolus complets.
- [ ] Migration - fournir une table exhaustive des anciens noms denvironnement vers `KS_*` et une stratégie explicite pour le format `0.4.8`.
- [ ] Contrat - maintenir lidentité entre chaque schéma embarqué et son fichier sous `config/`.
- [ ] Tests - ajouter les tests dAPI externe, de migration multi-fichiers et les canaris de non-divulgation.
- [ ] Documentation - mettre à jour guides, exemples et `.env.example` seulement avec limplémentation correspondante.
- [ ] Intégration - coordonner la migration avec logging, transports, pipeline, scénarios et applications.

143
ks-config/USAGE.md Normal file
View File

@@ -0,0 +1,143 @@
<!-- file: ks-config/USAGE.md -->
<!-- version: 5 -->
# Utilisation de ks-config
## Chargement recommandé
```rust
let config_result = ks_config::read_config_json_file_with_environment(
std::path::Path::new("config/example.config.json"),
std::path::Path::new("."),
);
let config = match config_result {
Ok(value) => value,
Err(error) => return Err(error),
};
let profile = match ks_config::active_profile(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
```
Cette fonction charge lenvironnement du workspace, résout les placeholders puis applique successivement le schéma JSON, la désérialisation typée et les invariants métier.
## Chargement de lenvironnement
```rust
let report = match ks_config::load_workspace_environment(std::path::Path::new(".")) {
Ok(value) => value,
Err(error) => return Err(error),
};
for path in report.loaded_files {
println!("environment file: {}", path.display());
}
```
`EnvironmentLoadReport` indique les fichiers chargés. Les placeholders non résolus sans fallback restent visibles afin que la validation ou le consommateur puisse les signaler explicitement. Le format `0.4.8` accepte encore les anciens noms denvironnement ; la migration `0.5.1` imposera le namespace `KS_*`.
## Résolution explicite des placeholders
```rust
let raw = r#"{"databaseUrl":"${KB_DATABASE_URL:-postgres://localhost/kb}"}"#;
let resolved = ks_config::resolve_environment_placeholders(raw);
assert!(resolved.contains("databaseUrl"));
```
Cette API retourne actuellement une chaîne résolue ordinaire et peut donc contenir des secrets issus de lenvironnement. Elle doit rester strictement backend et ne doit pas être utilisée pour afficher, logger ou transmettre le JSON résolu. `0.5.1` remplacera cette frontière par une résolution conservant la classification de sensibilité.
## Validation et parsing
```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);
}
```
`parse_config_json` effectue déjà les deux validations ; les appels séparés servent aux outils de diagnostic.
## Sérialisation
```rust
let compact = match ks_config::serialize_config_json(&config) {
Ok(value) => value,
Err(error) => return Err(error),
};
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.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.
## 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),
};
let property_count = schema_value
.get("properties")
.and_then(serde_json::Value::as_object)
.map_or(0, serde_json::Map::len);
println!("embedded schema bytes={}, properties={property_count}", schema_text.len());
```
Le schéma actif est aussi disponible sous [`../config/schema.config.json`](../config/schema.config.json). Le fichier [`../config/example.config.json`](../config/example.config.json) fournit un exemple utilisateur complet.
## 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());
```
## Types publics importants
- `AppConfig`, `ProfileConfig`, `AppSectionConfig` ;
- `DatabaseConfig`, `PostgresConfig`, `SqliteConfig`, `DataConfig` ;
- `SolanaConfig`, `HttpEndpointConfig`, `WsEndpointConfig`, `EndpointRoleConfig` ;
- `ListenerConfig` et ses variantes ;
- `LoggingConfig`, `LogTargetConfig`, `LogTargetFilterConfig` ;
- `WalletConfig`, `ExecutionConfig`, `DemoConfig`.
## Erreurs et invariants
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, les routes de logging et les contraintes wallet.
## Tests instructifs
Les tests `example_config_validates_against_schema`, `example_config_parses_and_resolves_active_profile` et `example_config_routes_global_and_operational_crate_files` démontrent le contrat complet de lexemple actif. Les tests `parser_rejects_*` et `schema_rejects_*` documentent les invariants refusés.
## Limites
- format JSON uniquement ;
- la crate valide les références et paramètres, mais nouvre aucune connexion externe.

View File

@@ -0,0 +1,95 @@
// file: ks-config/src/environment.rs
// version: 4
//! Environment-file loading and configuration placeholder resolution.
/// Result of loading one optional workspace environment file.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EnvironmentLoadReport {
/// Explicit or default environment file that was loaded.
pub loaded_path: std::option::Option<std::path::PathBuf>,
}
/// Loads the selected environment file without overriding process variables.
///
/// Resolution order is: existing process environment, selected `.env`, then
/// fallback text declared with `${NAME:-fallback}` placeholders.
pub fn load_workspace_environment(
workspace_root: &std::path::Path,
) -> ks_core::Result<EnvironmentLoadReport> {
let explicit_path = std::env::var("KB_ENV_FILE").ok();
let selected_path = match explicit_path {
std::option::Option::Some(path) if !path.trim().is_empty() => {
let candidate = std::path::PathBuf::from(path);
if candidate.is_absolute() { candidate } else { workspace_root.join(candidate) }
},
_ => workspace_root.join(".env"),
};
if !selected_path.exists() {
return std::result::Result::Ok(EnvironmentLoadReport { loaded_path: None });
}
return match dotenvy::from_path(&selected_path) {
std::result::Result::Ok(()) => std::result::Result::Ok(EnvironmentLoadReport {
loaded_path: std::option::Option::Some(selected_path),
}),
std::result::Result::Err(error) => std::result::Result::Err(ks_core::Error::new(
"config_env_file_load_failed",
format!("{}: {error}", selected_path.display()),
)),
};
}
/// Resolves `${NAME}` and `${NAME:-fallback}` placeholders in arbitrary text.
/// Missing variables without fallbacks are preserved for lazy consumers.
pub fn resolve_environment_placeholders(raw: &str) -> std::string::String {
let mut output = std::string::String::with_capacity(raw.len());
let bytes = raw.as_bytes();
let mut index = 0_usize;
while index < bytes.len() {
if bytes[index] == b'$' && index + 1 < bytes.len() && bytes[index + 1] == b'{' {
let start = index;
let mut end = index + 2;
while end < bytes.len() && bytes[end] != b'}' {
end += 1;
}
if end < bytes.len() {
let expression = &raw[index + 2..end];
let (name, fallback) = match expression.split_once(":-") {
std::option::Option::Some((name, fallback)) => {
(name, std::option::Option::Some(fallback))
},
std::option::Option::None => (expression, std::option::Option::None),
};
let resolved = std::env::var(name)
.ok()
.or_else(|| return fallback.map(|value| return value.to_string()));
match resolved {
std::option::Option::Some(value) => output.push_str(&value),
std::option::Option::None => output.push_str(&raw[start..=end]),
}
index = end + 1;
continue;
}
}
output.push(bytes[index] as char);
index += 1;
}
return output;
}
#[cfg(test)]
mod tests {
#[test]
fn fallback_is_used_when_variable_is_absent() {
let resolved =
super::resolve_environment_placeholders("${KB_CONFIG_TEST_MISSING:-fallback}");
assert_eq!(resolved, "fallback");
}
#[test]
fn unresolved_required_placeholder_is_preserved() {
let resolved =
super::resolve_environment_placeholders("prefix-${KB_CONFIG_TEST_MISSING}-suffix");
assert_eq!(resolved, "prefix-${KB_CONFIG_TEST_MISSING}-suffix");
}
}

79
ks-config/src/lib.rs Normal file
View File

@@ -0,0 +1,79 @@
// file: ks-config/src/lib.rs
// version: 5
//! Khadhroony Bot3 workspace configuration contract and loading helpers.
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
mod environment;
mod settings;
/// Exposes the environment loading report.
pub use self::environment::EnvironmentLoadReport;
/// Exposes workspace environment-file loading.
pub use self::environment::load_workspace_environment;
/// Exposes environment placeholder resolution.
pub use self::environment::resolve_environment_placeholders;
/// Exposes the account listener configuration type.
pub use self::settings::AccountListenerConfig;
/// Exposes the root application configuration type.
pub use self::settings::AppConfig;
/// Exposes the application section configuration type.
pub use self::settings::AppSectionConfig;
/// Exposes the local data configuration type.
pub use self::settings::DataConfig;
/// Exposes the database configuration type.
pub use self::settings::DatabaseConfig;
/// Exposes the demo application configuration type.
pub use self::settings::DemoConfig;
/// Exposes the endpoint role configuration type.
pub use self::settings::EndpointRoleConfig;
/// Exposes the execution configuration type.
pub use self::settings::ExecutionConfig;
/// Exposes the HTTP endpoint configuration type.
pub use self::settings::HttpEndpointConfig;
/// Exposes the listener configuration type.
pub use self::settings::ListenerConfig;
/// Exposes the log listener configuration type.
pub use self::settings::LogListenerConfig;
/// Exposes the logging target configuration type.
pub use self::settings::LogTargetConfig;
/// Exposes the logging target filter configuration type.
pub use self::settings::LogTargetFilterConfig;
/// Exposes the logging configuration type.
pub use self::settings::LoggingConfig;
/// Exposes the PostgreSQL configuration type.
pub use self::settings::PostgresConfig;
/// Exposes the profile configuration type.
pub use self::settings::ProfileConfig;
/// Exposes the program listener configuration type.
pub use self::settings::ProgramListenerConfig;
/// Exposes the Solana configuration type.
pub use self::settings::SolanaConfig;
/// Exposes the SQLite configuration type.
pub use self::settings::SqliteConfig;
/// Exposes the wallet configuration type.
pub use self::settings::WalletConfig;
/// Exposes the WebSocket endpoint configuration type.
pub use self::settings::WsEndpointConfig;
/// Exposes the active profile resolver.
pub use self::settings::active_profile;
/// Exposes the embedded JSON Schema text.
pub use self::settings::config_json_schema_text;
/// Exposes the embedded JSON Schema value parser.
pub use self::settings::config_json_schema_value;
/// Exposes the configuration parser from a JSON string.
pub use self::settings::parse_config_json;
/// Exposes the configuration loader from a filesystem path.
pub use self::settings::read_config_json_file;
/// Exposes configuration loading with workspace environment resolution.
pub use self::settings::read_config_json_file_with_environment;
/// Exposes the compact JSON serializer for configuration values.
pub use self::settings::serialize_config_json;
/// Exposes the pretty JSON serializer for configuration values.
pub use self::settings::serialize_config_json_pretty;
/// Exposes the typed configuration validator.
pub use self::settings::validate_config;
/// Exposes the JSON Schema validator for raw JSON configuration.
pub use self::settings::validate_config_json_schema;

1600
ks-config/src/settings.rs Normal file

File diff suppressed because it is too large Load Diff