Files
khadhroony-bot3/docs/guides/POSTGRES_STORAGE.md
2026-08-12 14:31:48 +02:00

167 lines
7.3 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: docs/guides/POSTGRES_STORAGE.md -->
<!-- version: 7 -->
# Guide PostgreSQL et contrats de stockage
## Objectif
`ks-store` porte la frontière de stockage généraliste. PostgreSQL reste le backend opérationnel actif, mais il est encapsulé derrière la façade publique backend-agnostique `Store`.
## Connexion
Les consommateurs ne construisent plus `PostgresStore`, `PostgresStoreOptions` ni un pool SQLx. Ils transmettent le backend sélectionné et ses options résolues à `StoreOpenOptions`; `ks-store` valide et interprète ensuite les paramètres 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
}),
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let store = match ks_store::Store::open(options).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
```
Le descripteur public éventuellement affiché provient du résumé runtime et est déjà masqué par `ks-store`. Le DSN brut et les options backend ne doivent jamais être propagés dans les DTO, erreurs applicatives ou logs normaux.
## Domaines
- N1 raw/acquisition : transactions canoniques, observations de transactions et observations génériques de comptes ;
- N2 Core : transactions, clés, top-level, CPI, logs, variations de balances, return data et états de comptes ;
- N3/transverse : ledger, observations décodées, couverture et `k_sol_mat_outputs` ;
- replay/diagnostic : sélections et résumés bornés au-dessus de ces contrats.
## Baseline `0.5.3-pre.003`
`pre.003` reconstruit directement le schéma sous `k_sol_*`. Les bases Devnet/Mainnet/test historiques sont considérées reconstructibles ; aucune migration in-place depuis `kb_sol_*` n'est fournie.
Le comportement attendu à l'ouverture est :
1. base vide + auto-init : création du baseline complet ;
2. base `k_sol_*` déjà conforme : vérification/idempotence ;
3. base contenant encore des objets `kb_sol_*` : refus non destructif et demande de reconstruction explicite ;
4. `DROP`/`TRUNCATE` : opérations de maintenance distinctes, jamais déclenchées implicitement par `Store::open()`.
Le baseline candidat au gel comprend 16 tables N1-N3.
## Ressources SQL
Les ressources actives sont sous :
```text
ks-store/migrations/postgres/
schema/
tables/
constraints/
indexes/
maintenance/
truncate/
drop/
```
Chaque fichier contient une instruction SQL. Le code PostgreSQL privé utilise `include_str!` et l'orchestrateur global exécute le schéma dans une transaction unique avec advisory lock.
Il n'existe plus trois initialiseurs raw/Core/decode indépendants : **l'initialisation du schéma est globale**.
Le corpus `pre.003` contient actuellement :
- 16 créations de tables ;
- 129 ressources de contraintes ;
- 59 créations d'index explicites ;
- 16 ressources `TRUNCATE` ;
- 16 ressources `DROP` ;
- quatre index supplémentaires justifiés par le replay/invalidation `pre.004` ;
- soit **240 ressources SQL**.
PostgreSQL attend désormais **79 index** au total dans son diagnostic : 63 index explicites plus les 16 index de clé primaire créés par PostgreSQL.
Les index non uniques restent des optimisations physiques et ne font pas partie du gel logique N1-N3.
## Repositories `pre.004`
La tranche `pre.004` conserve les 16 tables et ferme les comportements suivants :
- replay logique commun top-level/CPI avec scope explicite et pagination keyset ;
- lifecycle symétrique top-level/CPI ;
- invalidation N2 Core -> N3 lors dun remplacement de signature ;
- invalidation decode -> matérialisation pour lidentité decoder exacte ;
- normalisation versionnée `k_sol_obs_account_observations` -> `k_sol_core_account_states` ;
- limites interactives à 500 et batches de processing à 1 000 ;
- traces fonctionnelles `TRACE ks-store` avec durée/lignes/outcome, sans bind values.
Les quatre nouveaux index couvrent lordre de replay CPI et les recherches dinvalidation/descendants dans coverage/materialization. Leur utilité finale doit encore être confirmée par des plans PostgreSQL réels avant le gel ; les index non uniques restent une optimisation physique.
## Statut du schéma
La façade n'utilise plus `_sqlx_migrations` comme preuve du baseline actuel. Le statut est dérivé du contrat réellement observé :
- aucune ressource connue : non initialisé ;
- toutes les ressources attendues : contrat courant ;
- présence partielle : drift/partial.
Le résumé d'initialisation expose des compteurs de modèles, tables et index sans publier leurs noms physiques.
## Compatibilité des identités de processeurs
Depuis `0.5.1-pre.003`, les identités techniques produites par `ks-lib` utilisent `ks-lib-decoder.*`, `ks-lib-executor.*` et `ks-lib-materializer.*`.
Comme les bases `0.5.2` doivent être reconstruites pour le nouveau baseline `0.5.3`, les anciennes identités `kb-lib.*` ne sont pas migrées automatiquement dans ce chantier.
## Core readiness
`pre.003` ajoute les éléments génériques nécessaires au futur redécodage :
- `block_time` sur raw/Core transaction ;
- `stack_height` sur top-level/CPI ;
- parent CPI immédiat reconstructible ;
- `k_sol_core_return_data` ;
- `k_sol_obs_account_observations` ;
- `k_sol_core_account_states` ;
- provenance de schéma optionnelle sur les observations décodées.
Ces contrats sont indépendants d'Anchor/IDL. Aucun parser Anchor ni table `anchor_*` n'appartient à `0.5.3`.
## Repositories
Les traits publics et la façade `Store` décrivent des opérations fonctionnelles indépendantes du moteur. PostgreSQL implémente ces contrats à l'intérieur de `ks-store`; aucune crate consommatrice ne reçoit `PgPool`, un type SQLx ou une requête concrète.
Le schéma des observations/états de comptes est introduit avant gel en `pre.003`; son ingestion/replay fonctionnel est raccordé dans la tranche repositories/replay suivante.
## Diagnostics
La surface publique expose :
- health snapshot ;
- schema/migration snapshot générique ;
- backend descriptor masqué ;
- résumé de configuration sanitisé ;
- résumé d'initialisation/vérification par modèle logique ;
- diagnostics de ressources sans nom physique d'objet.
Les noms de tables, index, contraintes et le SQL restent des détails backend-internes. Les traces PostgreSQL utilisent l'unique `target: crate::TRACING_TARGET` (`ks-store`) avec les champs structurés `backend="postgres"`, `domain="ks-store.pg"` et un `action` précis.
## Invariants
- aucune donnée canonique ne doit être dupliquée sans justification ;
- les écritures rejouables doivent être idempotentes ;
- la progression de campagne doit rester cohérente avec les lignes effectivement traitées ;
- les requêtes dynamiques n'acceptent que des identifiants validés ;
- les détails PostgreSQL utiles au diagnostic restent backend-internes ;
- les erreurs traversant la façade publique ne doivent jamais divulguer DSN, password ou options sensibles ;
- un nouveau décodeur doit pouvoir exploiter N1/N2/N3 sans remodelage normal de ces niveaux.
## Références
- `docs/architecture/STORAGE_ARCHITECTURE.md` ;
- `ks-store/USAGE.md` ;
- `ks-store/README.md`.