Files
decision/docs/content/dev/4.database-schema.md
Yvv 2bdc731639 Sprint 2 : moteur de documents + sanctuaire
Backend:
- CRUD complet documents/items/versions (update, delete, accept, reject, reorder)
- Service IPFS (upload/retrieve/pin via kubo HTTP API)
- Service sanctuaire : pipeline SHA-256 + IPFS + on-chain (system.remark)
- Verification integrite des entrees sanctuaire
- Recherche par reference (document -> entrees sanctuaire)
- Serialisation deterministe des documents pour archivage
- 14 tests unitaires supplementaires (document service)

Frontend:
- 9 composants : StatusBadge, MarkdownRenderer, DiffView, ItemCard,
  ItemVersionDiff, DocumentList, SanctuaryEntry, IPFSLink, ChainAnchor
- Page detail item avec historique des versions et diff
- Page detail sanctuaire avec verification integrite
- Modal de creation de document + proposition de version
- Archivage document vers sanctuaire depuis la page detail

Documentation:
- API reference mise a jour (9 nouveaux endpoints)
- Guides utilisateur documents et sanctuaire enrichis

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:08:48 +01:00

321 lines
19 KiB
Markdown

---
title: Schema de base de donnees
description: Tables et relations de la base de donnees PostgreSQL
---
# Schema de base de donnees
Glibredecision utilise PostgreSQL 16 avec SQLAlchemy 2.0 en mode asynchrone (asyncpg). Toutes les cles primaires sont des UUID v4.
## Tables
### `duniter_identities`
Identites Duniter V2 connues de la plateforme.
| Colonne | Type | Description |
| -------------- | ------------ | ---------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| address | VARCHAR(64) | Adresse SS58 Duniter (unique, indexee) |
| display_name | VARCHAR(128) | Nom d'affichage |
| wot_status | VARCHAR(32) | Statut WoT : member, pending, revoked, unknown |
| is_smith | BOOLEAN | Membre Smith (forgeron) |
| is_techcomm | BOOLEAN | Membre du Comite Technique |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `sessions`
Sessions d'authentification (tokens).
| Colonne | Type | Description |
| ------------ | ------------ | ---------------------------------- |
| id | UUID (PK) | Identifiant unique |
| token_hash | VARCHAR(128) | Hash du token (unique, indexe) |
| identity_id | UUID (FK) | -> duniter_identities.id |
| created_at | TIMESTAMPTZ | Date de creation |
| expires_at | TIMESTAMPTZ | Date d'expiration |
### `documents`
Documents de reference modulaires. Le cycle de vie d'un document suit les statuts `draft` -> `active` -> `archived`. Lors de l'archivage (Sprint 2), les champs `ipfs_cid` et `chain_anchor` sont renseignes automatiquement par le service sanctuaire.
| Colonne | Type | Description |
| ------------ | ------------ | ----------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| slug | VARCHAR(128) | Identifiant lisible (unique, indexe) |
| title | VARCHAR(256) | Titre du document |
| doc_type | VARCHAR(64) | Type : licence, engagement, reglement, constitution |
| version | VARCHAR(32) | Version semantique (defaut "0.1.0") |
| status | VARCHAR(32) | Statut : draft, active, archived |
| description | TEXT | Description du document |
| ipfs_cid | VARCHAR(128) | CID IPFS de la derniere version archivee (renseigne lors de l'archivage) |
| chain_anchor | VARCHAR(128) | Hash de transaction on-chain (renseigne lors de l'archivage) |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `document_items`
Items individuels composant un document (clauses, regles, verifications, etc.). Chaque item peut etre modifie, supprime ou reordonne individuellement (Sprint 2). Le champ `current_text` est mis a jour automatiquement lorsqu'une version est acceptee.
| Colonne | Type | Description |
| ------------------- | ------------ | ------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| document_id | UUID (FK) | -> documents.id (cascade delete) |
| position | VARCHAR(16) | Numero de position ("1", "1.1", "3.2") |
| item_type | VARCHAR(32) | Type : clause, rule, verification, preamble, section |
| title | VARCHAR(256) | Titre de l'item |
| current_text | TEXT | Texte courant de l'item (mis a jour lors de l'acceptation d'une version) |
| voting_protocol_id | UUID (FK) | -> voting_protocols.id (protocole specifique) |
| sort_order | INTEGER | Ordre de tri (modifiable via endpoint reorder) |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `item_versions`
Historique des versions proposees pour chaque item. Lors de l'acceptation d'une version (Sprint 2), le `current_text` de l'item parent est remplace par le `proposed_text` de la version, et toutes les autres versions en attente (`proposed`, `voting`) sont automatiquement rejetees.
| Colonne | Type | Description |
| -------------- | ------------ | ------------------------------------------------------ |
| id | UUID (PK) | Identifiant unique |
| item_id | UUID (FK) | -> document_items.id (cascade delete) |
| proposed_text | TEXT | Texte propose |
| diff_text | TEXT | Diff unifie entre texte courant et propose (genere automatiquement) |
| rationale | TEXT | Justification de la modification |
| status | VARCHAR(32) | Statut : proposed, voting, accepted, rejected |
| decision_id | UUID (FK) | -> decisions.id (decision associee) |
| proposed_by_id | UUID (FK) | -> duniter_identities.id (auteur de la proposition) |
| created_at | TIMESTAMPTZ | Date de creation |
### `decisions`
Processus decisionnels multi-etapes.
| Colonne | Type | Description |
| ------------------- | ------------ | -------------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| title | VARCHAR(256) | Titre de la decision |
| description | TEXT | Description |
| context | TEXT | Contexte additionnel |
| decision_type | VARCHAR(64) | Type : runtime_upgrade, document_change, mandate_vote, custom |
| status | VARCHAR(32) | Statut : draft, qualification, review, voting, executed, closed |
| voting_protocol_id | UUID (FK) | -> voting_protocols.id |
| created_by_id | UUID (FK) | -> duniter_identities.id |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `decision_steps`
Etapes d'un processus decisionnel.
| Colonne | Type | Description |
| ---------------- | ------------ | -------------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| decision_id | UUID (FK) | -> decisions.id |
| step_order | INTEGER | Ordre de l'etape |
| step_type | VARCHAR(32) | Type : qualification, review, vote, execution, reporting |
| title | VARCHAR(256) | Titre de l'etape |
| description | TEXT | Description |
| status | VARCHAR(32) | Statut : pending, active, completed, skipped |
| vote_session_id | UUID (FK) | -> vote_sessions.id (session de vote associee) |
| outcome | TEXT | Resultat de l'etape |
| created_at | TIMESTAMPTZ | Date de creation |
### `vote_sessions`
Sessions de vote avec snapshot des tailles WoT et decompte en temps reel.
| Colonne | Type | Description |
| ------------------- | ------------ | ---------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| decision_id | UUID (FK) | -> decisions.id |
| item_version_id | UUID (FK) | -> item_versions.id |
| voting_protocol_id | UUID (FK) | -> voting_protocols.id |
| wot_size | INTEGER | Taille WoT au debut de la session |
| smith_size | INTEGER | Taille Smith au debut de la session |
| techcomm_size | INTEGER | Taille TechComm au debut de la session |
| starts_at | TIMESTAMPTZ | Date de debut |
| ends_at | TIMESTAMPTZ | Date de fin |
| status | VARCHAR(32) | Statut : open, closed, tallied |
| votes_for | INTEGER | Nombre de votes pour |
| votes_against | INTEGER | Nombre de votes contre |
| votes_total | INTEGER | Nombre total de votes |
| smith_votes_for | INTEGER | Votes pour des membres Smith |
| techcomm_votes_for | INTEGER | Votes pour des membres TechComm |
| threshold_required | FLOAT | Seuil calcule requis |
| result | VARCHAR(32) | Resultat : adopted, rejected, null |
| chain_recorded | BOOLEAN | Enregistre sur la blockchain |
| chain_tx_hash | VARCHAR(128) | Hash de la transaction on-chain |
| created_at | TIMESTAMPTZ | Date de creation |
### `votes`
Votes individuels avec preuve cryptographique.
| Colonne | Type | Description |
| ---------------- | ------------ | -------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| session_id | UUID (FK) | -> vote_sessions.id |
| voter_id | UUID (FK) | -> duniter_identities.id |
| vote_value | VARCHAR(32) | Valeur : for, against, ou niveau nuance |
| nuanced_level | INTEGER | Niveau nuance (0-5) pour les votes nuances |
| comment | TEXT | Commentaire optionnel |
| signature | TEXT | Signature Ed25519 du payload |
| signed_payload | TEXT | Payload signe (pour verification) |
| voter_wot_status | VARCHAR(32) | Statut WoT du votant au moment du vote |
| voter_is_smith | BOOLEAN | Le votant est-il forgeron |
| voter_is_techcomm| BOOLEAN | Le votant est-il membre TechComm |
| is_active | BOOLEAN | Vote actif (false si remplace) |
| created_at | TIMESTAMPTZ | Date de creation |
### `mandates`
Mandats assignes a des membres.
| Colonne | Type | Description |
| ------------- | ------------ | ------------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| title | VARCHAR(256) | Titre du mandat |
| description | TEXT | Description |
| mandate_type | VARCHAR(64) | Type : techcomm, smith, custom |
| status | VARCHAR(32) | Statut : draft, candidacy, voting, active, reporting, completed, revoked |
| mandatee_id | UUID (FK) | -> duniter_identities.id (titulaire du mandat) |
| decision_id | UUID (FK) | -> decisions.id (decision associee) |
| starts_at | TIMESTAMPTZ | Date de debut |
| ends_at | TIMESTAMPTZ | Date de fin |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `mandate_steps`
Etapes du cycle de vie d'un mandat.
| Colonne | Type | Description |
| ---------------- | ------------ | ------------------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| mandate_id | UUID (FK) | -> mandates.id |
| step_order | INTEGER | Ordre de l'etape |
| step_type | VARCHAR(32) | Type : formulation, candidacy, vote, assignment, reporting, completion, revocation |
| title | VARCHAR(256) | Titre de l'etape |
| description | TEXT | Description |
| status | VARCHAR(32) | Statut : pending, active, completed, skipped |
| vote_session_id | UUID (FK) | -> vote_sessions.id (session de vote associee) |
| outcome | TEXT | Resultat de l'etape |
| created_at | TIMESTAMPTZ | Date de creation |
### `voting_protocols`
Protocoles de vote reutilisables.
| Colonne | Type | Description |
| ------------------ | ------------ | ----------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| name | VARCHAR(128) | Nom du protocole |
| description | TEXT | Description |
| vote_type | VARCHAR(32) | Type de vote : binary, nuanced |
| formula_config_id | UUID (FK) | -> formula_configs.id |
| mode_params | VARCHAR(64) | Parametres compacts ("D30M50B.1G.2T.1") |
| is_meta_governed | BOOLEAN | Le protocole est-il sous meta-gouvernance |
| created_at | TIMESTAMPTZ | Date de creation |
### `formula_configs`
Configurations de formules de seuil WoT.
| Colonne | Type | Description |
| ------------------------- | ------------ | ----------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| name | VARCHAR(128) | Nom de la configuration |
| description | TEXT | Description |
| duration_days | INTEGER | Duree du vote en jours |
| majority_pct | INTEGER | Pourcentage de majorite (0-100) |
| base_exponent | FLOAT | Exposant de base B |
| gradient_exponent | FLOAT | Exposant de gradient G |
| constant_base | FLOAT | Base constante C |
| smith_exponent | FLOAT | Exposant Smith S (null si non requis) |
| techcomm_exponent | FLOAT | Exposant TechComm T (null si non requis) |
| nuanced_min_participants | INTEGER | Participants minimum (vote nuance) |
| nuanced_threshold_pct | INTEGER | Seuil positif % (vote nuance) |
| created_at | TIMESTAMPTZ | Date de creation |
### `sanctuary_entries`
Entrees du sanctuaire (archivage immuable). Le champ `reference_id` permet de retrouver toutes les entrees liees a un document, une decision ou une session de vote via l'endpoint `/by-reference/{reference_id}` (Sprint 2). L'endpoint `/verify` recalcule le hash et verifie la coherence IPFS/on-chain.
| Colonne | Type | Description |
| -------------- | ------------ | ------------------------------------------ |
| id | UUID (PK) | Identifiant unique |
| entry_type | VARCHAR(64) | Type : document, decision, vote_result |
| reference_id | UUID | UUID de l'entite source (indexe pour recherche par reference) |
| title | VARCHAR(256) | Titre |
| content_hash | VARCHAR(128) | Hash SHA-256 du contenu |
| ipfs_cid | VARCHAR(128) | CID IPFS (renseigne lors de l'upload) |
| chain_tx_hash | VARCHAR(128) | Hash de la transaction on-chain |
| chain_block | INTEGER | Numero de bloc de la transaction |
| metadata_json | TEXT | Metadonnees JSON supplementaires |
| created_at | TIMESTAMPTZ | Date de creation |
### `blockchain_cache`
Cache des donnees blockchain pour eviter les appels RPC repetes.
| Colonne | Type | Description |
| ------------ | ------------ | -------------------------------- |
| id | UUID (PK) | Identifiant unique |
| cache_key | VARCHAR(256) | Cle de cache (unique, indexee) |
| cache_value | JSONB | Valeur en cache |
| fetched_at | TIMESTAMPTZ | Date de recuperation |
| expires_at | TIMESTAMPTZ | Date d'expiration du cache |
## Diagramme des relations
```
duniter_identities
|-- 1:N --> sessions
|-- 1:N --> votes (voter_id)
|-- 1:N --> item_versions (proposed_by_id)
|-- 1:N --> decisions (created_by_id)
|-- 1:N --> mandates (mandatee_id)
documents
|-- 1:N --> document_items
|-- 1:N ..> sanctuary_entries (via reference_id, non FK)
document_items
|-- 1:N --> item_versions (cascade delete)
|-- N:1 --> voting_protocols
item_versions
|-- N:1 --> decisions
decisions
|-- 1:N --> decision_steps
|-- 1:N ..> sanctuary_entries (via reference_id, non FK)
decision_steps
|-- N:1 --> vote_sessions
vote_sessions
|-- 1:N --> votes
|-- N:1 --> voting_protocols
|-- 1:N ..> sanctuary_entries (via reference_id, non FK)
mandates
|-- 1:N --> mandate_steps
|-- N:1 --> decisions
mandate_steps
|-- N:1 --> vote_sessions
voting_protocols
|-- N:1 --> formula_configs
formula_configs
|-- 1:N --> voting_protocols
sanctuary_entries
|-- reference_id ..> documents | decisions | vote_sessions (lien logique)
```
> **Note Sprint 2** : Les liens `..>` (pointilles) representent des references logiques via le champ `reference_id` de `sanctuary_entries`. Ce ne sont pas des cles etrangeres PostgreSQL car `reference_id` peut pointer vers differentes tables selon le `entry_type`.