CREATE TABLE tags ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), name text NOT NULL UNIQUE, description text, color text, created_at timestamptz NOT NULL DEFAULT now() ); CREATE TABLE entity_tags ( entity_type text NOT NULL, entity_id uuid NOT NULL, tag_id uuid NOT NULL REFERENCES tags(id) ON DELETE CASCADE, created_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (entity_type, entity_id, tag_id) ); CREATE TABLE entity_links ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), from_type text NOT NULL, from_id uuid NOT NULL, to_type text NOT NULL, to_id uuid NOT NULL, relation text NOT NULL DEFAULT 'attached', created_at timestamptz NOT NULL DEFAULT now(), UNIQUE (from_type, from_id, to_type, to_id, relation) ); CREATE TABLE attachments ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), entity_type text, entity_id uuid, filename text NOT NULL, mime_type text, size_bytes bigint, blob_path text NOT NULL, checksum text, uploaded_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX idx_entity_tags_entity ON entity_tags(entity_type, entity_id); CREATE INDEX idx_entity_links_from ON entity_links(from_type, from_id); CREATE INDEX idx_entity_links_to ON entity_links(to_type, to_id); CREATE INDEX idx_attachments_entity ON attachments(entity_type, entity_id);