forked from yvv/decision
- Le revirement de l'auteur sur une coquille (reprendre une correction appliquée, valider une correction refusée) ne s'écrit que sur une version encore ouverte : Settle porte while_open ; et la garde de statut de write_text marche enfin (?9 restait NULL, le statut est le 8e paramètre). - 0008 lève les signalements debout dont un côté est déjà retiré. - Une seule objection debout par personne et par paire (index unique partiel) ; envoyée plusieurs fois à la fois, les autres reçoivent objection_exists. - Un retrait relance l'adoption : la version que l'objection retenait entre aussitôt. Tests vus rouges d'abord. Boucle : 230 tests Rust, svelte-check 0, 55 vitest, e2e 35 / 35. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
107 lines
5.9 KiB
SQL
107 lines
5.9 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;
|
|
|
|
-- A standing one whose other side left (withdrawn, or never submitted) ends: a
|
|
-- withdrawal ends the objection, which the rule of before did not do.
|
|
UPDATE signals SET phase = 'lifted', lift = 'withdrawn', lifted_by = 'withdrawn',
|
|
lifted_at = strftime('%Y-%m-%dT%H:%M:%SZ', 'now')
|
|
WHERE lifted_at IS NULL AND EXISTS (
|
|
SELECT 1 FROM proposals p
|
|
WHERE p.id IN (signals.proposal_id, signals.target_proposal_id) AND p.status NOT IN ('open', 'in_force'));
|
|
|
|
-- 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);
|
|
-- One person, one standing objection on a pair, whichever way it was written
|
|
-- (relecture of cd7e683: sent four times at once, four stood).
|
|
CREATE UNIQUE INDEX signals_one_standing
|
|
ON signals(author_id, min(proposal_id, target_proposal_id), max(proposal_id, target_proposal_id))
|
|
WHERE lifted_at IS NULL;
|
|
|
|
-- 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);
|