Lot V : le quorum jugé sur le décompte affiché, l'adoption jamais sur une intention ; « un vote existe » pour chaque état du tampon (en attente, prouvé quel que soit son sort, retrait, simulé) — tests vus rouges par mutation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-11-03 05:37:46 +01:00
co-authored by Claude Opus 5.5
parent c0c4d129cb
commit 0cde5bdbd0
2 changed files with 158 additions and 6 deletions
+17 -6
View File
@@ -27,21 +27,32 @@ use std::collections::{HashMap, HashSet};
///
/// A vote exists on an article when any version of it (its texts, a removal, a change
/// of its inertia; any revision) holds
/// - a vote of the server (`votes`: a vote of a managed group, or the line of a ballot
/// of the chain once confirmed, written there by the confirmation);
/// - a line of a ballot of the chain, **even pending** — signed, not yet read on the
/// chain (Yvv, 2026-11-03) — or confirmed; a refused or expired ballot is no vote;
/// - a vote that counts (`votes`): a vote of a managed group, a vote proven by the
/// chain, a **simulated** vote (ADR 0012);
/// - a line of a ballot — the buffer of the votes keeps their history (ADR 0012) —
/// of the chain or of the simulation: **an intention still pending** (signed, not yet
/// read on the chain: Yvv, 2026-11-03), or a ballot proven, **whatever became of its
/// line**: the voice that counts, a vote overtaken by a more recent one, a *for* set
/// aside by an objection, **a withdrawal** (`none`). A vote withdrawn on the chain or
/// in simulation, before any adoption, thus still says that someone voted. A ballot
/// the wallet never signed (let go at once), never seen on the chain in time, or
/// refused by the chain, is no vote;
/// - an adoption: a version that entered into force by the vote keeps that trace once
/// its votes are withdrawn.
///
/// A vote of the server withdrawn before any adoption leaves no row (`votes` keeps the
/// last choice only): from then on, no vote exists (a known limit, ADR 0013).
/// Two limits, known. In a managed group there is no buffer: a vote of the server
/// withdrawn before any adoption leaves no row (`votes` keeps the last choice only),
/// and from then on no vote exists (ADR 0013). The act « supprime » that ends the
/// simulation (`simulation::discard`) takes the simulated ballots away with their
/// trace: an article voted in simulation only has no vote any more, unless an adoption
/// that holds on the proven votes stays.
pub async fn voted_units(conn: &mut SqliteConnection, doc_id: &str) -> sqlx::Result<HashSet<String>> {
let ids: Vec<String> = sqlx::query_scalar(
"SELECT p.unit_id FROM votes v
JOIN proposals p ON p.id = v.proposal_id JOIN units u ON u.id = p.unit_id
WHERE u.doc_id = ?1
UNION
-- Every ballot of the buffer, chain or simulated, pending or proven: its history.
SELECT p.unit_id FROM ballot_lines l
JOIN ballots b ON b.id = l.ballot_id
JOIN proposals p ON p.id = l.proposal_id JOIN units u ON u.id = p.unit_id