Files
sasedev-knowledge/docs/studies/008-V0_0_4_POSTGRES_FOUNDATION_STUDY.md
2026-10-01 11:00:00 +02:00

14 KiB

Étude 0.0.4 — fondation PostgreSQL partagée

Objet

Cette étude de 0.0.4-alpha.1 décide l'ownership et la première architecture PostgreSQL de SaseDev Knowledge avant toute implémentation de stockage.

Elle part exclusivement de la stable Knowledge v0.0.3 publiée et vérifiée. Elle ne consulte ni n'adopte une nouvelle version de PGR.

Baseline autoritaire vérifiée

La baseline reçue au démarrage est :

tag       v0.0.3
commit    b3823972449150b72905930b806d4d15471cddce
archive   sasedev-knowledge-v0.0.3.zip
SHA-256   82407dc2a83be878daa65692f975681428d0adc721ff249c3c9020e3a9d1f29d
report    sasedev-knowledge-0.0.3-publish.001-report.md = PASS

La vérification de démarrage confirme :

  • VERSION = 0.0.3 et [workspace.package].version = 0.0.3 dans l'archive ;
  • neuf packages Cargo et aucune crate PostgreSQL déjà matérialisée ;
  • douze deltas et douze histories 0.0.3, appariés jusqu'à rel.1.fix.1 = PASS ;
  • Git lecture/écriture contrôlée stable et provider-neutral ;
  • ROADMAP.md engage déjà 0.0.4 comme fondation PostgreSQL partagée ;
  • prompts/004-V0_0_4_START_PROMPT.md est présent dans la stable ;
  • PGR v0.1.3 reste uniquement une provenance historique de l'adoption fermée en 0.0.2.

Contraintes acquises

La fondation doit préserver simultanément :

Git                      vérité du contenu publié
PostgreSQL               état applicatif transversal et projections reconstructibles
knowledge-domain-lib     aucun type SQL/Actix/Gitea
knowledge-git-api        contrats Git provider-neutral
knowledge-git-lib        configuration physique et opérations Git
knowledge-app-lib        orchestration applicative
knowledge-web-lib        composition Web partagée

La première implémentation PostgreSQL ne doit pas entraîner par symétrie une nouvelle crate -api, un service réseau, trois bases séparées, un ORM complet, un scheduler ou un modèle de contenu final.

Sources techniques consultées

Consultation effectuée le 2026-09-30 sur les documentations publiées des crates comparées :

Comparaison des options Rust

État des versions consultées le 2026-09-30 : SQLx 0.9.0, tokio-postgres 0.7.18, deadpool-postgres 0.14.2, Diesel 2.3.13, diesel-async 0.9.2, SeaORM 2.0.4 et Refinery 0.9.2.

Option Atouts pour Knowledge Coûts / inadéquations Décision
tokio-postgres + Deadpool + Refinery driver PostgreSQL async natif, responsabilités séparées, SQL explicite, pool spécialisé et migrations SQL intégrées trois briques à versionner et intégrer ; la façade Knowledge doit normaliser leurs erreurs SELECT
SQLx 0.9 async/Tokio, PostgreSQL natif, pool et migrations intégrés, SQL explicite toolkit multi-SGBD plus large que le besoin ; MSRV 1.94; ses macros de requêtes ne sont pas nécessaires ici REJECT
Diesel + diesel-async typage/DSL fort, écosystème migrations, pooling disponible modèle ORM/query-builder plus large que le premier schéma et davantage de surface de génération/traits REJECT
SeaORM ORM async complet, migrations, relations et modèles riches surdimensionné avant les modèles/projections 0.0.5; risque de faire remonter l'ORM dans les contrats REJECT

La sélection privilégie des responsabilités explicitement bornées plutôt qu'un toolkit généraliste. Knowledge cible PostgreSQL comme choix de produit : l'abstraction multi-SGBD de SQLx n'apporte donc pas de valeur attendue pour cette fondation. Le coût de composition de trois briques reste acceptable parce que chacune possède une responsabilité unique et vérifiable.

Décision de dépendance

La première implémentation utilisera tokio-postgres comme driver PostgreSQL asynchrone natif, deadpool-postgres comme pool et refinery comme owner technique des migrations SQL. Aucun ORM n'est sélectionné et aucune abstraction multi-SGBD n'est recherchée.

