Files
archify-vscode-ext-sync/crates/store/migrations/0001_init.sql
T
root-at-skic 5c43b90ef8 Archify Sync server, Dockerfile and Helm chart
Rust server (axum, yrs, sqlx/PostgreSQL): live shared models over the y-websocket protocol, versions, browser sign-in with PKCE, invites, single sign-on through OIDC, metrics. Docker image on distroless, compose file, and a Helm chart with one pod, optional bundled PostgreSQL and secrets from existing Secrets.
2026-11-06 12:06:59 +02:00

96 lines
3.7 KiB
SQL

-- Organisations, accounts and sessions.
CREATE TABLE organisations (
id uuid PRIMARY KEY,
name text NOT NULL,
meta jsonb NOT NULL DEFAULT '{}',
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE accounts (
id uuid PRIMARY KEY,
organisation_id uuid NOT NULL REFERENCES organisations (id) ON DELETE CASCADE,
name text NOT NULL, -- sign-in name, unique per server
display_name text NOT NULL,
role text NOT NULL CHECK (role IN ('admin', 'member')),
password_hash text, -- argon2; NULL for SSO-only accounts
meta jsonb NOT NULL DEFAULT '{}',
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE UNIQUE INDEX accounts_name ON accounts (lower(name));
-- Refresh tokens rotate on every use; a reused token revokes its family.
CREATE TABLE refresh_tokens (
token_hash bytea PRIMARY KEY,
family uuid NOT NULL,
account_id uuid NOT NULL REFERENCES accounts (id) ON DELETE CASCADE,
expires_at timestamptz NOT NULL,
used_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX refresh_tokens_family ON refresh_tokens (family);
-- Server-wide values: the signing key, whether setup is done.
CREATE TABLE settings (
key text PRIMARY KEY,
value jsonb NOT NULL
);
-- Spaces: one shared model each.
CREATE TABLE spaces (
id uuid PRIMARY KEY,
organisation_id uuid NOT NULL REFERENCES organisations (id) ON DELETE CASCADE,
name text NOT NULL,
created_by uuid REFERENCES accounts (id) ON DELETE SET NULL,
meta jsonb NOT NULL DEFAULT '{}',
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE members (
space_id uuid NOT NULL REFERENCES spaces (id) ON DELETE CASCADE,
account_id uuid NOT NULL REFERENCES accounts (id) ON DELETE CASCADE,
role text NOT NULL CHECK (role IN ('owner', 'editor')),
joined_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (space_id, account_id)
);
CREATE INDEX members_account ON members (account_id);
CREATE TABLE invites (
token_hash bytea PRIMARY KEY,
space_id uuid NOT NULL REFERENCES spaces (id) ON DELETE CASCADE,
created_by uuid REFERENCES accounts (id) ON DELETE SET NULL,
expires_at timestamptz NOT NULL,
max_uses integer,
uses integer NOT NULL DEFAULT 0,
created_at timestamptz NOT NULL DEFAULT now()
);
-- The CRDT: an append-only log of Yjs updates since the last version, and
-- versions as full encoded documents. Taking a version compacts the log.
CREATE TABLE updates (
id bigserial PRIMARY KEY,
space_id uuid NOT NULL REFERENCES spaces (id) ON DELETE CASCADE,
data bytea NOT NULL,
account_id uuid REFERENCES accounts (id) ON DELETE SET NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX updates_space ON updates (space_id, id);
CREATE TABLE versions (
id bigserial PRIMARY KEY,
space_id uuid NOT NULL REFERENCES spaces (id) ON DELETE CASCADE,
major integer NOT NULL,
minor integer NOT NULL,
kind text NOT NULL CHECK (kind IN ('snapshot', 'publish', 'restore')),
name text,
state bytea NOT NULL,
up_to bigint NOT NULL, -- last update id the state contains
restored_from bigint REFERENCES versions (id) ON DELETE SET NULL,
created_by uuid REFERENCES accounts (id) ON DELETE SET NULL,
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (space_id, major, minor)
);
CREATE INDEX versions_space ON versions (space_id, id DESC);