- Accueil sobre, menu complet à gauche (Décisions, Docs de référence, Mandats, Protocoles), intro demandée, quatre sections, connexion Ğ1. - Lecteur : texte en vigueur en Literata, actions contextuelles par article (le vote, propositions, proposer), propositions en cours sous la « surface » avec leur niveau d'eau, aperçus « si les bien cotées passent » / « si tout passe », langue du texte fr/en/es (traductions éditoriales). - Panneau : vote pour/contre, seuil et formule (MathML), inertie et son changement (voté en inertie +), coquille sans vote, traduction, signalement de contradiction, historique des corrections. - trustinWallet (/acces) : groupes et membres, invitations à usage unique, administrateurs, retours d'usage. - Contrôles : vitest (markdown, catalogues, anti-lexique), Playwright C1–C10 + M1. - Sections du seed portées jusqu'à l'écran. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
183 lines
6.4 KiB
SQL
183 lines
6.4 KiB
SQL
-- libreDecision v3 — initial schema. Runtime data: never dropped, never rewritten.
|
|
-- Dates are RFC 3339 UTC strings (sortable).
|
|
|
|
CREATE TABLE identities (
|
|
id TEXT PRIMARY KEY, -- idty:<index> | inv:<hex> | dev:<name>
|
|
kind TEXT NOT NULL, -- g1 | invite | dev
|
|
display_name TEXT NOT NULL,
|
|
address TEXT, -- SS58 seen at the last Ğ1 sign-in, display only
|
|
g1_member INTEGER NOT NULL DEFAULT 0,
|
|
admin INTEGER NOT NULL DEFAULT 0,
|
|
created_at TEXT NOT NULL,
|
|
last_seen_at TEXT
|
|
);
|
|
|
|
CREATE TABLE sessions (
|
|
token_hash TEXT PRIMARY KEY,
|
|
identity_id TEXT NOT NULL REFERENCES identities(id),
|
|
created_at TEXT NOT NULL,
|
|
expires_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE invitations (
|
|
token_hash TEXT PRIMARY KEY,
|
|
label TEXT NOT NULL,
|
|
admin INTEGER NOT NULL DEFAULT 0,
|
|
groups TEXT NOT NULL DEFAULT '[]', -- JSON array of group slugs granted on acceptance
|
|
created_by TEXT,
|
|
created_at TEXT NOT NULL,
|
|
expires_at TEXT NOT NULL,
|
|
used_at TEXT,
|
|
identity_id TEXT
|
|
);
|
|
|
|
CREATE TABLE groups (
|
|
slug TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
parent TEXT,
|
|
policy TEXT NOT NULL, -- g1-members | managed
|
|
hidden INTEGER NOT NULL DEFAULT 0,
|
|
position INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE memberships (
|
|
group_slug TEXT NOT NULL REFERENCES groups(slug),
|
|
identity_id TEXT NOT NULL REFERENCES identities(id),
|
|
granted_by TEXT,
|
|
granted_at TEXT NOT NULL,
|
|
PRIMARY KEY (group_slug, identity_id)
|
|
);
|
|
|
|
CREATE TABLE documents (
|
|
id TEXT PRIMARY KEY,
|
|
group_slug TEXT NOT NULL REFERENCES groups(slug),
|
|
slug TEXT NOT NULL,
|
|
title TEXT NOT NULL, -- JSON {lang: text}
|
|
summary TEXT NOT NULL, -- JSON {lang: text}
|
|
source_lang TEXT NOT NULL,
|
|
vote_floor REAL NOT NULL, -- C, minimal number of "for" votes
|
|
publish_path TEXT, -- path in the texts repository; NULL = never published
|
|
created_at TEXT NOT NULL,
|
|
UNIQUE (group_slug, slug)
|
|
);
|
|
|
|
CREATE TABLE units (
|
|
id TEXT PRIMARY KEY,
|
|
doc_id TEXT NOT NULL REFERENCES documents(id),
|
|
code TEXT NOT NULL,
|
|
section TEXT, -- grouping key of the seed (introduction, technique…)
|
|
position REAL NOT NULL,
|
|
inertia TEXT NOT NULL, -- low | standard | high | max
|
|
in_force_id TEXT, -- proposals.id of the version in force, NULL = empty slot
|
|
created_at TEXT NOT NULL
|
|
);
|
|
CREATE INDEX units_doc ON units(doc_id);
|
|
|
|
-- A proposal is a version of a unit: proposed, in force, or past.
|
|
CREATE TABLE proposals (
|
|
id TEXT PRIMARY KEY,
|
|
unit_id TEXT NOT NULL REFERENCES units(id),
|
|
kind TEXT NOT NULL, -- text | remove | inertia
|
|
inertia_target TEXT,
|
|
title TEXT NOT NULL,
|
|
body TEXT NOT NULL,
|
|
status TEXT NOT NULL, -- draft | open | in_force | superseded | withdrawn
|
|
origin TEXT NOT NULL, -- seed | member
|
|
label TEXT,
|
|
author_id TEXT REFERENCES identities(id),
|
|
revision INTEGER NOT NULL DEFAULT 1,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
submitted_at TEXT,
|
|
entered_at TEXT, -- entered into force by vote; NULL for a seed a minima
|
|
left_at TEXT,
|
|
confirmed_at TEXT -- a seed a minima that later reached its threshold
|
|
);
|
|
CREATE INDEX proposals_unit ON proposals(unit_id);
|
|
|
|
CREATE TABLE revisions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
proposal_id TEXT NOT NULL REFERENCES proposals(id),
|
|
revision INTEGER NOT NULL,
|
|
kind TEXT NOT NULL, -- initial | typo | substantive
|
|
title TEXT NOT NULL,
|
|
body TEXT NOT NULL,
|
|
author_id TEXT,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
CREATE INDEX revisions_proposal ON revisions(proposal_id);
|
|
|
|
CREATE TABLE votes (
|
|
proposal_id TEXT NOT NULL REFERENCES proposals(id),
|
|
identity_id TEXT NOT NULL REFERENCES identities(id),
|
|
choice TEXT NOT NULL, -- for | against
|
|
revision INTEGER NOT NULL, -- counted only while equal to proposals.revision
|
|
cast_at TEXT NOT NULL,
|
|
PRIMARY KEY (proposal_id, identity_id)
|
|
);
|
|
|
|
CREATE TABLE signals (
|
|
id TEXT PRIMARY KEY,
|
|
proposal_id TEXT NOT NULL REFERENCES proposals(id),
|
|
target_proposal_id TEXT NOT NULL REFERENCES proposals(id),
|
|
reason TEXT NOT NULL,
|
|
author_id TEXT NOT NULL REFERENCES identities(id),
|
|
created_at TEXT NOT NULL,
|
|
lifted_at TEXT,
|
|
lifted_by TEXT -- identity id, or 'revision' when the text changed
|
|
);
|
|
|
|
CREATE TABLE translations (
|
|
proposal_id TEXT NOT NULL REFERENCES proposals(id),
|
|
lang TEXT NOT NULL,
|
|
title TEXT NOT NULL,
|
|
body TEXT NOT NULL,
|
|
source_hash TEXT NOT NULL, -- hash of the source title + body it translates
|
|
origin TEXT NOT NULL, -- seed | member
|
|
updated_by TEXT,
|
|
updated_at TEXT NOT NULL,
|
|
PRIMARY KEY (proposal_id, lang)
|
|
);
|
|
|
|
CREATE TABLE adoptions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
proposal_id TEXT NOT NULL,
|
|
unit_id TEXT NOT NULL,
|
|
doc_id TEXT NOT NULL,
|
|
kind TEXT NOT NULL,
|
|
votes_for INTEGER NOT NULL,
|
|
votes_against INTEGER NOT NULL,
|
|
electorate INTEGER NOT NULL,
|
|
required INTEGER NOT NULL,
|
|
params TEXT NOT NULL,
|
|
at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE outbox (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
doc_id TEXT NOT NULL,
|
|
reason TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
attempts INTEGER NOT NULL DEFAULT 0,
|
|
last_error TEXT,
|
|
next_at TEXT NOT NULL,
|
|
done_at TEXT,
|
|
commit_sha TEXT
|
|
);
|
|
|
|
CREATE TABLE feedback (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
identity_id TEXT,
|
|
route TEXT NOT NULL,
|
|
body TEXT NOT NULL,
|
|
context TEXT,
|
|
created_at TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'new'
|
|
);
|
|
|
|
CREATE TABLE settings (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|