Files
khadhroony-bot3/olddocs/archivekbot2/kb_store_pg/README.md
2026-07-30 17:50:29 +02:00

247 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- file: kb_store_pg/README.md -->
<!-- version: 13 -->
# kb_store_pg
`kb_store_pg` implémente le backend PostgreSQL destiné à la production.
Ce crate dépend de `kb_store_core` pour les contrats et fournit les implémentations concrètes PostgreSQL : pool, healthcheck, migrations, requêtes SQL et repositories.
## Rôle exact
`kb_store_pg` contient :
- le handle de store PostgreSQL ;
- la création effective du pool PostgreSQL ;
- le healthcheck PostgreSQL minimal ;
- les diagnostics backend : DSN masqué, schéma courant et version serveur ;
- la stratégie de migrations PostgreSQL ;
- les requêtes SQL dans `queries/` ;
- les implémentations repository dans `repositories/`.
`kb_store_pg` ne contient pas :
- de contrat applicatif générique qui devrait vivre dans `kb_store_core` ;
- de logique Tauri ;
- de logique RPC ;
- de décodeur ;
- de matérialisateur métier ;
- de création de schémas PostgreSQL applicatifs explicites ;
- de création des tables `decode`, `mat`, `catalog`, `agg` ou `wallet` avant les jalons dédiés ; la seule table `ops` active en `0.3.4` est le ledger générique de traitement.
## Convention PostgreSQL
`kb_store_pg` utilise le schéma courant/default du profil PostgreSQL, généralement `public`.
Il est interdit de créer ou d'utiliser des schémas applicatifs explicites comme :
```text
raw
core
obs
decode
mat
catalog
agg
ops
wallet
```
La séparation logique se fait dans le nom de table :
```text
kb_sol_<domain>_<name>
```
Exemples valides :
```text
kb_sol_raw_transactions
kb_sol_obs_transaction_observations
kb_sol_core_transactions
kb_sol_core_account_keys
kb_sol_core_instructions
kb_sol_core_inner_instructions
kb_sol_core_logs
kb_sol_core_balance_changes
kb_sol_obs_program_observations
kb_sol_obs_instruction_observations
kb_sol_decode_decoded_events
kb_sol_mat_trade_events
kb_sol_catalog_tokens
kb_sol_catalog_pools
kb_sol_catalog_pairs
kb_sol_ops_processing_ledger
```
Exemples interdits, écrits avec `DOT` pour que les audits textuels simples ne confondent pas documentation et usage réel :
```text
raw DOT kb_sol_rpc_transactions
raw DOT sol_transactions
core DOT sol_instructions
obs DOT program_observations
decode DOT protocol_events
ops DOT processing_ledger
```
## Layout obligatoire
```text
src/
lib.rs
pg_store.rs
migrations.rs
queries/
repositories/
```
## Conventions de dossiers
| Dossier | Rôle |
|-----------------|--------------------------------------------------------|
| `queries/` | SQL, bind et exécution SQL uniquement. |
| `repositories/` | Implémentations PostgreSQL des traits `kb_store_core`. |
Aucune structure métier, DTO ou entity ne doit être créée dans `queries/`.
## Infrastructure `0.2.2`
Le jalon `0.2.2` introduit `PostgresStoreOptions` et `PostgresStore`.
Le store sait :
- construire ses options depuis `kb_config::PostgresConfig` ;
- valider `url`, `max_connections` et `connect_timeout_ms` ;
- créer un pool `sqlx::PgPool` ;
- masquer le DSN pour les logs et l'interface ;
- lire `current_schema()` ;
- lire `version()` ;
- exécuter un healthcheck `SELECT 1` ;
- lire un snapshot de migrations non destructif.
Le store ne crée aucune table Solana lourde en `0.2.2`; raw est ajouté en `0.2.3` et core en `0.2.4`.
## Migrations
Le store applique un DDL idempotent contrôlé par le crate, dans le schéma courant du profil. Après validation réelle de la transition historique `0.2.x -> 0.3.1`, la baseline a été consolidée puis étendue par une migration additive dédiée au ledger :
```text
0001_canonical_transaction_store.sql
0002_core_store.sql
0003_processing_ledger.sql
```
Ces fichiers ne créent que les tables canoniques actuelles. Les anciens noms RPC/WS et la logique de conversion historique restent documentés dans `CHANGELOG.md`, mais ne font plus partie du DDL runtime.
Les futures migrations doivent :
- utiliser uniquement le schéma courant du profil ;
- créer des tables non qualifiées comme `kb_sol_raw_transactions` ;
- ajouter des contraintes strictes mais réversibles ;
- privilégier des index minimaux par `signature`, `slot`, `program_id` et `created_at` selon table ;
- éviter les contraintes métier prématurées.
## Règles locales
- Les commentaires de code restent en anglais.
- La documentation Markdown reste en français.
- Les exports publics sont contrôlés depuis `lib.rs`.
- Les erreurs passent par `kb_core::Error` et `kb_core::Result`.
- Les tests PostgreSQL réels sont reportables si aucun serveur local n'est garanti.
## Raw store `0.2.3`
Le jalon `0.2.3` ajoute les premières tables Solana réelles :
```text
kb_sol_raw_rpc_transactions
kb_sol_raw_ws_notifications
```
Ces tables restent dans le schéma PostgreSQL courant du profil actif. Elles sont créées par une initialisation idempotente du store PostgreSQL et non par des schémas applicatifs explicites.
La table RPC est dédupliquée par `signature`. La table WebSocket est dédupliquée par `notification_key`, avec signature optionnelle et lien optionnel vers une transaction RPC canonique déjà stockée.
La méthode `PostgresStore::initialize_raw_store_schema()` applique uniquement le schéma raw minimal. Si `database.postgres.auto_initialize_schema` vaut `true`, cette initialisation est appelée après la connexion.
`0.2.3` ne supprime pas encore physiquement les payloads raw. Les colonnes `retention_state`, `processing_state`, `raw_json_hash` et `lifecycle_reason` préparent la compaction, l'archivage et la purge future.
## Core store `0.2.4`
Le jalon `0.2.4` ajoute les tables core minimales :
```text
kb_sol_core_transactions
kb_sol_core_account_keys
kb_sol_core_instructions
kb_sol_core_inner_instructions
kb_sol_core_logs
kb_sol_core_balance_changes
```
`PostgresStore::initialize_core_store_schema()` applique le schéma raw puis le schéma core, car les transactions core peuvent référencer les transactions raw.
`PostgresStore::initialize_store_schema()` applique maintenant raw puis core. Si `database.postgres.auto_initialize_schema` vaut `true`, la connexion applique donc les deux familles de tables.
Le repository `CoreTransactionStore` est implémenté pour :
- insérer la transaction core canonique ;
- insérer les account keys résolus ;
- insérer les instructions replayables ;
- insérer les inner instructions comme contexte d'arbre ;
- insérer les logs ordonnés ;
- insérer les balance changes ;
- lister les instructions à rejouer ;
- construire `CoreInstructionReplayInput` avec contexte, dont toutes les instructions outer de la signature ordonnées par index numérique ;
- marquer le lifecycle d'une instruction.
## Baseline canonique `0.3.1`
`0.3.1` a validé sur PostgreSQL réel la transition des anciennes tables vers :
```text
kb_sol_raw_transactions
kb_sol_obs_transaction_observations
kb_sol_core_transactions.raw_transaction_id
```
La transaction raw est unique par signature et porte le document canonique versionné. Les observations sont légères et ne contiennent aucun payload transactionnel complet. Les repositories actifs exposent `RawTransactionInsert` et `TransactionObservationInsert`.
Après validation, les scripts SQL historiques ont été remplacés par la baseline courante `0001`/`0002`. Linitialiseur crate-managed conserve temporairement un chemin de compatibilité idempotent pour les workspaces encore issus de `pre.001`; il ne recrée pas les anciennes tables.
## Extraction core `0.3.4`
`kb_store_pg` implémente `CoreExtractionStore` avec une transaction PostgreSQL unique par signature. Une extraction réussie :
- remplace le graphe core de la signature par cascade ;
- insère transaction, account keys, instructions, inner instructions, logs et balance changes ;
- marque la ligne raw `core_extracted` ;
- upsert le ledger `kb_sol_ops_processing_ledger` avec la version et le hash canonique ;
- commit lensemble ou annule toutes les écritures.
Les échecs dextraction sont enregistrés séparément dans le ledger et dans létat raw afin de rester rejouables.
## Store decode et matérialisation `0.4.0`
La migration additive `0004_decode_materialization_store.sql` crée dans le schéma courant :
```text
kb_sol_decode_events
kb_sol_decode_coverage_declarations
kb_sol_decode_coverage_observations
kb_sol_mat_events
```
Ces tables réutilisent `kb_sol_ops_processing_ledger`. Les observations decode, leur couverture, létat lifecycle et le ledger sont écrits dans une même transaction PostgreSQL. Les sorties materialized et leur ledger suivent la même règle. Les colonnes JSONB portent le suffixe `_jsonb`.
## Tracing opérationnel
`kb_store_pg` utilise le target canonique `kb_store_pg`. Les décisions SQL de decode/mat/ledger et leurs rollbacks sont émises par le store lui-même. Un `mark_decode_failed`, une persistance de bundle matérialisation en statut `failed` ou une erreur transactionnelle sont écrits au niveau `error` avec les identifiants de corrélation disponibles.
Le store ne délègue pas ces détails à `kb_app_demo` et ne journalise jamais un DSN non masqué.
## Contexte outer du replay `0.4.1-pre.014`
La lecture contextualisée agrège directement `kb_sol_core_instructions` pour la signature ciblée. Elle expose les chemins outer purement numériques sous la forme stable `instructionIndex`, `instructionPath`, `programId`, `payloadJson`, `payloadHash`, avec un `ORDER BY instruction_path::BIGINT`. Linstruction cible reste présente dans le tableau. La requête est strictement en lecture et najoute aucune migration.