SET search_path TO atlas, public; -- 重试拥有独立代次;旧轮询或迟到结果不得影响新的生图请求。 ALTER TABLE media_ai_edits ADD COLUMN generation_attempt INTEGER NOT NULL DEFAULT 1 CHECK (generation_attempt >= 1); ALTER TABLE media_ai_edits DROP CONSTRAINT media_ai_edits_suite_shape; ALTER TABLE media_ai_edits ADD CONSTRAINT media_ai_edits_suite_shape CHECK ( (suite_id IS NULL AND suite_shot_id IS NULL AND suite_position IS NULL) OR (suite_id IS NOT NULL AND product_id IS NOT NULL AND suite_shot_id IS NOT NULL AND suite_position IS NOT NULL AND suite_position BETWEEN 0 AND 19)); ALTER TABLE product_image_suites ADD CONSTRAINT image_suite_input_references CHECK ( coalesce(jsonb_typeof(input -> 'reference_asset_ids') = 'array' AND jsonb_array_length(input -> 'reference_asset_ids') BETWEEN 1 AND 8, false)); CREATE FUNCTION guard_image_suite_snapshot() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN IF NEW.input IS DISTINCT FROM OLD.input OR NEW.product_id IS DISTINCT FROM OLD.product_id OR NEW.variant_id IS DISTINCT FROM OLD.variant_id OR NEW.purpose IS DISTINCT FROM OLD.purpose THEN RAISE EXCEPTION '套图输入快照不可改写' USING ERRCODE = '23514'; END IF; IF NEW.shots IS DISTINCT FROM OLD.shots AND (OLD.purpose <> 'plan' OR OLD.status NOT IN ('queued', 'running')) THEN RAISE EXCEPTION '已固化的出图方案不可改写' USING ERRCODE = '23514'; END IF; RETURN NEW; END $$; CREATE TRIGGER product_image_suite_snapshot BEFORE UPDATE ON product_image_suites FOR EACH ROW EXECUTE FUNCTION guard_image_suite_snapshot(); CREATE FUNCTION guard_image_suite_reference_slot() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN IF NOT EXISTS (SELECT 1 FROM product_image_suites WHERE workspace_id = NEW.workspace_id AND id = NEW.suite_id AND input -> 'reference_asset_ids' ->> NEW.position = NEW.asset_id::text) THEN RAISE EXCEPTION '底图槽位与套图输入快照不一致' USING ERRCODE = '23514'; END IF; RETURN NEW; END $$; CREATE TRIGGER product_image_suite_reference_slot BEFORE INSERT OR UPDATE ON product_image_suite_references FOR EACH ROW EXECUTE FUNCTION guard_image_suite_reference_slot();