# `kb-store` `kb-store` regroupe les contrats de persistance neutres et l’adaptateur PostgreSQL de production 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`. ## Architecture ```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 ``` `contracts` ne dépend d’aucun backend. `postgres` implémente ces contrats avec `sqlx`. `lib.rs` ne contient aucune logique métier. ## Direction des dépendances ```text kb-core ↑ kb-lib ← kb-store ``` `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`. `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. ## Contrats publics Les familles principales sont : - 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. Les traits publics sont : - `StoreHealthStore` ; - `RawTransactionStore` ; - `CoreTransactionStore` ; - `CoreExtractionStore` ; - `DecodePipelineStore` ; - `ProgramObservationStore` ; - `DecodedEventStore` ; - `MaterializedEventStore` ; - `ProcessingLedgerStore`. ## 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 ```