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