Files
decision/crates/ld-server/migrations/0001_init.sql
YvvandClaude Opus 5.5 7a022dd35e v3 : interface Svelte — accueil, groupes, lecteur du texte en vigueur, panneau contextuel, éditeur à assistant, trustinWallet
- 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>
2026-10-21 02:58:34 +02:00

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
);