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

19 KiB

title, description
title description
Schema de base de donnees 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.