ALTER TABLE services DROP CONSTRAINT services_available_source_check; ALTER TABLE services ADD CONSTRAINT services_available_source_check CHECK (available_source IN ('', 'webhook', 'poll')); ALTER TABLE services ADD COLUMN available_digest text NOT NULL DEFAULT ''; ALTER TABLE services ADD COLUMN last_poll_error text NOT NULL DEFAULT ''; ALTER TABLE services ADD COLUMN last_auto_digest text NOT NULL DEFAULT ''; -- Every version the master has seen. '' means "no tag" / "digest unknown"; -- never NULL, so the unique constraint deduplicates. CREATE TABLE image_versions ( id bigserial PRIMARY KEY, repo text NOT NULL, tag text NOT NULL DEFAULT '', digest text NOT NULL DEFAULT '', source text NOT NULL CHECK (source IN ('webhook', 'poll', 'running')), first_seen_at timestamptz NOT NULL, CONSTRAINT image_versions_tag_or_digest CHECK (tag <> '' OR digest <> ''), CONSTRAINT image_versions_unique UNIQUE (repo, tag, digest) ); CREATE INDEX image_versions_recent ON image_versions (repo, first_seen_at DESC, id DESC);