v0.1.0-pre.069
This commit is contained in:
42
kb-store/CHANGELOG.md
Normal file
42
kb-store/CHANGELOG.md
Normal file
@@ -0,0 +1,42 @@
|
||||
<!-- file: kb-store/CHANGELOG.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# CHANGELOG — kb-store
|
||||
|
||||
## 0.1.0-pre.069-fix-001
|
||||
|
||||
### Corrigé
|
||||
|
||||
- suppression de la section `Non publié`, incompatible avec le rôle chronologique du changelog ;
|
||||
- retrait des constats sans action du TODO et des travaux futurs du changelog.
|
||||
|
||||
### Documentation
|
||||
|
||||
- réécriture de `TODO.md` sous forme de tâches uniquement ;
|
||||
- correction des exemples de `USAGE.md` afin de ne pas utiliser l’opérateur `?`.
|
||||
|
||||
## 0.1.0-pre.069
|
||||
|
||||
### Documentation
|
||||
|
||||
- création de `TODO.md`, `USAGE.md` et du changelog détaillé ;
|
||||
- réécriture du README autour des contrats consolidés et de `PostgresStore`.
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Migré
|
||||
|
||||
- consolidation de `kb_store_core`, `kb_store_pg` et des contrats associés dans `kb-store` ;
|
||||
- migration des tables raw, observations, Core, ledger, événements décodés, couverture et matérialisations ;
|
||||
- migration des migrations SQL, diagnostics et requêtes de replay.
|
||||
|
||||
### Modifié
|
||||
|
||||
- adoption de Rust 2024 et des règles Khadhroony ;
|
||||
- maintien des modules internes privés derrière une façade publique contrôlée ;
|
||||
- erreurs structurées via `kb_core::Error` et transactions async via `sqlx`.
|
||||
|
||||
### Validation
|
||||
|
||||
- tests des DTO, pagination, filtres, schéma, migrations, diagnostics et atomicité ;
|
||||
- tests PostgreSQL réels optionnels pilotés par environnement.
|
||||
@@ -1,126 +1,52 @@
|
||||
<!-- file: kb-store/README.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# `kb-store`
|
||||
# kb-store
|
||||
|
||||
`kb-store` regroupe les contrats de persistance neutres et l’adaptateur PostgreSQL de production de Khadhroony Bot3.
|
||||
`kb-store` consolide les contrats de stockage et l’implémentation PostgreSQL de `khadhroony-bot3`.
|
||||
|
||||
La crate remplace l’ancienne séparation physique entre contrats et PostgreSQL, sans mélanger leurs responsabilités. Tous les modules restent privés et l’API stable est réexportée depuis `src/lib.rs`.
|
||||
## Périmètre
|
||||
|
||||
## Architecture
|
||||
La crate expose :
|
||||
|
||||
```text
|
||||
src/
|
||||
├── lib.rs
|
||||
├── constants.rs
|
||||
├── contracts.rs
|
||||
├── contracts/
|
||||
│ ├── dto.rs
|
||||
│ ├── dto/
|
||||
│ ├── entity.rs
|
||||
│ ├── entity/
|
||||
│ ├── error.rs
|
||||
│ ├── health.rs
|
||||
│ ├── pagination.rs
|
||||
│ └── repository.rs
|
||||
├── postgres.rs
|
||||
└── postgres/
|
||||
├── migrations.rs
|
||||
├── query.rs
|
||||
├── query/
|
||||
├── replay_candidates.rs
|
||||
├── repository.rs
|
||||
├── repository/
|
||||
├── store.rs
|
||||
└── test_serial.rs
|
||||
```
|
||||
- DTO et entités raw, observations, Core, décodage, matérialisation et ledger ;
|
||||
- traits async de repositories indépendants du backend ;
|
||||
- pagination et filtres bornés ;
|
||||
- `PostgresStore` et ses options de connexion ;
|
||||
- initialisation idempotente du schéma et migrations SQL ;
|
||||
- diagnostics read-only, healthchecks et résumés de replay ;
|
||||
- transactions atomiques pour extraction, décodage et matérialisation.
|
||||
|
||||
`contracts` ne dépend d’aucun backend. `postgres` implémente ces contrats avec `sqlx`. `lib.rs` ne contient aucune logique métier.
|
||||
## Responsabilités
|
||||
|
||||
## Direction des dépendances
|
||||
- garantir les invariants des données persistées ;
|
||||
- séparer contrats et implémentation PostgreSQL à l’intérieur de la crate consolidée ;
|
||||
- maintenir les tables canoniques `kb_sol_*` ;
|
||||
- fournir au pipeline des frontières async typées ;
|
||||
- protéger les opérations multi-tables par transactions ;
|
||||
- borner toutes les requêtes de diagnostic et de replay exposées.
|
||||
|
||||
```text
|
||||
kb-core
|
||||
↑
|
||||
kb-lib ← kb-store
|
||||
```
|
||||
## Hors périmètre
|
||||
|
||||
`MdCoreInstructionReplayInput` et sa version de contrat appartiennent à `kb-lib`, car ils sont partagés avec les décodeurs. `kb-store` les consomme et les réexporte. `kb-lib` ne dépend jamais de `kb-store`.
|
||||
La crate ne décode pas les instructions, n’acquiert pas les transactions et ne décide pas quelle matérialisation exécuter. Elle persiste les résultats produits par `kb-lib` et orchestrés par `kb-pipeline`.
|
||||
|
||||
`kb-store` ne dépend pas de `kb-config`. L’application résout sa configuration, puis construit explicitement `PostgresStoreOptions`. Cette séparation évite de coupler la persistance à la forme évolutive des profils.
|
||||
## API publique
|
||||
|
||||
## Contrats publics
|
||||
Les consommateurs utilisent principalement `PostgresStore`, `PostgresStoreOptions`, les traits `*Store`, les DTO `*Insert`/`*Row`, les filtres de replay et les diagnostics. Les constantes de tables et fonctions de validation sont publiques pour les audits et outils d’administration.
|
||||
|
||||
Les familles principales sont :
|
||||
## Relations
|
||||
|
||||
- transactions raw et observations d’acquisition ;
|
||||
- graphe core Solana : transaction, comptes, instructions, inner instructions, logs et balances ;
|
||||
- sélection et lifecycle de replay ;
|
||||
- extraction core atomique ;
|
||||
- décodage, couverture et matérialisation atomiques ;
|
||||
- ledger de traitement versionné ;
|
||||
- santé, migrations et pagination bornée.
|
||||
- dépend de `kb-core` pour les erreurs ;
|
||||
- utilise les contrats de replay de `kb-lib` ;
|
||||
- est consommée principalement par `kb-pipeline`, les scénarios de démonstration et le desktop.
|
||||
|
||||
Les traits publics sont :
|
||||
## Statut
|
||||
|
||||
- `StoreHealthStore` ;
|
||||
- `RawTransactionStore` ;
|
||||
- `CoreTransactionStore` ;
|
||||
- `CoreExtractionStore` ;
|
||||
- `DecodePipelineStore` ;
|
||||
- `ProgramObservationStore` ;
|
||||
- `DecodedEventStore` ;
|
||||
- `MaterializedEventStore` ;
|
||||
- `ProcessingLedgerStore`.
|
||||
Le stockage consolidé dispose de tests unitaires étendus et de tests PostgreSQL optionnels pilotés par environnement. Les opérations réelles exigent un serveur PostgreSQL et l’application préalable des migrations.
|
||||
|
||||
## PostgreSQL
|
||||
|
||||
`PostgresStore` fournit :
|
||||
|
||||
- connexion depuis `PostgresStoreOptions` validées ;
|
||||
- création depuis un `sqlx::PgPool` existant ;
|
||||
- initialisation idempotente des tables raw, core, decode, materialization et ledger ;
|
||||
- diagnostics de backend, migrations et tables ;
|
||||
- sélections bornées de candidats de replay ;
|
||||
- implémentations des traits store-neutral.
|
||||
|
||||
Les transactions raw sont immuables. Les écritures core, decode et materialization conservent leur lineage et utilisent le ledger pour le skip version/hash, le force replay et l’idempotence.
|
||||
|
||||
Exemple :
|
||||
|
||||
```rust
|
||||
let options = match kb_store::PostgresStoreOptions::new(
|
||||
database_url,
|
||||
8,
|
||||
5_000,
|
||||
true,
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let store = match kb_store::PostgresStore::connect(options).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
return std::result::Result::Ok(store);
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
cargo check -p kb-store
|
||||
cargo test -p kb-store
|
||||
cargo clippy -p kb-store --all-targets
|
||||
KB_POSTGRES_TEST_URL='postgres://solana:solana@localhost:5432/solana_test' \
|
||||
cargo test -p kb-store -- --nocapture
|
||||
```
|
||||
|
||||
La validation complète du jalon ajoute :
|
||||
|
||||
```bash
|
||||
cargo check --workspace
|
||||
cargo test --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
```
|
||||
## Documents
|
||||
|
||||
- [Utilisation](USAGE.md)
|
||||
- [Travaux restants](TODO.md)
|
||||
- [Historique](CHANGELOG.md)
|
||||
- [Architecture du stockage](../docs/architecture/STORAGE_ARCHITECTURE.md)
|
||||
|
||||
18
kb-store/TODO.md
Normal file
18
kb-store/TODO.md
Normal file
@@ -0,0 +1,18 @@
|
||||
<!-- file: kb-store/TODO.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# TODO — kb-store
|
||||
|
||||
## Maintenance des contrats de stockage
|
||||
|
||||
- [ ] auditer toute nouvelle requête afin de garantir une borne explicite ;
|
||||
- [ ] vérifier le caractère read-only des nouvelles requêtes de diagnostic ;
|
||||
- [ ] conserver une séparation nette entre les contrats publics et les détails SQL internes ;
|
||||
- [ ] ajouter un test PostgreSQL réel pour chaque nouvelle migration ;
|
||||
- [ ] ajouter un test d’atomicité pour chaque nouvelle transaction multi-tables ;
|
||||
- [ ] compléter le guide transversal d’exploitation PostgreSQL lors de l’ajout des procédures administratives.
|
||||
|
||||
## Extensions futures
|
||||
|
||||
- [ ] définir les outils d’administration supplémentaires prévus par le ROADMAP avant leur implémentation ;
|
||||
- [ ] documenter et tester les futures opérations historiques ajoutées à la crate.
|
||||
88
kb-store/USAGE.md
Normal file
88
kb-store/USAGE.md
Normal file
@@ -0,0 +1,88 @@
|
||||
<!-- file: kb-store/USAGE.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Utilisation de kb-store
|
||||
|
||||
## Connexion PostgreSQL
|
||||
|
||||
```rust
|
||||
let options = match kb_store::PostgresStoreOptions::new(
|
||||
database_url,
|
||||
"public".to_string(),
|
||||
10,
|
||||
std::time::Duration::from_secs(10),
|
||||
) {
|
||||
Ok(value) => value,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let store = match kb_store::PostgresStore::connect(options).await {
|
||||
Ok(value) => value,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
if let Err(error) = store.initialize_store_schema().await {
|
||||
return Err(error);
|
||||
}
|
||||
```
|
||||
|
||||
`PostgresStoreOptions::new` valide le DSN, le schéma, le nombre de connexions et le timeout. Utiliser `masked_dsn` ou `mask_postgres_dsn` dans les logs ; ne jamais journaliser le DSN brut.
|
||||
|
||||
## Diagnostics
|
||||
|
||||
```rust
|
||||
let health = store.health_snapshot().await;
|
||||
let migrations = store.migration_snapshot().await;
|
||||
let backend = store.backend_diagnostics().await;
|
||||
```
|
||||
|
||||
Les diagnostics de tables raw, Core et decode/materialization sont également disponibles par les méthodes `*_table_diagnostics`.
|
||||
|
||||
## Contrats de repositories
|
||||
|
||||
Les traits publics principaux sont :
|
||||
|
||||
- `StoreHealthStore` ;
|
||||
- `RawTransactionStore` ;
|
||||
- `CoreTransactionStore` ;
|
||||
- `CoreExtractionStore` ;
|
||||
- `DecodePipelineStore` ;
|
||||
- `ProgramObservationStore` ;
|
||||
- `DecodedEventStore` ;
|
||||
- `MaterializedEventStore` ;
|
||||
- `ProcessingLedgerStore`.
|
||||
|
||||
Ils permettent au pipeline de dépendre d’un contrat async plutôt que d’une requête SQL directe.
|
||||
|
||||
## Replay et requêtes bornées
|
||||
|
||||
```rust
|
||||
let candidates = store.replay_transaction_candidates(filter).await;
|
||||
let programs = store.replay_program_summaries(program_filter).await;
|
||||
let entities = store.replay_entity_summaries(entity_filter).await;
|
||||
```
|
||||
|
||||
Les filtres refusent les limites nulles ou supérieures aux bornes publiques. `PageRequest` impose également `DEFAULT_PAGE_SIZE` et `MAX_PAGE_SIZE`.
|
||||
|
||||
## Transactions atomiques
|
||||
|
||||
Les bundles `CoreExtractionBundle`, `DecodePersistenceBundle` et `MaterializationPersistenceBundle` regroupent les écritures qui doivent réussir ou être annulées ensemble. Les consommateurs ne doivent pas reproduire manuellement ces transactions avec des écritures isolées.
|
||||
|
||||
## Schéma et tables
|
||||
|
||||
Les constantes `RAW_STORE_TABLE_NAMES`, `CORE_STORE_TABLE_NAMES` et `DECODE_STORE_TABLE_NAMES` exposent les noms canoniques. Les fonctions `validate_*_table_names` et `is_valid_solana_table_name` servent aux audits et outils d’administration.
|
||||
|
||||
## Erreurs et invariants
|
||||
|
||||
Toutes les APIs utilisent `kb_core::Result`. Les DTO valident notamment les signatures, chemins, Program IDs, clés, montants, états de traitement et identités de ledger. Les erreurs de contrat peuvent être construites avec `storage_contract_error`.
|
||||
|
||||
## Tests instructifs
|
||||
|
||||
- les tests `*_rejects_*` documentent les invariants des DTO et filtres ;
|
||||
- `decoded_events_and_ledger_roll_back_together` vérifie l’atomicité ;
|
||||
- `optional_postgres_*_from_env` couvre les parcours réels lorsque l’environnement PostgreSQL est configuré ;
|
||||
- les tests de schéma vérifient les noms, index, contraintes et migrations.
|
||||
|
||||
## Limites
|
||||
|
||||
- backend actif : PostgreSQL ;
|
||||
- les tests réels sont optionnels sans DSN de test ;
|
||||
- la crate ne prend aucune décision de décodage ou de matérialisation.
|
||||
Reference in New Issue
Block a user