fix(data): protect portfolio publication invariant

This commit is contained in:
2026-06-01 09:20:27 +03:00
parent 5809a470b9
commit d591e5ed5a
4 changed files with 114 additions and 5 deletions
@@ -52,6 +52,48 @@ CREATE TABLE portfolio_game_masters (
CREATE INDEX ix_portfolio_game_masters_player
ON portfolio_game_masters (player_id, portfolio_game_id);
CREATE FUNCTION unpublish_portfolio_game_without_required_links()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
PERFORM 1
FROM portfolio_games
WHERE id = OLD.portfolio_game_id
FOR UPDATE;
UPDATE portfolio_games
SET is_public = false,
updated_at = now()
WHERE id = OLD.portfolio_game_id
AND is_public = true
AND (
NOT EXISTS (
SELECT 1
FROM portfolio_game_sessions
WHERE portfolio_game_id = OLD.portfolio_game_id
)
OR NOT EXISTS (
SELECT 1
FROM portfolio_game_masters
WHERE portfolio_game_id = OLD.portfolio_game_id
)
);
RETURN OLD;
END;
$$;
CREATE TRIGGER trg_portfolio_game_sessions_unpublish_after_delete
AFTER DELETE ON portfolio_game_sessions
FOR EACH ROW
EXECUTE FUNCTION unpublish_portfolio_game_without_required_links();
CREATE TRIGGER trg_portfolio_game_masters_unpublish_after_delete
AFTER DELETE ON portfolio_game_masters
FOR EACH ROW
EXECUTE FUNCTION unpublish_portfolio_game_without_required_links();
CREATE TABLE portfolio_game_reviews (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
portfolio_game_id UUID NOT NULL REFERENCES portfolio_games(id) ON DELETE CASCADE,
@@ -80,5 +122,5 @@ CREATE INDEX ix_portfolio_game_reviews_public
WHERE moderation_status = 'Approved' AND publication_consent_at IS NOT NULL;
CREATE INDEX ix_portfolio_game_reviews_pending
ON portfolio_game_reviews (created_at)
ON portfolio_game_reviews (portfolio_game_id, created_at DESC)
WHERE moderation_status = 'Pending';