fix(data): enforce completed portfolio sessions
This commit is contained in:
@@ -4,16 +4,18 @@ var postgres = builder.AddPostgres("postgres")
|
||||
.WithPgAdmin()
|
||||
.AddDatabase("gmrelay-db");
|
||||
|
||||
builder.AddProject<Projects.GmRelay_Bot>("bot")
|
||||
var bot = builder.AddProject<Projects.GmRelay_Bot>("bot")
|
||||
.WithReference(postgres)
|
||||
.WaitFor(postgres);
|
||||
|
||||
builder.AddProject<Projects.GmRelay_DiscordBot>("discord")
|
||||
.WithReference(postgres)
|
||||
.WaitFor(postgres);
|
||||
.WaitFor(postgres)
|
||||
.WaitFor(bot);
|
||||
|
||||
builder.AddProject<Projects.GmRelay_Web>("web")
|
||||
.WithReference(postgres)
|
||||
.WaitFor(postgres);
|
||||
.WaitFor(postgres)
|
||||
.WaitFor(bot);
|
||||
|
||||
builder.Build().Run();
|
||||
|
||||
@@ -58,13 +58,18 @@ LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE
|
||||
target_portfolio_game_id UUID;
|
||||
target_portfolio_game_ids UUID[];
|
||||
BEGIN
|
||||
PERFORM pg_advisory_xact_lock(20260530, 108);
|
||||
|
||||
IF TG_TABLE_NAME = 'portfolio_games' THEN
|
||||
target_portfolio_game_id := NEW.id;
|
||||
target_portfolio_game_ids := ARRAY[NEW.id];
|
||||
ELSIF TG_OP = 'DELETE' THEN
|
||||
target_portfolio_game_ids := ARRAY[OLD.portfolio_game_id];
|
||||
ELSIF TG_OP = 'INSERT' THEN
|
||||
target_portfolio_game_ids := ARRAY[NEW.portfolio_game_id];
|
||||
ELSE
|
||||
target_portfolio_game_id := OLD.portfolio_game_id;
|
||||
target_portfolio_game_ids := ARRAY[OLD.portfolio_game_id, NEW.portfolio_game_id];
|
||||
END IF;
|
||||
|
||||
IF current_setting('transaction_isolation') <> 'read committed' THEN
|
||||
@@ -73,24 +78,33 @@ BEGIN
|
||||
USING ERRCODE = '0A000';
|
||||
END IF;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM portfolio_games pg
|
||||
WHERE pg.id = target_portfolio_game_id
|
||||
AND pg.is_public = true
|
||||
AND (
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM portfolio_game_sessions pgs
|
||||
WHERE pgs.portfolio_game_id = target_portfolio_game_id
|
||||
)
|
||||
OR NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM portfolio_game_masters pgm
|
||||
WHERE pgm.portfolio_game_id = target_portfolio_game_id
|
||||
)
|
||||
SELECT pg.id
|
||||
INTO target_portfolio_game_id
|
||||
FROM portfolio_games pg
|
||||
WHERE pg.id = ANY(target_portfolio_game_ids)
|
||||
AND pg.is_public = true
|
||||
AND (
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM portfolio_game_sessions pgs
|
||||
WHERE pgs.portfolio_game_id = pg.id
|
||||
)
|
||||
) THEN
|
||||
OR EXISTS (
|
||||
SELECT 1
|
||||
FROM portfolio_game_sessions pgs
|
||||
JOIN sessions s ON s.id = pgs.session_id
|
||||
WHERE pgs.portfolio_game_id = pg.id
|
||||
AND s.scheduled_at >= now()
|
||||
)
|
||||
OR NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM portfolio_game_masters pgm
|
||||
WHERE pgm.portfolio_game_id = pg.id
|
||||
)
|
||||
)
|
||||
LIMIT 1;
|
||||
|
||||
IF target_portfolio_game_id IS NOT NULL THEN
|
||||
RAISE EXCEPTION
|
||||
'published portfolio game % must have at least one linked session and at least one linked master',
|
||||
target_portfolio_game_id
|
||||
@@ -101,6 +115,32 @@ BEGIN
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION unpublish_public_portfolio_games_for_future_session()
|
||||
RETURNS TRIGGER
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF OLD.scheduled_at IS DISTINCT FROM NEW.scheduled_at
|
||||
AND NEW.scheduled_at >= now() THEN
|
||||
UPDATE portfolio_games pg
|
||||
SET is_public = false,
|
||||
updated_at = now()
|
||||
FROM portfolio_game_sessions pgs
|
||||
WHERE pgs.portfolio_game_id = pg.id
|
||||
AND pgs.session_id = NEW.id
|
||||
AND pg.is_public = true;
|
||||
END IF;
|
||||
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE CONSTRAINT TRIGGER trg_sessions_unpublish_public_portfolio_games_for_future_reschedule
|
||||
AFTER UPDATE OF scheduled_at ON sessions
|
||||
DEFERRABLE INITIALLY DEFERRED
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION unpublish_public_portfolio_games_for_future_session();
|
||||
|
||||
CREATE CONSTRAINT TRIGGER trg_portfolio_games_validate_required_links
|
||||
AFTER INSERT OR UPDATE OF is_public ON portfolio_games
|
||||
DEFERRABLE INITIALLY DEFERRED
|
||||
@@ -108,7 +148,7 @@ FOR EACH ROW
|
||||
EXECUTE FUNCTION validate_public_portfolio_game_required_links();
|
||||
|
||||
CREATE CONSTRAINT TRIGGER trg_portfolio_game_sessions_validate_required_links
|
||||
AFTER DELETE OR UPDATE OF portfolio_game_id ON portfolio_game_sessions
|
||||
AFTER INSERT OR DELETE OR UPDATE OF portfolio_game_id, session_id ON portfolio_game_sessions
|
||||
DEFERRABLE INITIALLY DEFERRED
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION validate_public_portfolio_game_required_links();
|
||||
|
||||
Reference in New Issue
Block a user