0.0.4-alpha.1
This commit is contained in:
255
docs/studies/008-V0_0_4_POSTGRES_FOUNDATION_STUDY.md
Normal file
255
docs/studies/008-V0_0_4_POSTGRES_FOUNDATION_STUDY.md
Normal file
@@ -0,0 +1,255 @@
|
||||
<!-- file: docs/studies/008-V0_0_4_POSTGRES_FOUNDATION_STUDY.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# É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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
- SQLx `0.9.0` et ses features/MSRV : <https://docs.rs/crate/sqlx/0.9.0/source/Cargo.toml.orig> ;
|
||||
- `PgPool` SQLx : <https://docs.rs/sqlx/0.9.0/sqlx/postgres/type.PgPool.html> ;
|
||||
- migrations et `migrate!` SQLx : <https://docs.rs/sqlx/0.9.0/sqlx/migrate/index.html> et <https://docs.rs/sqlx/0.9.0/sqlx/macro.migrate.html> ;
|
||||
- `tokio-postgres` `0.7.18` : <https://docs.rs/tokio-postgres/0.7.18/tokio_postgres/> ;
|
||||
- `deadpool-postgres` `0.14.2` : <https://docs.rs/deadpool-postgres/0.14.2/deadpool_postgres/> ;
|
||||
- Diesel `2.3.13` : <https://docs.rs/crate/diesel/2.3.13> ;
|
||||
- `diesel-async` `0.9.2` : <https://docs.rs/crate/diesel-async/0.9.2> ;
|
||||
- SeaORM `2.0.4` : <https://docs.rs/crate/sea-orm/2.0.4> ;
|
||||
- Refinery `0.9.2` : <https://docs.rs/crate/refinery/0.9.2>.
|
||||
|
||||
## 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` doit néanmoins revalider les versions stables compatibles au moment exact de leur ajout au manifest, conformément à la politique locale de dépendances, sans downgrade silencieux.
|
||||
|
||||
La séparation est volontaire :
|
||||
|
||||
```text
|
||||
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.
|
||||
|
||||
Un backend TLS n'est pas figé par `alpha.1`. Si la cible de déploiement PostgreSQL exige TLS, la tranche qui matérialise la connexion doit 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 :
|
||||
|
||||
```text
|
||||
knowledge-store-postgres-lib
|
||||
```
|
||||
|
||||
Cette crate possédera :
|
||||
|
||||
- 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`
|
||||
|
||||
```text
|
||||
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`
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
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` ne crée encore aucune crate, dépendance ou migration. Après son `PASS` opérateur, `alpha.2` peut matérialiser `knowledge-store-postgres-lib`, le trio `tokio-postgres` / `deadpool-postgres` / `refinery` et la première migration.
|
||||
Reference in New Issue
Block a user