Les versions observées pendant l'étude sont tokio-postgres 0.7.18, deadpool-postgres 0.14.2 et refinery 0.9.2. tokio-postgres et deadpool-postgres déclarent actuellement Rust 2024 avec un MSRV 1.85; Refinery vise les Rust stable récents. alpha.2 a revalidé ces versions le 2026-09-30 avant leur ajout au manifest et retient les features minimales runtime pour tokio-postgres, rt_tokio_1 pour deadpool-postgres et tokio-postgres pour Refinery. Tokio 1.53.1 est ajouté uniquement comme runtime de test d'intégration.

La séparation est volontaire :

tokio-postgres     protocole, connexion, requêtes et transactions PostgreSQL
deadpool-postgres  cycle de vie et mutualisation des connexions
refinery           découverte, historique et application des migrations SQL

La façade publique de knowledge-store-postgres-lib masque ces dépendances et normalise leurs erreurs dans le type d'erreur de la crate. Les types tokio-postgres, Deadpool ou Refinery ne doivent pas remonter dans knowledge-domain-lib ni dans les contrats applicatifs.

alpha.2 matérialise la première connexion avec tokio_postgres::NoTls et n'ajoute aucune dépendance TLS prématurée. Si une cible de déploiement PostgreSQL exige TLS, une tranche ultérieure devra sélectionner explicitement l'intégration TLS minimale compatible avec tokio-postgres au lieu d'hériter d'un défaut implicite.

Ownership

La responsabilité est suffisamment concrète pour justifier :

knowledge-store-postgres-lib

À partir d'alpha.2, cette crate possède :

  • construction et lifecycle du pool deadpool-postgres ;
  • migrations SQL de Knowledge ;
  • mapping SQL des types nécessaires ;
  • persistance de configuration logique de source ;
  • persistance de l'état de synchronisation ;
  • erreurs publiques récupérables de cette frontière.

Elle dépendra des types domaine/Git strictement nécessaires, jamais l'inverse.

Aucun knowledge-store-api n'est créé en 0.0.4-alpha.1. Si une deuxième implémentation réelle ou un besoin de fake transverse rend plus tard une frontière passive utile, cette décision sera réévaluée à partir d'un usage concret.

Connexion, pool et secrets

La crate de stockage ne lit pas l'environnement. La composition lui fournit une configuration contenant au minimum l'URL PostgreSQL et les paramètres de pool retenus.

L'URL peut contenir un secret et respecte donc les invariants suivants :

  • aucune valeur réelle versionnée ;
  • aucune URL complète dans les erreurs publiques ou logs ;
  • aucune valeur par défaut de production codée en dur ;
  • aucune tentative de fallback vers un fichier, SQLite ou un stockage mémoire si PostgreSQL est indisponible.

Le pool est partagé par l'instance applicative qui compose le store. Les trois produits peuvent pointer vers la même base logique sans que chaque launcher réimplémente sa propre couche SQL.

Premier schéma utile

Le premier schéma est volontairement plus petit que l'état futur décrit dans l'architecture.

knowledge_sources

source_id         TEXT PRIMARY KEY
family            TEXT NOT NULL
git_reference     TEXT NOT NULL

source_id correspond à SourceId. family représente ContentFamily avec une contrainte SQL sur les valeurs supportées. git_reference est la référence Git logique à résoudre, pas une URL remote ni un credential. Les valeurs family persistées sont pgr, howto, snippet et project_local; la migration doit les contraindre explicitement.

knowledge_source_sync_state

source_id                   TEXT PRIMARY KEY REFERENCES knowledge_sources(source_id) ON DELETE CASCADE
last_synchronized_revision  TEXT NOT NULL

La révision stockée représente la dernière révision effectivement acceptée par le cas d'usage de synchronisation. Elle est un état applicatif de comparaison. Git reste capable de fournir l'identité autoritaire et une valeur PostgreSQL perdue ou obsolète conduit à une nouvelle réconciliation, pas à une perte du contenu publié.

Le schéma n'ajoute pas encore :

  • corps ou métadonnées éditoriales de contenu ;
  • révision indexée séparée avant l'implémentation réelle des projections ;
  • utilisateurs/sessions ;
  • propositions/revues ;
  • jobs ;
  • audit applicatif ;
  • moteur de recherche.

Migrations

Les migrations sont des fichiers SQL versionnés sous :

crates/knowledge-store-postgres-lib/migrations/

