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

7.3 KiB
Raw Blame History

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.

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 :

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.