Accents FR, architecture modulaire, protocoles opérationnels

- Fix accents manquants dans 7 pages UI (décisions, boîte à outils, etc.)
- Titres accueil enrichis : Décisions structurantes, Documents de référence,
  Mandats et nominations, Protocoles et fonctionnement
- Retrait Embarquement Forgeron du seed (n'est pas une Decision)
- 2 protocoles opérationnels dans Protocoles : Embarquement Forgeron
  (lié à l'Acte d'engagement) + Soumission Runtime Upgrade (lié à la
  Décision Runtime Upgrade) avec timeline et liens croisés signalétiques
- Décision Runtime Upgrade : badge on-chain + lien protocole + contexte
- Document [slug] : lien protocole dans la section Qualification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-03-03 07:05:55 +01:00
parent c19c1aa55e
commit 8201e73d7c
8 changed files with 328 additions and 221 deletions

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
/**
* Protocoles & Fonctionnement — Boite a outils de vote.
* Protocoles & Fonctionnement — Boîte à outils de vote.
*
* Liste les protocoles de vote avec SectionLayout,
* sidebar n8n workflow + simulateur de formules.
@@ -30,14 +30,14 @@ onMounted(async () => {
const voteTypeLabel = (voteType: string) => {
switch (voteType) {
case 'binary': return 'Binaire'
case 'nuanced': return 'Nuance'
case 'nuanced': return 'Nuancé'
default: return voteType
}
}
const voteTypeOptions = [
{ label: 'Binaire (Pour/Contre)', value: 'binary' },
{ label: 'Nuance (6 niveaux)', value: 'nuanced' },
{ label: 'Nuancé (6 niveaux)', value: 'nuanced' },
]
const formulaOptions = computed(() => {
@@ -57,7 +57,7 @@ const statuses = computed(() => [
},
{
id: 'nuanced',
label: 'Nuance',
label: 'Nuancé',
count: protocols.protocols.filter(p => p.vote_type === 'nuanced').length,
cssClass: 'status-prepa',
},
@@ -117,24 +117,60 @@ interface WorkflowStep {
type: string
}
const operationalProtocols = [
interface LinkedRef {
label: string
icon: string
to: string
kind: 'document' | 'decision'
}
interface OperationalProtocol {
slug: string
name: string
description: string
category: string
icon: string
instancesLabel: string
linkedRefs: LinkedRef[]
steps: WorkflowStep[]
}
const operationalProtocols: OperationalProtocol[] = [
{
slug: 'embarquement-forgeron',
name: 'Embarquement Forgeron',
description: 'Processus complet d\'intégration d\'un nouveau forgeron dans le réseau Duniter.',
description: 'Processus complet d\'intégration d\'un nouveau forgeron dans le réseau Duniter. Parcours en 5 jalons de la candidature à la mise en ligne du nœud validateur.',
category: 'onboarding',
icon: 'i-lucide-hammer',
instancesLabel: '~10-50 / an',
linkedRefs: [
{ label: 'Acte d\'engagement forgeron', icon: 'i-lucide-book-open', to: '/documents/engagement-forgeron', kind: 'document' },
],
steps: [
{ label: 'Invitation on-chain', actor: 'Smith existant', icon: 'i-lucide-send', type: 'on_chain' },
{ label: 'Acceptation', actor: 'Candidat', icon: 'i-lucide-check', type: 'on_chain' },
{ label: 'Session keys', actor: 'Candidat', icon: 'i-lucide-key', type: 'on_chain' },
{ label: 'Checklist aspirant', actor: 'Candidat', icon: 'i-lucide-clipboard-check', type: 'checklist' },
{ label: 'Certification 1', actor: 'Certificateur', icon: 'i-lucide-stamp', type: 'certification' },
{ label: 'Certification 2', actor: 'Certificateur', icon: 'i-lucide-stamp', type: 'certification' },
{ label: 'Certification 3', actor: 'Certificateur', icon: 'i-lucide-stamp', type: 'certification' },
{ label: 'Candidature', actor: 'Aspirant forgeron', icon: 'i-lucide-user-plus', type: 'checklist' },
{ label: 'Nœud miroir', actor: 'Candidat', icon: 'i-lucide-server', type: 'on_chain' },
{ label: 'Évaluation technique', actor: 'Certificateur', icon: 'i-lucide-clipboard-check', type: 'checklist' },
{ label: 'Certification Smith (×3)', actor: 'Certificateurs', icon: 'i-lucide-stamp', type: 'certification' },
{ label: 'Go online', actor: 'Candidat', icon: 'i-lucide-wifi', type: 'on_chain' },
] as WorkflowStep[],
],
},
{
slug: 'soumission-runtime-upgrade',
name: 'Soumission Runtime Upgrade',
description: 'Protocole de soumission d\'une mise à jour du runtime Duniter V2 on-chain. Chaque upgrade suit un parcours strict en 5 étapes, de la qualification technique au suivi post-déploiement.',
category: 'on-chain',
icon: 'i-lucide-cpu',
instancesLabel: '~2-6 / an',
linkedRefs: [
{ label: 'Décision Runtime Upgrade', icon: 'i-lucide-scale', to: '/decisions', kind: 'decision' },
],
steps: [
{ label: 'Qualification', actor: 'Proposant', icon: 'i-lucide-file-check', type: 'checklist' },
{ label: 'Revue technique', actor: 'Comité technique', icon: 'i-lucide-search', type: 'checklist' },
{ label: 'Vote communautaire', actor: 'Communauté WoT', icon: 'i-lucide-vote', type: 'on_chain' },
{ label: 'Exécution on-chain', actor: 'Proposant', icon: 'i-lucide-zap', type: 'on_chain' },
{ label: 'Suivi post-upgrade', actor: 'Forgerons', icon: 'i-lucide-activity', type: 'checklist' },
],
},
]
@@ -142,7 +178,7 @@ const operationalProtocols = [
const n8nWorkflows = [
{
name: 'Vote -> Notification',
description: 'Notifie les membres lorsqu\'un nouveau vote demarre ou se termine.',
description: 'Notifie les membres lorsqu\'un nouveau vote démarre ou se termine.',
icon: 'i-lucide-bell',
status: 'actif',
},
@@ -153,13 +189,13 @@ const n8nWorkflows = [
status: 'actif',
},
{
name: 'Decision -> Etape suivante',
description: 'Avance automatiquement une decision a l\'etape suivante apres validation.',
name: 'Décision → Étape suivante',
description: 'Avance automatiquement une décision à l\'étape suivante après validation.',
icon: 'i-lucide-git-branch',
status: 'demo',
},
{
name: 'Mandat expire -> Alerte',
name: 'Mandat expiré → Alerte',
description: 'Envoie une alerte 7 jours avant l\'expiration d\'un mandat.',
icon: 'i-lucide-alarm-clock',
status: 'demo',
@@ -170,7 +206,7 @@ const n8nWorkflows = [
<template>
<SectionLayout
title="Protocoles & Fonctionnement"
subtitle="Boite a outils de vote, formules de seuil, workflows automatises"
subtitle="Boîte à outils de vote, formules de seuil, workflows automatisés"
:statuses="statuses"
:active-status="activeStatus"
@update:active-status="activeStatus = $event"
@@ -212,7 +248,7 @@ const n8nWorkflows = [
<template v-else>
<div v-if="filteredProtocols.length === 0" class="proto-empty">
<UIcon name="i-lucide-settings" class="text-2xl" />
<p>Aucun protocole trouve</p>
<p>Aucun protocole trouvé</p>
</div>
<div v-else class="proto-list">
@@ -262,7 +298,7 @@ const n8nWorkflows = [
<div class="proto-ops">
<h3 class="proto-ops__title">
<UIcon name="i-lucide-git-branch" class="text-sm" />
Protocoles operationnels
Protocoles opérationnels
<span class="proto-ops__count">{{ operationalProtocols.length }}</span>
</h3>
@@ -282,6 +318,21 @@ const n8nWorkflows = [
</div>
</div>
<!-- Linked references -->
<div v-if="op.linkedRefs.length > 0" class="proto-ops__refs">
<NuxtLink
v-for="ref in op.linkedRefs"
:key="ref.to"
:to="ref.to"
class="proto-ops__ref"
:class="`proto-ops__ref--${ref.kind}`"
>
<UIcon :name="ref.icon" class="text-xs" />
<span>{{ ref.label }}</span>
<UIcon name="i-lucide-arrow-right" class="text-xs proto-ops__ref-arrow" />
</NuxtLink>
</div>
<!-- Step timeline -->
<div class="proto-ops__timeline">
<div
@@ -314,8 +365,8 @@ const n8nWorkflows = [
<thead>
<tr>
<th>Nom</th>
<th>Duree</th>
<th>Majorite</th>
<th>Durée</th>
<th>Majorité</th>
<th>B</th>
<th>G</th>
<th>Smith</th>
@@ -343,7 +394,7 @@ const n8nWorkflows = [
<!-- Simulateur -->
<ToolboxVignette
title="Simulateur de formules"
:bullets="['Testez WoT, Smith, TechComm', 'Ajustez les parametres en temps reel', 'Visualisez les seuils']"
:bullets="['Testez WoT, Smith, TechComm', 'Ajustez les paramètres en temps réel', 'Visualisez les seuils']"
:actions="[
{ label: 'Tutos', icon: 'i-lucide-graduation-cap', emit: 'tutos' },
{ label: 'Ouvrir', icon: 'i-lucide-calculator', to: '/protocols/formulas', primary: true },
@@ -357,7 +408,7 @@ const n8nWorkflows = [
<span>Workflows n8n</span>
</div>
<p class="n8n-section__desc">
Automatisations reliees via MCP
Automatisations reliées via MCP
</p>
<div class="n8n-workflows">
@@ -387,12 +438,12 @@ const n8nWorkflows = [
<!-- Meta-gouvernance -->
<ToolboxVignette
title="Meta-gouvernance"
title="Méta-gouvernance"
:bullets="['Les formules sont soumises au vote', 'Modifier les seuils collectivement', 'Transparence totale']"
:actions="[
{ label: 'Tutos', icon: 'i-lucide-graduation-cap', emit: 'tutos' },
{ label: 'Formules', icon: 'i-lucide-calculator', emit: 'formules' },
{ label: 'Demarrer', icon: 'i-lucide-play', emit: 'meta', primary: true },
{ label: 'Démarrer', icon: 'i-lucide-play', emit: 'meta', primary: true },
]"
/>
</template>
@@ -439,7 +490,7 @@ const n8nWorkflows = [
<USelect
v-model="newProtocol.formula_config_id"
:items="formulaOptions"
placeholder="Selectionnez une formule..."
placeholder="Sélectionnez une formule..."
value-key="value"
/>
</div>
@@ -455,7 +506,7 @@ const n8nWorkflows = [
@click="createProtocol"
>
<UIcon v-if="creating" name="i-lucide-loader-2" class="animate-spin text-xs" />
<span>Creer</span>
<span>Créer</span>
</button>
</div>
</div>
@@ -952,6 +1003,49 @@ const n8nWorkflows = [
opacity: 0.7;
}
/* Linked references */
.proto-ops__refs {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.proto-ops__ref {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.375rem 0.75rem;
font-size: 0.75rem;
font-weight: 600;
border-radius: 20px;
text-decoration: none;
transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.proto-ops__ref:hover {
transform: translateY(-1px);
box-shadow: 0 2px 8px var(--mood-shadow);
}
.proto-ops__ref--document {
background: color-mix(in srgb, var(--mood-accent) 12%, transparent);
color: var(--mood-accent);
}
.proto-ops__ref--decision {
background: color-mix(in srgb, var(--mood-secondary, var(--mood-accent)) 12%, transparent);
color: var(--mood-secondary, var(--mood-accent));
}
.proto-ops__ref-arrow {
opacity: 0.4;
transition: opacity 0.12s;
}
.proto-ops__ref:hover .proto-ops__ref-arrow {
opacity: 1;
}
/* Timeline */
.proto-ops__timeline {
display: flex;