152 lines
6.3 KiB
Markdown
152 lines
6.3 KiB
Markdown
<!-- file: docs/guides/POSTGRES_STORAGE.md -->
|
|
<!-- version: 6 -->
|
|
|
|
# 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` ;
|
|
- soit **236 ressources SQL**.
|
|
|
|
PostgreSQL attend **75 index** au total dans son diagnostic : 59 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.
|
|
|
|
## 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`.
|