gestion_table_tournante_libre/test/fixtures/badges/temoin.js
Mathieu Benoit 4e25e73a5d [ADD] badges: sheet model from the retained plan or a chosen proposal
Badges hang on guests' necks: their content must be exact and stable. The
model builds one badge per non-excluded person, from the retained plan or,
on demand, from a proposal, which always prints as a draft. Each round says
table, seat when seats are assigned, and a title only where a reservation
makes the person its holder there; a constant itinerary takes one line.
Names sort by code point, never by locale; namesakes carry their id, and a
reprint gives the same texts. Without any placement it refuses, pointing at
the proposals.
Checked: red first; 3343 node tests green from the index alone.

--- FR ---

[ADD] badges : modèle de planche, du retenu ou d'une proposition choisie

Les badges pendent au cou des invités : leur contenu doit être exact et
stable. Le modèle fait un badge par personne non exclue, depuis le retenu
ou, sur demande, une proposition, toujours imprimée en brouillon. Chaque
tour dit la table, le siège sous attribution, et un titre seulement là où
une réservation en fait la personne titulaire ; un itinéraire constant tient
en une ligne. Les noms se classent par points de code, jamais selon la
locale ; les homonymes portent leur identifiant, et une réédition rend les
mêmes textes. Sans aucun placement, il refuse et renvoie aux propositions.
Vérifié : rouge d'abord ; 3343 node verts depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 13:03:04 -04:00

75 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// © 2026 TechnoLibre (http://www.technolibre.ca)
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
// Le témoin de la planche (§ 15.1, § 11.5) : 260 personnes inventées,
// « Témoin 001 » à « Témoin 260 », dont 3 exclues, sur la salle de la grande
// démonstration — 33 tables, 29 de 8 sièges et 4 de 7 —, 4 tours, et un
// placement retenu, daté, sur un plan retenu. Les 257 badges qu'il produit
// donnent 65 planches A4 et 129 planches Lettre (§ 15.1).
//
// Chaque personne porte un courriel, des notes et un titre pressenti, que le
// badge ne doit jamais imprimer (§ 11.4), et une personne sur cinq une
// appartenance. Le plan du tour r range les 257 présentes à partir du rang
// 64 × (r − 1), en boucle, et remplit les tables dans l'ordre de leurs
// identifiants : chaque tour est une partition, les trois sièges libres
// tombent à la dernière table. Aucune réservation, aucun titre. Chaque appel
// rend une charge neuve.
import { creerCharge } from '../../../src/stockage/document.js';
import { H_RETENU, personne, placementDe, table } from './cas.js';
/** Les comptes du témoin, que les épreuves lisent plutôt que de les écrire. */
export const FORME_TEMOIN = Object.freeze({
participants: 260,
exclus: 3,
produits: 257,
tables: 33,
tours: 4,
planchesA4: 65,
planchesLettre: 129,
});
/** Les identifiants des trois personnes exclues. */
export const EXCLUS_TEMOIN = Object.freeze([50, 150, 250]);
const DECALAGE_PAR_TOUR = 64;
/** Le numéro d'une personne du témoin, sur trois chiffres. */
export const numeroTemoin = (id) => String(id).padStart(3, '0');
/**
* La charge du témoin, état retenu, retenu daté de H_RETENU.
*
* @returns {import('../../../src/stockage/types.js').Charge}
*/
export function chargeTemoin() {
const { participants, tables, tours } = FORME_TEMOIN;
const charge = creerCharge({ id: 'evt-temoin', nom: 'Soirée des Lucioles', date: '2031-05-17', siegesParDefaut: 8, tours });
charge.evenement.etat = 'retenu';
charge.participants = Array.from({ length: participants }, (_, rang) => {
const id = rang + 1;
const n = numeroTemoin(id);
return personne(id, null, `Témoin ${n}`, {
appartenance: id % 5 === 0 ? 'Club des Merles' : null,
courriel: `temoin${n}@exemple.test`,
titrePressenti: `pressenti ${n}`,
notes: `note confidentielle ${n}`,
exclu: EXCLUS_TEMOIN.includes(id),
});
});
charge.tables = Array.from({ length: tables }, (_, rang) => table(rang + 1, rang + 1, rang < 29 ? null : 7));
const presents = charge.participants.filter(({ exclu }) => !exclu).map(({ id }) => id);
const plan = Array.from({ length: tours }, (_, r) => {
const debut = (DECALAGE_PAR_TOUR * r) % presents.length;
const ordre = [...presents.slice(debut), ...presents.slice(0, debut)];
let rang = 0;
const sieges = charge.tables.map((enregistrement) => {
const liste = ordre.slice(rang, rang + (enregistrement.sieges ?? 8));
rang += liste.length;
return liste;
});
return { sieges };
});
charge.prochainsIds = { participant: participants + 1, table: tables + 1, proposition: 2 };
charge.retenu = { proposition: 1, ...placementDe(charge, plan), horodatage: H_RETENU };
return charge;
}