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>
This commit is contained in:
Yvv
2026-02-28 13:08:48 +01:00
parent 25437f24e3
commit 2bdc731639
26 changed files with 3452 additions and 397 deletions

View File

@@ -27,7 +27,14 @@ Tous les endpoints sont prefixes par `/api/v1`. L'API est auto-documentee via Op
| 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`)
@@ -73,11 +80,13 @@ Tous les endpoints sont prefixes par `/api/v1`. L'API est auto-documentee via Op
## 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 |
| 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`)
@@ -91,6 +100,127 @@ Tous les endpoints sont prefixes par `/api/v1`. L'API est auto-documentee via Op
| ------- | -------------- | -------------------------- |
| 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`.
## Pagination
Les endpoints de liste acceptent les parametres `skip` (offset, defaut 0) et `limit` (max 200, defaut 50).