mirror of
https://github.com/block/buzz.git
synced 2026-10-27 20:41:57 +00:00
31 lines
1.8 KiB
SQL
31 lines
1.8 KiB
SQL
-- ── Communities ───────────────────────────────────────────────────────────────
|
|
-- Conformance: row zero (host binding). The host map. `resolve_host(host)`
|
|
-- reads exactly one row here to mint the request's TenantContext. This table
|
|
-- is OPERATOR-GLOBAL: it is the registry of tenants, not itself tenant-scoped,
|
|
-- so it carries no `community_id` of its own (its `id` IS the community key).
|
|
-- Listed in the lint allowlist as operator-global.
|
|
--
|
|
-- Host normalization (Lane 0 contract): `host` is stored already-normalized —
|
|
-- ASCII-lowercased, trailing dot stripped, default port omitted. The UNIQUE is
|
|
-- on `lower(host)` belt-and-suspenders so `Relay.Example` and `relay.example`
|
|
-- can never become two tenants even if a writer forgets to normalize.
|
|
-- `resolve_host()` (buzz-core) applies the identical normalization before
|
|
-- lookup, so resolution and storage agree by construction.
|
|
|
|
CREATE TABLE communities (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
host VARCHAR(255) NOT NULL,
|
|
signing_key BYTEA,
|
|
-- Per-community workspace icon (NIP-11 `icon`), set via kind:9033.
|
|
-- Added by migration 0003; kept here so desired-state applies match.
|
|
icon TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
archived_at TIMESTAMPTZ,
|
|
deletion_state TEXT NOT NULL DEFAULT 'active' CHECK (deletion_state IN ('active', 'quiescing', 'fenced', 'tombstone')),
|
|
deletion_fence_generation BIGINT NOT NULL DEFAULT 0 CHECK (deletion_fence_generation >= 0),
|
|
deleted_at TIMESTAMPTZ,
|
|
CONSTRAINT chk_communities_id_not_nil CHECK (id <> '00000000-0000-0000-0000-000000000000'::uuid)
|
|
);
|
|
|
|
CREATE UNIQUE INDEX idx_communities_host ON communities (lower(host));
|