Sprint 1 : scaffolding complet de Glibredecision
Plateforme de decisions collectives pour Duniter/G1. Backend FastAPI async + PostgreSQL (14 tables, 8 routers, 6 services, moteur de vote avec formule d'inertie WoT/Smith/TechComm). Frontend Nuxt 4 + Nuxt UI v3 + Pinia (9 pages, 5 stores). Infrastructure Docker + Woodpecker CI + Traefik. Documentation technique et utilisateur (15 fichiers). Seed : Licence G1, Engagement Forgeron v2.0.0, 4 protocoles de vote. 30 tests unitaires (formules, mode params, vote nuance) -- tous verts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
100
frontend/app/stores/protocols.ts
Normal file
100
frontend/app/stores/protocols.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Protocols store: voting protocols and formula configurations.
|
||||
*
|
||||
* Maps to the backend /api/v1/protocols endpoints.
|
||||
*/
|
||||
|
||||
export interface FormulaConfig {
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
duration_days: number
|
||||
majority_pct: number
|
||||
base_exponent: number
|
||||
gradient_exponent: number
|
||||
constant_base: number
|
||||
smith_exponent: number | null
|
||||
techcomm_exponent: number | null
|
||||
nuanced_min_participants: number | null
|
||||
nuanced_threshold_pct: number | null
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface VotingProtocol {
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
vote_type: string
|
||||
formula_config_id: string
|
||||
mode_params: string | null
|
||||
is_meta_governed: boolean
|
||||
created_at: string
|
||||
formula_config: FormulaConfig
|
||||
}
|
||||
|
||||
interface ProtocolsState {
|
||||
protocols: VotingProtocol[]
|
||||
formulas: FormulaConfig[]
|
||||
loading: boolean
|
||||
error: string | null
|
||||
}
|
||||
|
||||
export const useProtocolsStore = defineStore('protocols', {
|
||||
state: (): ProtocolsState => ({
|
||||
protocols: [],
|
||||
formulas: [],
|
||||
loading: false,
|
||||
error: null,
|
||||
}),
|
||||
|
||||
getters: {
|
||||
binaryProtocols: (state): VotingProtocol[] => {
|
||||
return state.protocols.filter(p => p.vote_type === 'binary')
|
||||
},
|
||||
nuancedProtocols: (state): VotingProtocol[] => {
|
||||
return state.protocols.filter(p => p.vote_type === 'nuanced')
|
||||
},
|
||||
metaGovernedProtocols: (state): VotingProtocol[] => {
|
||||
return state.protocols.filter(p => p.is_meta_governed)
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
/**
|
||||
* Fetch all voting protocols with their formula configurations.
|
||||
*/
|
||||
async fetchProtocols(params?: { vote_type?: string }) {
|
||||
this.loading = true
|
||||
this.error = null
|
||||
|
||||
try {
|
||||
const { $api } = useApi()
|
||||
const query: Record<string, string> = {}
|
||||
if (params?.vote_type) query.vote_type = params.vote_type
|
||||
|
||||
this.protocols = await $api<VotingProtocol[]>('/protocols/', { query })
|
||||
} catch (err: any) {
|
||||
this.error = err?.data?.detail || err?.message || 'Erreur lors du chargement des protocoles'
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch all formula configurations.
|
||||
*/
|
||||
async fetchFormulas() {
|
||||
this.loading = true
|
||||
this.error = null
|
||||
|
||||
try {
|
||||
const { $api } = useApi()
|
||||
this.formulas = await $api<FormulaConfig[]>('/protocols/formulas')
|
||||
} catch (err: any) {
|
||||
this.error = err?.data?.detail || err?.message || 'Erreur lors du chargement des formules'
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user