Sprint 3 : protocoles de vote et boite a outils
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>
This commit is contained in:
@@ -32,9 +32,52 @@ export interface VotingProtocol {
|
||||
formula_config: FormulaConfig
|
||||
}
|
||||
|
||||
export interface ProtocolCreate {
|
||||
name: string
|
||||
description: string | null
|
||||
vote_type: string
|
||||
formula_config_id: string
|
||||
}
|
||||
|
||||
export interface FormulaCreate {
|
||||
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
|
||||
}
|
||||
|
||||
export interface SimulateParams {
|
||||
wot_size: number
|
||||
total_votes: number
|
||||
majority_pct: number
|
||||
base_exponent: number
|
||||
gradient_exponent: number
|
||||
constant_base: number
|
||||
smith_wot_size?: number
|
||||
smith_exponent?: number
|
||||
techcomm_size?: number
|
||||
techcomm_exponent?: number
|
||||
}
|
||||
|
||||
export interface SimulateResult {
|
||||
threshold: number
|
||||
smith_threshold: number | null
|
||||
techcomm_threshold: number | null
|
||||
inertia_factor: number
|
||||
required_ratio: number
|
||||
}
|
||||
|
||||
interface ProtocolsState {
|
||||
protocols: VotingProtocol[]
|
||||
formulas: FormulaConfig[]
|
||||
currentProtocol: VotingProtocol | null
|
||||
loading: boolean
|
||||
error: string | null
|
||||
}
|
||||
@@ -43,6 +86,7 @@ export const useProtocolsStore = defineStore('protocols', {
|
||||
state: (): ProtocolsState => ({
|
||||
protocols: [],
|
||||
formulas: [],
|
||||
currentProtocol: null,
|
||||
loading: false,
|
||||
error: null,
|
||||
}),
|
||||
@@ -96,5 +140,89 @@ export const useProtocolsStore = defineStore('protocols', {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch a single protocol by ID.
|
||||
*/
|
||||
async fetchProtocolById(id: string) {
|
||||
this.loading = true
|
||||
this.error = null
|
||||
|
||||
try {
|
||||
const { $api } = useApi()
|
||||
this.currentProtocol = await $api<VotingProtocol>(`/protocols/${id}`)
|
||||
} catch (err: any) {
|
||||
this.error = err?.data?.detail || err?.message || 'Protocole introuvable'
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new voting protocol.
|
||||
*/
|
||||
async createProtocol(data: ProtocolCreate) {
|
||||
this.loading = true
|
||||
this.error = null
|
||||
|
||||
try {
|
||||
const { $api } = useApi()
|
||||
const protocol = await $api<VotingProtocol>('/protocols/', {
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
this.protocols.push(protocol)
|
||||
return protocol
|
||||
} catch (err: any) {
|
||||
this.error = err?.data?.detail || err?.message || 'Erreur lors de la creation du protocole'
|
||||
throw err
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new formula configuration.
|
||||
*/
|
||||
async createFormula(data: FormulaCreate) {
|
||||
this.loading = true
|
||||
this.error = null
|
||||
|
||||
try {
|
||||
const { $api } = useApi()
|
||||
const formula = await $api<FormulaConfig>('/protocols/formulas', {
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
this.formulas.push(formula)
|
||||
return formula
|
||||
} catch (err: any) {
|
||||
this.error = err?.data?.detail || err?.message || 'Erreur lors de la creation de la formule'
|
||||
throw err
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulate formula computation on the backend.
|
||||
*/
|
||||
async simulate(params: SimulateParams) {
|
||||
this.loading = true
|
||||
this.error = null
|
||||
|
||||
try {
|
||||
const { $api } = useApi()
|
||||
return await $api<SimulateResult>('/protocols/simulate', {
|
||||
method: 'POST',
|
||||
body: params,
|
||||
})
|
||||
} catch (err: any) {
|
||||
this.error = err?.data?.detail || err?.message || 'Erreur lors de la simulation'
|
||||
throw err
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user