/** * 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 } 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 } export const useProtocolsStore = defineStore('protocols', { state: (): ProtocolsState => ({ protocols: [], formulas: [], currentProtocol: null, 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 = {} if (params?.vote_type) query.vote_type = params.vote_type this.protocols = await $api('/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('/protocols/formulas') } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Erreur lors du chargement des formules' } finally { 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(`/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('/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('/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('/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 } }, }, })