Backend: - Sessions de vote : list, close, tally, threshold details, auto-expiration - Protocoles : update, simulate, meta-gouvernance, formulas CRUD - Service vote enrichi : close_session, get_threshold_details, nuanced breakdown - Schemas : ThresholdDetailOut, VoteResultOut, FormulaSimulationRequest/Result - WebSocket broadcast sur chaque vote + fermeture session - 25 nouveaux tests (threshold details, close, nuanced, simulation) Frontend: - 5 composants vote : VoteBinary, VoteNuanced, ThresholdGauge, FormulaDisplay, VoteHistory - 3 composants protocoles : ProtocolPicker, FormulaEditor, ModeParamsDisplay - Simulateur de formules interactif (page /protocols/formulas) - Page detail protocole (/protocols/[id]) - Composable useWebSocket (live updates) - Composable useVoteFormula (calcul client-side reactif) - Integration KaTeX pour rendu LaTeX des formules Documentation: - API reference : 8 nouveaux endpoints documentes - Formules : tables d'inertie, parametres detailles, simulation API - Guide vote : vote binaire/nuance, jauge, historique, simulateur, meta-gouvernance 55 tests passes (+ 1 skipped), 126 fichiers total. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
464 lines
18 KiB
Markdown
464 lines
18 KiB
Markdown
---
|
|
title: Reference API
|
|
description: Liste des endpoints de l'API Glibredecision
|
|
---
|
|
|
|
# Reference API
|
|
|
|
Tous les endpoints sont prefixes par `/api/v1`. L'API est auto-documentee via OpenAPI/Swagger a l'adresse `/docs` en mode debug.
|
|
|
|
## Authentification (`/api/v1/auth`)
|
|
|
|
| Methode | Endpoint | Description | Auth |
|
|
| ------- | ------------- | ----------------------------------------------------- | ---- |
|
|
| POST | `/challenge` | Generer un challenge Ed25519 pour une adresse Duniter | Non |
|
|
| POST | `/verify` | Verifier la signature du challenge et obtenir un token | Non |
|
|
| GET | `/me` | Retourner l'identite authentifiee courante | Oui |
|
|
| POST | `/logout` | Invalider la session courante | Oui |
|
|
|
|
## Documents (`/api/v1/documents`)
|
|
|
|
| Methode | Endpoint | Description | Auth |
|
|
| ------- | -------------------------------------- | ---------------------------------------- | ---- |
|
|
| GET | `/` | Lister les documents (filtres: doc_type, status) | Non |
|
|
| POST | `/` | Creer un nouveau document | Oui |
|
|
| GET | `/{slug}` | Obtenir un document par son slug | Non |
|
|
| PUT | `/{slug}` | Mettre a jour un document | Oui |
|
|
| POST | `/{slug}/items` | Ajouter un item au document | Oui |
|
|
| GET | `/{slug}/items` | Lister les items d'un document | Non |
|
|
| GET | `/{slug}/items/{item_id}` | Obtenir un item avec son historique | Non |
|
|
| PUT | `/{slug}/items/{item_id}` | Mettre a jour un item (titre, texte, position, type) | Oui |
|
|
| DELETE | `/{slug}/items/{item_id}` | Supprimer un item du document | Oui |
|
|
| POST | `/{slug}/items/{item_id}/versions` | Proposer une nouvelle version d'un item | Oui |
|
|
| GET | `/{slug}/items/{item_id}/versions` | Lister les versions d'un item | Non |
|
|
| PUT | `/{slug}/items/{item_id}/versions/{version_id}/accept` | Accepter une version proposee (applique le texte a l'item) | Oui |
|
|
| PUT | `/{slug}/items/{item_id}/versions/{version_id}/reject` | Rejeter une version proposee | Oui |
|
|
| PUT | `/{slug}/items/reorder` | Reordonner les items d'un document | Oui |
|
|
| POST | `/{slug}/archive` | Archiver le document dans le sanctuaire (hash SHA-256 + IPFS + on-chain) | Oui |
|
|
|
|
## Decisions (`/api/v1/decisions`)
|
|
|
|
| Methode | Endpoint | Description | Auth |
|
|
| ------- | ---------------- | ------------------------------------------------ | ---- |
|
|
| GET | `/` | Lister les decisions (filtres: decision_type, status) | Non |
|
|
| POST | `/` | Creer une nouvelle decision | Oui |
|
|
| GET | `/{id}` | Obtenir une decision avec ses etapes | Non |
|
|
| PUT | `/{id}` | Mettre a jour une decision | Oui |
|
|
| POST | `/{id}/steps` | Ajouter une etape a une decision | Oui |
|
|
|
|
## Votes (`/api/v1/votes`)
|
|
|
|
| Methode | Endpoint | Description | Auth |
|
|
| ------- | ------------------------------- | -------------------------------------------- | ---- |
|
|
| POST | `/sessions` | Creer une session de vote | Oui |
|
|
| GET | `/sessions` | Lister les sessions de vote (filtres: status, protocol_id, decision_id) | Non |
|
|
| GET | `/sessions/{id}` | Obtenir une session de vote | Non |
|
|
| POST | `/sessions/{id}/vote` | Soumettre un vote (signe) | Oui |
|
|
| GET | `/sessions/{id}/votes` | Lister les votes d'une session | Non |
|
|
| GET | `/sessions/{id}/result` | Calculer et retourner le resultat courant | Non |
|
|
| POST | `/sessions/{id}/close` | Cloturer la session et calculer le resultat final | Oui |
|
|
| GET | `/sessions/{id}/threshold` | Obtenir le detail du calcul de seuil (formule, parametres, valeurs intermediaires) | Non |
|
|
| POST | `/sessions/{id}/tally` | Forcer un recomptage des votes et recalcul du seuil | Oui |
|
|
|
|
## Mandats (`/api/v1/mandates`)
|
|
|
|
| Methode | Endpoint | Description | Auth |
|
|
| ------- | ----------------- | ---------------------------------------------- | ---- |
|
|
| GET | `/` | Lister les mandats (filtres: mandate_type, status) | Non |
|
|
| POST | `/` | Creer un nouveau mandat | Oui |
|
|
| GET | `/{id}` | Obtenir un mandat avec ses etapes | Non |
|
|
| PUT | `/{id}` | Mettre a jour un mandat | Oui |
|
|
| DELETE | `/{id}` | Supprimer un mandat (brouillon uniquement) | Oui |
|
|
| POST | `/{id}/steps` | Ajouter une etape a un mandat | Oui |
|
|
| GET | `/{id}/steps` | Lister les etapes d'un mandat | Non |
|
|
|
|
## Protocoles (`/api/v1/protocols`)
|
|
|
|
| Methode | Endpoint | Description | Auth |
|
|
| ------- | ------------------- | -------------------------------------------------- | ---- |
|
|
| GET | `/` | Lister les protocoles de vote | Non |
|
|
| POST | `/` | Creer un protocole de vote | Oui |
|
|
| GET | `/{id}` | Obtenir un protocole avec sa configuration formule | Non |
|
|
| PUT | `/{id}` | Mettre a jour un protocole (meta-gouvernance) | Oui |
|
|
| GET | `/formulas` | Lister les configurations de formules | Non |
|
|
| POST | `/formulas` | Creer une configuration de formule | Oui |
|
|
| GET | `/formulas/{id}` | Obtenir une configuration de formule par son ID | Non |
|
|
| PUT | `/formulas/{id}` | Mettre a jour une configuration de formule (meta-gouvernance) | Oui |
|
|
| POST | `/simulate` | Simuler le calcul d'une formule avec des parametres arbitraires | Non |
|
|
|
|
## Sanctuaire (`/api/v1/sanctuary`)
|
|
|
|
| Methode | Endpoint | Description | Auth |
|
|
| ------- | --------------------------------- | ---------------------------------------------------------- | ---- |
|
|
| GET | `/` | Lister les entrees du sanctuaire (filtre: entry_type) | Non |
|
|
| GET | `/{id}` | Obtenir une entree du sanctuaire | Non |
|
|
| POST | `/` | Creer une entree (hash SHA-256, CID IPFS, TX on-chain) | Oui |
|
|
| GET | `/{id}/verify` | Verifier l'integrite d'une entree (recalcul SHA-256, verification IPFS et on-chain) | Non |
|
|
| GET | `/by-reference/{reference_id}` | Obtenir les entrees liees a une entite source par son UUID | Non |
|
|
|
|
## WebSocket (`/api/v1/ws`)
|
|
|
|
| Endpoint | Description |
|
|
| --------- | -------------------------------------------------------- |
|
|
| `/ws` | Connexion WebSocket pour notifications temps reel (votes, decisions) |
|
|
|
|
## Sante
|
|
|
|
| Methode | Endpoint | Description |
|
|
| ------- | -------------- | -------------------------- |
|
|
| GET | `/api/health` | Verification de sante (hors versionning) |
|
|
|
|
## Details des endpoints Sprint 2
|
|
|
|
### `PUT /api/v1/documents/{slug}/items/{item_id}` -- Mettre a jour un item
|
|
|
|
Met a jour les champs d'un item existant (titre, texte courant, position, type). Seuls les champs fournis sont mis a jour (mise a jour partielle).
|
|
|
|
**Corps de la requete** (tous les champs sont optionnels) :
|
|
|
|
```json
|
|
{
|
|
"title": "Nouveau titre",
|
|
"current_text": "Texte mis a jour...",
|
|
"position": "2.1",
|
|
"item_type": "rule"
|
|
}
|
|
```
|
|
|
|
**Reponse** : `200 OK` avec l'item mis a jour (`DocumentItemOut`).
|
|
|
|
---
|
|
|
|
### `DELETE /api/v1/documents/{slug}/items/{item_id}` -- Supprimer un item
|
|
|
|
Supprime un item d'un document. La suppression est en cascade : toutes les versions associees sont egalement supprimees.
|
|
|
|
**Reponse** : `204 No Content`.
|
|
|
|
---
|
|
|
|
### `GET /api/v1/documents/{slug}/items/{item_id}/versions` -- Lister les versions d'un item
|
|
|
|
Retourne l'historique complet des versions proposees pour un item, ordonne par date de creation decroissante.
|
|
|
|
**Parametres de requete** : `skip`, `limit` (pagination standard).
|
|
|
|
**Reponse** : `200 OK` avec une liste de `ItemVersionOut`.
|
|
|
|
---
|
|
|
|
### `PUT /api/v1/documents/{slug}/items/{item_id}/versions/{version_id}/accept` -- Accepter une version
|
|
|
|
Accepte une version proposee. Le texte propose remplace le texte courant de l'item. Toutes les autres versions en statut `proposed` ou `voting` pour cet item sont automatiquement rejetees.
|
|
|
|
**Reponse** : `200 OK` avec la version mise a jour (`ItemVersionOut`, statut `accepted`).
|
|
|
|
---
|
|
|
|
### `PUT /api/v1/documents/{slug}/items/{item_id}/versions/{version_id}/reject` -- Rejeter une version
|
|
|
|
Rejette une version proposee. Le texte courant de l'item reste inchange.
|
|
|
|
**Reponse** : `200 OK` avec la version mise a jour (`ItemVersionOut`, statut `rejected`).
|
|
|
|
---
|
|
|
|
### `PUT /api/v1/documents/{slug}/items/reorder` -- Reordonner les items
|
|
|
|
Modifie l'ordre d'affichage des items dans un document en mettant a jour le champ `sort_order` de chaque item.
|
|
|
|
**Corps de la requete** :
|
|
|
|
```json
|
|
{
|
|
"items": [
|
|
{ "item_id": "uuid-1", "sort_order": 0 },
|
|
{ "item_id": "uuid-2", "sort_order": 1 },
|
|
{ "item_id": "uuid-3", "sort_order": 2 }
|
|
]
|
|
}
|
|
```
|
|
|
|
**Reponse** : `200 OK` avec la liste des items reordonnes.
|
|
|
|
---
|
|
|
|
### `POST /api/v1/documents/{slug}/archive` -- Archiver un document
|
|
|
|
Archive le document complet dans le sanctuaire. Le processus :
|
|
|
|
1. Le contenu integral du document (metadonnees + items) est serialise.
|
|
2. Un hash SHA-256 est calcule sur le contenu.
|
|
3. Le contenu est envoye sur IPFS (CID retourne).
|
|
4. Le hash est ancre on-chain via `system.remark` sur Duniter V2.
|
|
5. Une entree `sanctuary_entries` est creee avec les references.
|
|
6. Le statut du document passe a `archived` et les champs `ipfs_cid` et `chain_anchor` sont mis a jour.
|
|
|
|
**Reponse** : `200 OK` avec le document mis a jour incluant `ipfs_cid` et `chain_anchor`.
|
|
|
|
---
|
|
|
|
### `GET /api/v1/sanctuary/{id}/verify` -- Verifier l'integrite d'une entree
|
|
|
|
Verifie l'integrite d'une entree du sanctuaire en effectuant trois controles :
|
|
|
|
1. **Hash SHA-256** : recalcul du hash a partir du contenu source et comparaison avec `content_hash`.
|
|
2. **IPFS** : verification que le CID IPFS pointe vers un contenu valide (si disponible).
|
|
3. **On-chain** : verification que le hash est present dans le `system.remark` du bloc reference (si disponible).
|
|
|
|
**Reponse** :
|
|
|
|
```json
|
|
{
|
|
"entry_id": "uuid",
|
|
"hash_valid": true,
|
|
"ipfs_valid": true,
|
|
"chain_valid": true,
|
|
"verified_at": "2026-02-28T12:00:00Z",
|
|
"details": "Tous les controles sont valides."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### `GET /api/v1/sanctuary/by-reference/{reference_id}` -- Entrees par reference
|
|
|
|
Retourne toutes les entrees du sanctuaire liees a une entite source (document, decision ou session de vote) identifiee par son UUID.
|
|
|
|
**Parametres de requete** : `skip`, `limit` (pagination standard).
|
|
|
|
**Reponse** : `200 OK` avec une liste de `SanctuaryEntryOut`.
|
|
|
|
## Details des endpoints Sprint 3
|
|
|
|
### `GET /api/v1/votes/sessions` -- Lister les sessions de vote
|
|
|
|
Retourne la liste des sessions de vote avec pagination et filtres optionnels.
|
|
|
|
**Parametres de requete** :
|
|
|
|
| Parametre | Type | Description |
|
|
| ------------- | ------ | ---------------------------------------------- |
|
|
| `status` | string | Filtrer par statut (`open`, `closed`, `draft`) |
|
|
| `protocol_id` | uuid | Filtrer par protocole de vote |
|
|
| `decision_id` | uuid | Filtrer par decision associee |
|
|
| `skip` | int | Offset de pagination (defaut 0) |
|
|
| `limit` | int | Nombre max de resultats (defaut 50, max 200) |
|
|
|
|
**Reponse** : `200 OK` avec une liste de `VoteSessionOut`.
|
|
|
|
---
|
|
|
|
### `POST /api/v1/votes/sessions/{id}/close` -- Cloturer une session
|
|
|
|
Cloture une session de vote ouverte et calcule le resultat final. Le calcul inclut la formule WoT, les criteres Smith et TechComm le cas echeant. La session passe au statut `closed` et le resultat est fige.
|
|
|
|
**Preconditions** :
|
|
- La session doit etre au statut `open`.
|
|
- L'utilisateur doit etre le createur de la session ou un membre du Comite Technique.
|
|
|
|
**Reponse** :
|
|
|
|
```json
|
|
{
|
|
"session_id": "uuid",
|
|
"status": "closed",
|
|
"closed_at": "2026-02-28T12:00:00Z",
|
|
"result": {
|
|
"votes_for": 97,
|
|
"votes_against": 23,
|
|
"total_votes": 120,
|
|
"wot_size": 7224,
|
|
"threshold": 94,
|
|
"adopted": true,
|
|
"smith_threshold": 2,
|
|
"smith_votes_for": 5,
|
|
"smith_met": true,
|
|
"techcomm_threshold": null,
|
|
"techcomm_votes_for": null,
|
|
"techcomm_met": null
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### `GET /api/v1/votes/sessions/{id}/threshold` -- Detail du calcul de seuil
|
|
|
|
Retourne le detail complet du calcul de seuil pour une session de vote, incluant les valeurs intermediaires de la formule. Utile pour la transparence et le debug.
|
|
|
|
**Reponse** :
|
|
|
|
```json
|
|
{
|
|
"session_id": "uuid",
|
|
"formula_config_id": "uuid",
|
|
"mode_params": "D30M50B.1G.2",
|
|
"parameters": {
|
|
"constant_base": 0.0,
|
|
"base_exponent": 0.1,
|
|
"majority_pct": 50,
|
|
"gradient_exponent": 0.2,
|
|
"smith_exponent": null,
|
|
"techcomm_exponent": null
|
|
},
|
|
"inputs": {
|
|
"wot_size": 7224,
|
|
"total_votes": 120,
|
|
"smith_wot_size": 20,
|
|
"techcomm_size": 5
|
|
},
|
|
"computation": {
|
|
"base_term": 7.943e-08,
|
|
"participation_ratio": 0.0166,
|
|
"participation_ratio_powered": 0.4217,
|
|
"inertia_factor": 0.7892,
|
|
"effective_threshold": 94.70,
|
|
"threshold_ceiled": 95,
|
|
"threshold_final": 94
|
|
},
|
|
"criteria": {
|
|
"smith_threshold": null,
|
|
"techcomm_threshold": null
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### `POST /api/v1/votes/sessions/{id}/tally` -- Forcer un recomptage
|
|
|
|
Force le recalcul du decompte des votes et du seuil pour une session. Utile si des votes ont ete invalides manuellement ou si la taille WoT a ete corrigee.
|
|
|
|
**Preconditions** :
|
|
- L'utilisateur doit etre le createur de la session ou un membre du Comite Technique.
|
|
|
|
**Corps de la requete** (optionnel) :
|
|
|
|
```json
|
|
{
|
|
"wot_size_override": 7250,
|
|
"smith_wot_size_override": null,
|
|
"techcomm_size_override": null
|
|
}
|
|
```
|
|
|
|
Si aucun corps n'est fourni, les tailles sont reprises du snapshot initial.
|
|
|
|
**Reponse** : `200 OK` avec le meme format que le resultat de cloture.
|
|
|
|
---
|
|
|
|
### `PUT /api/v1/protocols/{id}` -- Mettre a jour un protocole
|
|
|
|
Met a jour un protocole de vote existant. Les modifications de protocoles actifs (utilises par des sessions ouvertes) sont soumises a **meta-gouvernance** : une session de vote doit d'abord valider la modification.
|
|
|
|
**Corps de la requete** (champs optionnels) :
|
|
|
|
```json
|
|
{
|
|
"name": "Nouveau nom du protocole",
|
|
"description": "Description mise a jour",
|
|
"vote_type": "nuanced",
|
|
"duration_days": 60,
|
|
"formula_config_id": "uuid-de-la-nouvelle-formule"
|
|
}
|
|
```
|
|
|
|
**Reponse** : `200 OK` avec le protocole mis a jour (`ProtocolOut`).
|
|
|
|
**Code 409** : Si le protocole est utilise par une session ouverte et qu'aucune validation meta-gouvernance n'est fournie.
|
|
|
|
---
|
|
|
|
### `GET /api/v1/protocols/formulas/{id}` -- Obtenir une formule
|
|
|
|
Retourne une configuration de formule par son identifiant, incluant tous les parametres et le `mode_params` encode.
|
|
|
|
**Reponse** : `200 OK` avec un `FormulaConfigOut`.
|
|
|
|
---
|
|
|
|
### `PUT /api/v1/protocols/formulas/{id}` -- Mettre a jour une formule
|
|
|
|
Met a jour une configuration de formule existante. Comme pour les protocoles, les formules actives sont protegees par la meta-gouvernance.
|
|
|
|
**Corps de la requete** (champs optionnels) :
|
|
|
|
```json
|
|
{
|
|
"name": "Configuration amendee",
|
|
"majority_pct": 66,
|
|
"base_exponent": 0.05,
|
|
"gradient_exponent": 0.3,
|
|
"constant_base": 0.0,
|
|
"smith_exponent": 0.1,
|
|
"techcomm_exponent": 0.1,
|
|
"ratio_multiplier": null,
|
|
"is_ratio_mode": false
|
|
}
|
|
```
|
|
|
|
Le champ `mode_params` est recalcule automatiquement a partir des valeurs fournies.
|
|
|
|
**Reponse** : `200 OK` avec la formule mise a jour (`FormulaConfigOut`).
|
|
|
|
**Code 409** : Si la formule est liee a un protocole actif sans validation meta-gouvernance.
|
|
|
|
---
|
|
|
|
### `POST /api/v1/protocols/simulate` -- Simuler une formule
|
|
|
|
Simule le calcul de seuil d'une formule avec des parametres arbitraires, sans creer ni modifier aucune donnee. Endpoint ouvert (pas d'authentification requise) pour permettre l'experimentation.
|
|
|
|
**Corps de la requete** :
|
|
|
|
```json
|
|
{
|
|
"wot_size": 7224,
|
|
"total_votes": 120,
|
|
"majority_pct": 50,
|
|
"base_exponent": 0.1,
|
|
"gradient_exponent": 0.2,
|
|
"constant_base": 0.0,
|
|
"smith_wot_size": 20,
|
|
"smith_exponent": 0.1,
|
|
"techcomm_size": 5,
|
|
"techcomm_exponent": 0.1,
|
|
"votes_for": 97
|
|
}
|
|
```
|
|
|
|
**Reponse** :
|
|
|
|
```json
|
|
{
|
|
"threshold": 94,
|
|
"inertia_factor": 0.7892,
|
|
"participation_ratio": 0.0166,
|
|
"base_term": 7.943e-08,
|
|
"smith_threshold": 2,
|
|
"techcomm_threshold": 2,
|
|
"adopted": true,
|
|
"details": {
|
|
"wot_threshold_met": true,
|
|
"smith_met": true,
|
|
"techcomm_met": true
|
|
}
|
|
}
|
|
```
|
|
|
|
## Pagination
|
|
|
|
Les endpoints de liste acceptent les parametres `skip` (offset, defaut 0) et `limit` (max 200, defaut 50).
|
|
|
|
## Authentification
|
|
|
|
Les endpoints marques "Oui" dans la colonne Auth requierent un header :
|
|
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
Le token est obtenu via le flux challenge-response (`/auth/challenge` puis `/auth/verify`).
|