191 lines
8.1 KiB
Markdown
191 lines
8.1 KiB
Markdown
<!-- file: ks-store/USAGE.md -->
|
||
<!-- version: 7 -->
|
||
|
||
# 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 conserve 16 tables et compte désormais 240 ressources SQL atomiques et 79 index attendus après la revue des chemins de replay `pre.004`.
|
||
|
||
## 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` ;
|
||
- `AccountStateStore` ;
|
||
- `CoreExtractionStore` ;
|
||
- `DecodePipelineStore`.
|
||
|
||
`Store` implémente ces traits et délègue au backend privé.
|
||
|
||
Le couple générique observation/état de compte est opérationnel en `pre.004` : `RawTransactionStore` persiste les observations N1, puis `AccountStateStore` sélectionne et normalise de manière versionnée/idempotente vers N2. Une nouvelle version du normalizer n’est pas masquée par la présence d’un ancien état Core : le processing ledger porte l’identité/version/hash du traitement.
|
||
|
||
## 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, mais la lecture/replay utilise une union logique commune. `CoreInstructionScope` distingue explicitement `TopLevel` et `Inner`, et le lifecycle est mis à jour dans la table physique correspondant au chemin sélectionné.
|
||
|
||
## 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::after(
|
||
250,
|
||
cursor,
|
||
) {
|
||
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);
|
||
```
|
||
|
||
`PageRequest` n’expose plus d’offset durable. Pour le replay Core, le curseur encode la clé stable `(slot, signature, scope, instruction_path)` ; la requête demande `limit + 1` afin de produire `PageSlice.next_cursor` sans doublon ni saut sur un dataset figé. Les lectures interactives sont bornées à 500 lignes. Les batches de processing Core/decode/account-state utilisent leurs propres limites, plafonnées à 1 000.
|
||
|
||
## Transactions atomiques
|
||
|
||
Les bundles `AccountStatePersistenceBundle`, `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.004`, 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 79 index attendus ;
|
||
- refus d'un schéma historique `kb_sol_*` ;
|
||
- roundtrip raw/Core/decode/materialization ;
|
||
- roundtrip account observation -> account state, y compris nouvelle version de normalizer et force replay ;
|
||
- replay top-level + CPI paginé sur plusieurs pages ;
|
||
- invalidation descendante lors d’un remplacement Core/decode ;
|
||
- rollback transactionnel account-state/Core/decode.
|
||
|
||
## Travaux encore ouverts après `pre.004`
|
||
|
||
- validation PostgreSQL réelle des nouveaux chemins account-state, CPI, invalidation et pagination sur dataset représentatif ;
|
||
- revue finale des plans `EXPLAIN` avant de considérer les 79 index comme suffisants ;
|
||
- snapshot machine-readable et gel formel N1/N2/N3 dans la tranche de réconciliation technique ;
|
||
- refonte desktop fonctionnelle finale autour du nouveau baseline en `pre.005` ;
|
||
- projections N4 spécialisées, hors `0.5.3`.
|