forked from yvv/decision
Objections « redit » / « contredit » à la place des signalements : la dernière arrivée des deux versions n'est plus votable (repli, panier, chaîne : un vote déjà scellé est gardé mais ne la fait pas entrer) ; un texte en vigueur ne l'est jamais. L'auteur répond en modifiant l'article visé (proposition liée) ou en reformulant ; la personne qui objecte lève ou réitère depuis ses messages ; sans réponse sous 3 jours, l'objection est levée. Un administrateur peut lever. Coquilles : la sienne passe tout de suite ; celle d'un autre attend l'auteur (valider / refuser), passe seule au bout de 3 jours, et l'auteur garde la main tant que le texte n'est pas en vigueur. En vigueur, seule une coquille validée corrige (auteur de la version, administrateur pour un texte semé). Deux coquilles en attente : la seconde se mesure au texte voté ; à l'application, celle qui ne colle plus est périmée. Messagerie dans l'application (boîte, non-lus, gestes, échéance), chaque personne ne lit que les siens. Échéances par le balayage existant, avec rattrapage au démarrage et horloge injectable (route de dev). Migration 0008 additive : les signalements deviennent des « contredit », sans perte. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
94 lines
5.2 KiB
SQL
94 lines
5.2 KiB
SQL
-- Objections « redit » / « contredit », typo fixes validated, and the messages
|
|
-- of trustinWallet (2026-10-31, lot F, ADR 0010). Additive only: nothing is
|
|
-- dropped, nothing is rewritten that an older image needs.
|
|
--
|
|
-- The contradiction signals of before become objections « contredit », in the
|
|
-- same table: an older image (rollback) still reads them as signals, and every
|
|
-- lifting still writes `lifted_at` / `lifted_by` as before.
|
|
|
|
ALTER TABLE signals ADD COLUMN kind TEXT NOT NULL DEFAULT 'contredit'; -- redit | contredit
|
|
ALTER TABLE signals ADD COLUMN held_id TEXT; -- the version held back (not votable): the latest arrival, never one in force
|
|
ALTER TABLE signals ADD COLUMN phase TEXT NOT NULL DEFAULT 'author'; -- author | objector | lifted
|
|
ALTER TABLE signals ADD COLUMN cycle INTEGER NOT NULL DEFAULT 1; -- a reiteration opens the next
|
|
ALTER TABLE signals ADD COLUMN due_at TEXT; -- phase objector: lifted by itself at this time
|
|
ALTER TABLE signals ADD COLUMN answered_at TEXT; -- the last answer of the author
|
|
ALTER TABLE signals ADD COLUMN answer TEXT; -- revision | other | proposal
|
|
ALTER TABLE signals ADD COLUMN answer_id TEXT; -- the version revised, or the proposal linked
|
|
ALTER TABLE signals ADD COLUMN lift TEXT; -- objector | admin | deadline | withdrawn | revision
|
|
|
|
-- The signals of before that were lifted stay lifted: by their author, by an
|
|
-- administrator, or because the text changed (the rule of before).
|
|
UPDATE signals SET phase = 'lifted', lift = CASE
|
|
WHEN lifted_by = 'revision' THEN 'revision'
|
|
WHEN lifted_by = author_id THEN 'objector'
|
|
ELSE 'admin' END
|
|
WHERE lifted_at IS NOT NULL;
|
|
|
|
-- The standing ones wait for the author of the version they now hold back: the
|
|
-- latest arrival of the two (submitted last; the same instant: written last),
|
|
-- unless it is in force — then the other. Both in force: none is held.
|
|
UPDATE signals SET held_id = (
|
|
SELECT CASE
|
|
WHEN a.status = 'in_force' AND b.status = 'in_force' THEN NULL
|
|
WHEN (IFNULL(a.submitted_at, a.created_at), a.rowid, a.id) > (IFNULL(b.submitted_at, b.created_at), b.rowid, b.id)
|
|
THEN CASE WHEN a.status = 'in_force' THEN b.id ELSE a.id END
|
|
ELSE CASE WHEN b.status = 'in_force' THEN a.id ELSE b.id END
|
|
END
|
|
FROM proposals a, proposals b
|
|
WHERE a.id = signals.proposal_id AND b.id = signals.target_proposal_id)
|
|
WHERE lifted_at IS NULL;
|
|
|
|
CREATE INDEX signals_proposal ON signals(proposal_id);
|
|
CREATE INDEX signals_target ON signals(target_proposal_id);
|
|
CREATE INDEX signals_due ON signals(phase, due_at);
|
|
|
|
-- A proposal written to answer an objection (« modifier l'article visé »).
|
|
ALTER TABLE proposals ADD COLUMN objection_id TEXT;
|
|
|
|
-- A typo fix written by someone other than the one who answers for the version:
|
|
-- it waits for them (or for the deadline), then applies — or not.
|
|
CREATE TABLE typos (
|
|
id TEXT PRIMARY KEY,
|
|
proposal_id TEXT NOT NULL REFERENCES proposals(id),
|
|
doc_id TEXT NOT NULL REFERENCES documents(id),
|
|
writer_id TEXT NOT NULL REFERENCES identities(id), -- who wrote the fix
|
|
answerer_id TEXT, -- the author of the version, who answers; NULL = administrators (no author)
|
|
revision INTEGER NOT NULL, -- the revision it was written over
|
|
base_title TEXT NOT NULL, -- the text it was written over
|
|
base_body TEXT NOT NULL,
|
|
title TEXT NOT NULL, -- the fix
|
|
body TEXT NOT NULL,
|
|
status TEXT NOT NULL, -- pending | applied | refused | stale
|
|
created_at TEXT NOT NULL,
|
|
due_at TEXT NOT NULL, -- applied by itself then, if nobody answered
|
|
settled_at TEXT,
|
|
settled_by TEXT -- identity id, 'deadline', or 'changed' (stale)
|
|
);
|
|
CREATE INDEX typos_proposal ON typos(proposal_id, status);
|
|
CREATE INDEX typos_due ON typos(status, due_at);
|
|
|
|
-- The revision a validated fix wrote, or the one that took it back (kind 'revert'),
|
|
-- and who let it in: the identity that validated it, or 'deadline'.
|
|
ALTER TABLE revisions ADD COLUMN typo_id TEXT;
|
|
ALTER TABLE revisions ADD COLUMN answered_by TEXT;
|
|
|
|
-- The messages of trustinWallet: one person, one box. The text is told by the
|
|
-- interface from the subject (in the language of the reader); the gestures
|
|
-- follow the subject's state, so a message dealt with offers none.
|
|
CREATE TABLE messages (
|
|
id TEXT PRIMARY KEY,
|
|
recipient_id TEXT NOT NULL REFERENCES identities(id),
|
|
doc_id TEXT NOT NULL REFERENCES documents(id),
|
|
topic TEXT NOT NULL, -- objection | typo
|
|
subject_id TEXT NOT NULL, -- signals.id | typos.id
|
|
kind TEXT NOT NULL, -- objection_raised | objection_reiterated | objection_answered | typo_pending
|
|
cycle INTEGER NOT NULL DEFAULT 1,
|
|
created_at TEXT NOT NULL,
|
|
due_at TEXT,
|
|
read_at TEXT,
|
|
done_at TEXT,
|
|
outcome TEXT -- answered | lifted | reiterated | deadline | admin | withdrawn | applied | refused | stale
|
|
);
|
|
CREATE INDEX messages_box ON messages(recipient_id, created_at);
|
|
CREATE INDEX messages_subject ON messages(topic, subject_id);
|