diff --git a/packages/server/graphql/mutations/helpers/createNewMeetingPhases.ts b/packages/server/graphql/mutations/helpers/createNewMeetingPhases.ts index 1f8b8afd09c..f5f7a2e1def 100644 --- a/packages/server/graphql/mutations/helpers/createNewMeetingPhases.ts +++ b/packages/server/graphql/mutations/helpers/createNewMeetingPhases.ts @@ -1,3 +1,4 @@ +import {InsertQueryBuilder} from 'kysely' import { AGENDA_ITEMS, CHECKIN, @@ -23,6 +24,7 @@ import UpdatesPhase from '../../../database/types/UpdatesPhase' import UpdatesStage from '../../../database/types/UpdatesStage' import {DataLoaderInstance} from '../../../dataloader/RootDataLoader' import getKysely from '../../../postgres/getKysely' +import {DB} from '../../../postgres/pg' import {MeetingTypeEnum} from '../../../postgres/types/Meeting' import {NewMeetingPhase, NewMeetingStages} from '../../../postgres/types/NewMeetingPhase' import isPhaseAvailable from '../../../utils/isPhaseAvailable' @@ -84,7 +86,7 @@ const createNewMeetingPhases = async [] + const inserts = [] as InsertQueryBuilder[] const tier = getFeatureTier(team) const phases = (await Promise.all( @@ -109,19 +111,16 @@ const createNewMeetingPhases = async stage.reflectionGroupId) if (discussStages.length > 0) { - asyncSideEffects.push( - pg - .insertInto('Discussion') - .values( - discussStages.map((stage) => ({ - id: stage.discussionId, - teamId, - meetingId, - discussionTopicId: stage.reflectionGroupId, - discussionTopicType: 'reflectionGroup' - })) - ) - .execute() + inserts.push( + pg.insertInto('Discussion').values( + discussStages.map((stage) => ({ + id: stage.discussionId, + teamId, + meetingId, + discussionTopicId: stage.reflectionGroupId, + discussionTopicType: 'reflectionGroup' + })) + ) ) } return discussPhase @@ -133,19 +132,16 @@ const createNewMeetingPhases = async 0) { - asyncSideEffects.push( - pg - .insertInto('Discussion') - .values( - stages.map((stage) => ({ - id: stage.discussionId, - teamId, - meetingId, - discussionTopicId: stage.agendaItemId, - discussionTopicType: 'agendaItem' - })) - ) - .execute() + inserts.push( + pg.insertInto('Discussion').values( + stages.map((stage) => ({ + id: stage.discussionId, + teamId, + meetingId, + discussionTopicId: stage.agendaItemId, + discussionTopicType: 'agendaItem' + })) + ) ) } return agendaItemPhase @@ -163,8 +159,7 @@ const createNewMeetingPhases = async ( + const [phases, inserts] = await createNewMeetingPhases( facilitatorUserId, teamId, meetingId, @@ -51,10 +51,13 @@ const safeCreateRetrospective = async ( name }) as RetrospectiveMeeting try { - await pg - .insertInto('NewMeeting') - .values({...meeting, phases: JSON.stringify(meeting.phases)}) - .execute() + await pg.transaction().execute(async (pg) => { + await pg + .insertInto('NewMeeting') + .values({...meeting, phases: JSON.stringify(meeting.phases)}) + .execute() + await Promise.all(inserts.map((insert) => pg.executeQuery(insert))) + }) } catch (e) { // meeting already started return null diff --git a/packages/server/graphql/mutations/startSprintPoker.ts b/packages/server/graphql/mutations/startSprintPoker.ts index 3396c6921bc..296f11af878 100644 --- a/packages/server/graphql/mutations/startSprintPoker.ts +++ b/packages/server/graphql/mutations/startSprintPoker.ts @@ -115,7 +115,7 @@ export default { const meetingId = generateUID() const meetingCount = await dataLoader.get('meetingCount').load({teamId, meetingType}) - const phases = await createNewMeetingPhases( + const [phases, inserts] = await createNewMeetingPhases( viewerId, teamId, meetingId, @@ -145,10 +145,13 @@ export default { const template = await dataLoader.get('meetingTemplates').load(selectedTemplateId) const [newMeetingRes] = await Promise.allSettled([ - pg - .insertInto('NewMeeting') - .values({...meeting, phases: JSON.stringify(phases)}) - .execute(), + pg.transaction().execute(async (pg) => { + await pg + .insertInto('NewMeeting') + .values({...meeting, phases: JSON.stringify(phases)}) + .execute() + await Promise.all(inserts.map((insert) => pg.executeQuery(insert))) + }), updateMeetingTemplateLastUsedAt(selectedTemplateId, teamId) ]) if (newMeetingRes.status === 'rejected') { diff --git a/packages/server/graphql/public/mutations/startCheckIn.ts b/packages/server/graphql/public/mutations/startCheckIn.ts index eab8efe5fb5..d06c9646d90 100644 --- a/packages/server/graphql/public/mutations/startCheckIn.ts +++ b/packages/server/graphql/public/mutations/startCheckIn.ts @@ -41,7 +41,7 @@ const startCheckIn: MutationResolvers['startCheckIn'] = async ( const meetingCount = await dataLoader.get('meetingCount').load({teamId, meetingType}) const meetingId = generateUID() - const phases = await createNewMeetingPhases( + const [phases, inserts] = await createNewMeetingPhases( viewerId, teamId, meetingId, @@ -59,10 +59,13 @@ const startCheckIn: MutationResolvers['startCheckIn'] = async ( facilitatorUserId: viewerId }) as CheckInMeeting try { - await pg - .insertInto('NewMeeting') - .values({...meeting, phases: JSON.stringify(phases)}) - .execute() + await pg.transaction().execute(async (pg) => { + await pg + .insertInto('NewMeeting') + .values({...meeting, phases: JSON.stringify(phases)}) + .execute() + await Promise.all(inserts.map((insert) => pg.executeQuery(insert))) + }) } catch (e) { return {error: {message: 'Meeting already started'}} }