La crate embarque le jeu de migrations au build et expose une opération explicite d'application. Le schéma n'est pas créé implicitement à chaque requête.

Les migrations sont forward-only pour cette fondation : une correction de schéma publiée utilise une nouvelle migration. Un rollback destructif automatique n'est pas requis pour fermer 0.0.4.

Stratégie de test PostgreSQL

Le test réel doit prouver PostgreSQL, pas une imitation en mémoire.

La stratégie retenue est :

KNOWLEDGE_POSTGRES_TEST_URL
  -> PostgreSQL local ou service CI explicitement fourni
  -> création d'un schéma de test unique
  -> search_path borné à ce schéma
  -> application des migrations
  -> tests CRUD / état de synchronisation
  -> suppression du schéma

Cette stratégie évite d'imposer Docker dans la bibliothèque tout en autorisant un service container en CI. L'absence du service requis pendant une gate qui exige le test PostgreSQL est BLOCKED, pas PASS.

Les tests unitaires sans PostgreSQL restent utiles pour les validations de types/configuration qui n'ont pas besoin d'un serveur réel, mais ils ne remplacent pas l'intégration PostgreSQL de migration et persistance.

Raccord au cas d'usage de synchronisation

Le cas d'usage existant synchronize_repository reçoit actuellement previous_revision de son appelant. 0.0.4 doit conserver cette primitive provider-neutral.

Le raccord prévu est une orchestration supplémentaire qui :

charge last_synchronized_revision
-> appelle synchronize_repository
-> enregistre la révision observée après succès

Un contrat passif de persistance peut vivre dans knowledge-app-lib si alpha.4 démontre qu'il est nécessaire pour tester cette orchestration sans coupler l'application au driver PostgreSQL. Cette possibilité ne justifie pas à elle seule une crate knowledge-store-api.

Indisponibilité PostgreSQL

Les erreurs de connexion, acquisition de pool, migration ou requête sont récupérables et typées à la frontière store.

Il n'existe pas de mode où une écriture est annoncée persistée alors que PostgreSQL ne l'est pas. Une future façade publique pourra continuer à servir un contenu Git déjà matérialisé seulement si son cas d'usage n'exige pas le store ; cette politique appartient à la composition de la façade, pas à un fallback interne de la crate de stockage.

Impact sur les trois applications

0.0.4 ne crée pas trois implémentations ou trois schémas par façade. knowledge-store-postgres-lib est le propriétaire partagé et la base logique est commune.

Les launchers ne seront modifiés que lorsqu'un cas d'usage runtime exige réellement la connexion. La fondation peut donc être testée indépendamment avant d'ajouter une dépendance de démarrage PostgreSQL à / et /healthz.

DEFER conservés

Restent explicitement hors scope de 0.0.4 :

  • formats finaux et parsing PGR/HOWTO/snippet ;
  • projections de contenu finales et révision indexée détaillée ;
  • recherche avancée ;
  • Gitea/forge et webhooks forge-only ;
  • scheduler/jobs ;
  • auth, sessions et rôles/capabilities ;
  • propositions/revues/publication produit ;
  • templates publics/admin et routes finales ;
  • quatrième application admin ;
  • partage multi-processus de la racine Git ;
  • Git LFS/submodules et rétention avancée.

Horizon

L'étude ne révèle aucune dépendance fausse dans la revue 0.0.3-beta.1.

L'horizon reste donc :

0.0.5  modèles de contenu et projections
0.0.6  templates publics
0.0.7  templates d'administration
0.0.8  lecture publique Actix Web / Maud
0.0.9  administration Actix Web / Maud et autorisation
0.0.10 gestion, proposition, revue et publication

Conclusion

0.0.4 peut progresser sans REPLAN : l'owner PostgreSQL est démontré, tokio-postgres, deadpool-postgres et refinery couvrent respectivement le driver, le pool et les migrations nécessaires, le premier schéma est borné et reconstructible par rapport à Git, et une stratégie de test PostgreSQL réelle est définie sans imposer un outil de provisioning unique.

alpha.1 a fermé le cadrage en PASS. alpha.2 matérialise maintenant knowledge-store-postgres-lib, le trio tokio-postgres / deadpool-postgres / refinery, une configuration/pool sans fuite de secret, la migration initiale des sources et un test PostgreSQL réel isolé par schéma. Les opérations de persistance source/state restent réservées à alpha.3.