# Utilisation de ks-store ## Ouvrir le store Le consommateur transmet uniquement le backend sélectionné et son objet d'options déjà résolu. Il ne construit jamais un pool PostgreSQL. ```rust let options = match ks_store::StoreOpenOptions::new( true, "postgres", serde_json::json!({ "url": database_url, "max_connections": 10, "connect_timeout_ms": 10_000, "auto_initialize_schema": true }), ) { Ok(value) => value, Err(error) => return Err(error), }; let store = match ks_store::Store::open(options).await { Ok(value) => value, Err(error) => return Err(error), }; ``` `Store::open` interprète les options du backend actif, crée la connexion, exécute l'auto-initialisation lorsqu'elle est configurée et capture un résumé d'initialisation sanitisé. PostgreSQL reste le seul backend opérationnel exigé en `0.5.3`; un code backend inconnu est refusé proprement. Avec PostgreSQL, l'auto-initialisation utilise un **seul orchestrateur transactionnel global**. Il ne faut pas initialiser séparément raw/Core/decode : la cohérence du baseline est vérifiée comme un contrat unique. ## Baseline PostgreSQL actif `0.5.3-pre.003` utilise directement le namespace `k_sol_*` et un baseline candidat au gel de 16 tables N1-N3. Une base contenant encore des objets `kb_sol_*` est refusée ; elle doit être supprimée/reconstruite explicitement. Les ressources actives sont sous : ```text ks-store/migrations/postgres/ schema/ tables/ constraints/ indexes/ maintenance/ truncate/ drop/ ``` Chaque fichier contient une seule instruction SQL. Les fonctions privées du backend l'embarquent par `include_str!`; le DDL n'est pas dupliqué dans des chaînes Rust. Le baseline courant compte 236 ressources SQL atomiques et 75 index attendus. ## Résumés sûrs ```rust let configuration = store.configuration_summary(); let initialization = store.initialization_summary(); let runtime = match store.runtime_summary().await { Ok(value) => value, Err(error) => return Err(error), }; ``` Ces contrats ne contiennent pas les options backend brutes. Le descripteur de connexion éventuellement exposé par `runtime.backend` est masqué par le backend propriétaire. Le résumé d'initialisation classe les ressources par modèles logiques et fournit des compteurs. `objects` expose des catégories physiques sans noms d'objets. PostgreSQL publie actuellement les catégories `table` et `index`; un futur backend peut publier d'autres catégories sans modifier le contrat desktop. ## Diagnostics de ressources ```rust let raw_resources = match store.raw_resource_diagnostics().await { Ok(value) => value, Err(error) => return Err(error), }; for resource in raw_resources { println!( "resource={} model={} available={}", resource.resource_code, resource.model_code, resource.available ); } ``` Les méthodes `core_resource_diagnostics`, `decode_resource_diagnostics` et `known_resource_diagnostics` suivent le même contrat backend-agnostique. Les codes de ressources publics sont logiques ; les noms physiques PostgreSQL restent internes. ## Contrats de repositories Les traits publics effectivement implémentés sont : - `StoreHealthStore` ; - `RawTransactionStore` ; - `CoreTransactionStore` ; - `CoreExtractionStore` ; - `DecodePipelineStore`. `Store` implémente ces traits et délègue au backend privé. Le schéma `pre.003` réserve aussi les contrats génériques d'observation/état de comptes nécessaires au gel N1/N2. Leur ingestion/replay opérationnel est raccordé dans la tranche repositories/replay suivante ; leur présence dans le baseline évite une modification structurelle ultérieure pour un futur décodeur de comptes. ## Core et replay N2 -> N3 Le replay d'instruction Core transporte désormais : - `block_time` nullable ; - `stack_height` nullable ; - `parent_instruction_path` pour les CPI ; - le contexte ordonné des instructions top-level ; - la `returnData` transactionnelle lorsqu'elle existe. Le contrat de replay Core est en version 3. Les anciens constructeurs restent utilisables pour les tests/sources synthétiques ; `ks-store` enrichit les inputs issus du Core persistant avec le contexte disponible. Les instructions top-level et CPI restent deux tables physiques. La sélection logique commune et le replay autonome des CPI sont finalisés dans la tranche repositories/replay. ## Matérialisation N3 Le journal générique est `k_sol_mat_outputs`. L'API publique utilise désormais : - `MaterializedOutputFilter` ; - `MaterializedOutputQueryRow` ; - `DecodePipelineStore::list_materialized_outputs`. `k_sol_mat_outputs` reste obligatoire même lorsque des projections N4 spécialisées existeront. ## Replay et requêtes bornées ```rust let candidates = match store.replay_transaction_candidates(filter).await { Ok(value) => value, Err(error) => return Err(error), }; let programs = match store.replay_program_summaries(program_filter).await { Ok(value) => value, Err(error) => return Err(error), }; let entities = match store.replay_entity_summaries(entity_filter).await { Ok(value) => value, Err(error) => return Err(error), }; ``` Les contrats publics utilisent `ReplayTransaction*`, `ReplayProgram*` et `ReplayEntity*`. Le scope d'instruction utilise `TopLevel`, `Inner` et `Logs`; le terme historique `outer` n'est pas introduit dans la nouvelle API store. ## Pagination bornée ```rust let first_page = ks_store::PageRequest::first_page(); let next_page = match ks_store::PageRequest::new(250, 250) { Ok(value) => value, Err(error) => return Err(error), }; assert_eq!(first_page.limit, ks_store::DEFAULT_PAGE_SIZE); assert!(next_page.limit <= ks_store::MAX_PAGE_SIZE); ``` La refonte cursorisée et la suppression des gros offsets comme contrat durable appartiennent à la tranche repositories/replay. ## 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 SQL isolées. ## Tests PostgreSQL réels Les tests opt-in utilisent `KS_SECRET_POSTGRES_TEST_URL`. Aucun credential réel ne doit être enregistré dans les fixtures ou logs. Les erreurs d'ouverture de connexion sont volontairement sanitisées. Pour `pre.003`, les validations PostgreSQL à exécuter après compilation sont particulièrement importantes : - init sur base vide ; - réouverture idempotente ; - présence des 16 tables et 75 index attendus ; - refus d'un schéma historique `kb_sol_*` ; - roundtrip raw/Core/decode/materialization ; - rollback transactionnel Core/decode. ## Travaux encore ouverts après `pre.003` - sélection/replay autonome des CPI et lecture logique top-level+CPI ; - invalidation descendante N1 -> N2 -> N3 -> N4 ; - replay opérationnel du nouveau flux d'observations/états de comptes ; - pagination cursorisée et revue finale des index par plans réels ; - snapshot machine-readable et gel formel en tranche de réconciliation technique ; - refonte desktop fonctionnelle finale autour du nouveau baseline.