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>
99 lines
2.7 KiB
TypeScript
99 lines
2.7 KiB
TypeScript
/**
|
|
* Composable for real-time vote formula computation.
|
|
*
|
|
* Re-exports and wraps the threshold utility functions for reactive use
|
|
* in Vue components. Provides convenient methods for threshold calculations,
|
|
* inertia factor, required ratio, and adoption checks.
|
|
*/
|
|
import { wotThreshold, smithThreshold, techcommThreshold } from '~/utils/threshold'
|
|
|
|
export interface FormulaParams {
|
|
majority_pct: number
|
|
base_exponent: number
|
|
gradient_exponent: number
|
|
constant_base: number
|
|
}
|
|
|
|
export function useVoteFormula() {
|
|
/**
|
|
* Compute the WoT threshold for a given set of parameters.
|
|
*/
|
|
function computeThreshold(wotSize: number, totalVotes: number, params: FormulaParams): number {
|
|
return wotThreshold(
|
|
wotSize,
|
|
totalVotes,
|
|
params.majority_pct,
|
|
params.base_exponent,
|
|
params.gradient_exponent,
|
|
params.constant_base,
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Compute the inertia factor: 1 - (T/W)^G
|
|
* Ranges from ~1 (low participation) to ~0 (full participation).
|
|
*/
|
|
function computeInertiaFactor(
|
|
totalVotes: number,
|
|
wotSize: number,
|
|
gradientExponent: number,
|
|
): number {
|
|
if (wotSize <= 0 || totalVotes <= 0) return 1.0
|
|
const participationRatio = totalVotes / wotSize
|
|
return 1.0 - Math.pow(participationRatio, gradientExponent)
|
|
}
|
|
|
|
/**
|
|
* Compute the required ratio of "pour" votes at a given participation level.
|
|
* requiredRatio = M + (1 - M) * inertiaFactor
|
|
*/
|
|
function computeRequiredRatio(
|
|
totalVotes: number,
|
|
wotSize: number,
|
|
majorityPct: number,
|
|
gradientExponent: number,
|
|
): number {
|
|
const M = majorityPct / 100
|
|
const inertia = computeInertiaFactor(totalVotes, wotSize, gradientExponent)
|
|
return M + (1.0 - M) * inertia
|
|
}
|
|
|
|
/**
|
|
* Check whether a vote is adopted given all criteria.
|
|
* A vote is adopted when it passes the WoT threshold AND
|
|
* any applicable Smith/TechComm criteria.
|
|
*/
|
|
function isAdopted(
|
|
votesFor: number,
|
|
threshold: number,
|
|
smithVotesFor?: number,
|
|
smithThresholdVal?: number,
|
|
techcommVotesFor?: number,
|
|
techcommThresholdVal?: number,
|
|
): boolean {
|
|
// Main WoT criterion
|
|
if (votesFor < threshold) return false
|
|
|
|
// Smith criterion (if applicable)
|
|
if (smithThresholdVal !== undefined && smithThresholdVal > 0) {
|
|
if ((smithVotesFor ?? 0) < smithThresholdVal) return false
|
|
}
|
|
|
|
// TechComm criterion (if applicable)
|
|
if (techcommThresholdVal !== undefined && techcommThresholdVal > 0) {
|
|
if ((techcommVotesFor ?? 0) < techcommThresholdVal) return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
return {
|
|
computeThreshold,
|
|
computeInertiaFactor,
|
|
computeRequiredRatio,
|
|
isAdopted,
|
|
smithThreshold,
|
|
techcommThreshold,
|
|
}
|
|
}
|