v3 : modules d'ordre et de titre — moteur, données, serveur (L11)

L'ordre des articles de chaque section (cran 2) et le titre du document
(cran 4) deviennent des modules : des unités à part, dont les versions
sont des propositions votées comme les articles (dépliées, panier, chaîne).

- moteur : ld-engine/src/order.rs (qui est dans l'ordre, ordre proposé,
  complété à la fin quand un article entre ou sort, places redistribuées,
  nouvel article en fin de section) ; pending : un ordre de moins de deux
  articles n'est jamais à voter ;
- données : migration 0007 (units.kind, module_amendments) ; le seed
  déclare ses modules ; module_amend.rs les ajoute une fois, gardé et
  journalisé, aux documents nés sans eux, sans toucher articles ni votes ;
- serveur : modules.rs, order.rs, doc_title.rs (portes pour proposer,
  entrée en vigueur : les articles changent de place, le document change
  de titre, en et es passent « à revoir ») ; publication des modules ;
- reste mineur : la médiane compte les statuts open, in_force, applied,
  et eux seuls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-10-31 02:08:44 +01:00
co-authored by Claude Opus 5.5
parent 1a35d0f521
commit 3831ddb1bf
21 changed files with 2249 additions and 115 deletions
+30 -3
View File
@@ -1,9 +1,11 @@
//! What is left to vote in a document — the line of « Décisions ».
//!
//! A module is an article (a unit). It stays **to vote** as long as no version
//! A module is an article, the title of the document, or the order of a
//! section (ADR 0009) — a unit. It stays **to vote** as long as no version
//! of it was adopted by a vote: its version in force is a seed a minima not yet
//! confirmed, or it has no version in force and at least one open version.
//! Variants of an article count once. For a person who votes, a module is
//! Variants of an article count once. The order of a section of fewer than two
//! articles has nothing to decide: never to vote. For a person who votes, a module is
//! **without their vote** when they hold no valid vote (one not « to
//! reconfirm ») on any of its versions.
@@ -17,10 +19,16 @@ pub struct Module {
pub open: u32,
/// The person holds a valid vote on one of its versions, in force or open.
pub voted: bool,
/// Nothing to decide: the order of a section of fewer than two articles
/// (`order::is_moot`). Never to vote, and not shown.
pub moot: bool,
}
impl Module {
pub fn to_vote(&self) -> bool {
if self.moot {
return false;
}
match self.in_force {
Some(adopted) => !adopted,
None => self.open > 0,
@@ -51,7 +59,7 @@ mod tests {
const ADOPTED: Option<bool> = Some(true);
fn m(in_force: Option<bool>, open: u32, voted: bool) -> Module {
Module { in_force, open, voted }
Module { in_force, open, voted, moot: false }
}
#[test]
@@ -88,6 +96,25 @@ mod tests {
assert_eq!(pending(&modules), Pending { to_vote: 31, without_my_vote: 30 });
}
#[test]
fn an_order_with_nothing_to_decide_is_never_to_vote() {
let one_article = Module { moot: true, ..m(SEED, 1, false) };
assert!(!one_article.to_vote());
assert_eq!(pending(&[one_article]), Pending::default());
}
#[test]
fn the_modules_of_the_certification_act() {
// 33 articles; the title of the document; the order of each of the 8 sections,
// all seeds a minima — but « ordonnancement » holds one article: 41 to vote.
let mut modules = vec![m(SEED, 0, false); 3];
modules.extend(vec![m(None, 1, false); 30]);
modules.push(m(SEED, 0, false));
modules.extend(vec![m(SEED, 0, false); 7]);
modules.push(Module { moot: true, ..m(SEED, 0, false) });
assert_eq!(pending(&modules), Pending { to_vote: 41, without_my_vote: 41 });
}
#[test]
fn nothing_to_vote_in_an_empty_document() {
assert_eq!(pending(&[]), Pending::default());