Skip to content

Commit

Permalink
write to PG
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Krick <matt.krick@gmail.com>
  • Loading branch information
mattkrick committed Aug 14, 2024
1 parent 8241c14 commit 4ead218
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ const AgendaListAndInput = (props: Props) => {
agendaItems {
id
content
sortOrder
...AgendaList_agendaItems
}
}
Expand Down
21 changes: 21 additions & 0 deletions packages/server/dataloader/foreignKeyLoaderMakers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import getKysely from '../postgres/getKysely'
import {getTeamPromptResponsesByMeetingIds} from '../postgres/queries/getTeamPromptResponsesByMeetingIds'
import {
selectAgendaItems,
selectOrganizations,
selectRetroReflections,
selectSuggestedAction,
Expand Down Expand Up @@ -170,3 +171,23 @@ export const teamPromptResponsesByMeetingId = foreignKeyLoaderMaker(
'meetingId',
getTeamPromptResponsesByMeetingIds
)

export const _pgagendaItemsByTeamId = foreignKeyLoaderMaker(
'_pgagendaItems',
'teamId',
async (teamIds) => {
return selectAgendaItems()
.where('teamId', 'in', teamIds)
.where('isActive', '=', true)
.orderBy('sortOrder')
.execute()
}
)

export const _pgagendaItemsByMeetingId = foreignKeyLoaderMaker(
'_pgagendaItems',
'meetingId',
async (meetingIds) => {
return selectAgendaItems().where('meetingId', 'in', meetingIds).orderBy('sortOrder').execute()
}
)
5 changes: 5 additions & 0 deletions packages/server/dataloader/primaryKeyLoaderMakers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import getMeetingTemplatesByIds from '../postgres/queries/getMeetingTemplatesByI
import getTemplateRefsByIds from '../postgres/queries/getTemplateRefsByIds'
import {getUsersByIds} from '../postgres/queries/getUsersByIds'
import {
selectAgendaItems,
selectMeetingSettings,
selectOrganizations,
selectRetroReflections,
Expand Down Expand Up @@ -90,3 +91,7 @@ export const suggestedActions = primaryKeyLoaderMaker((ids: readonly string[]) =
export const meetingSettings = primaryKeyLoaderMaker((ids: readonly string[]) => {
return selectMeetingSettings().where('id', 'in', ids).execute()
})

export const _pgagendaItems = primaryKeyLoaderMaker((ids: readonly string[]) => {
return selectAgendaItems().where('id', 'in', ids).execute()
})
21 changes: 19 additions & 2 deletions packages/server/graphql/mutations/addAgendaItem.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {GraphQLNonNull} from 'graphql'
import {SubscriptionChannel} from 'parabol-client/types/constEnums'
import makeAgendaItemSchema from 'parabol-client/validation/makeAgendaItemSchema'
import {positionAfter} from '../../../client/shared/sortOrder'
import getRethink from '../../database/rethinkDriver'
import AgendaItem, {AgendaItemInput} from '../../database/types/AgendaItem'
import generateUID from '../../generateUID'
import getKysely from '../../postgres/getKysely'
import {analytics} from '../../utils/analytics/analytics'
import {getUserId, isTeamMember} from '../../utils/authorization'
import publish from '../../utils/publish'
Expand Down Expand Up @@ -45,18 +47,33 @@ export default {
}

// RESOLUTION
const teamAgendaItems = await dataLoader.get('agendaItemsByTeamId').load(teamId)
const lastAgendaItem = teamAgendaItems.at(-1)
const lastSortOrder = lastAgendaItem?.sortOrder ? String(lastAgendaItem.sortOrder) : ''
// this is just during the migration of AgendaItem table
const sortOrder = positionAfter(lastSortOrder)
const agendaItemId = `${teamId}::${generateUID()}`
await r
.table('AgendaItem')
.insert(
new AgendaItem({
...validNewAgendaItem,
id: agendaItemId,
teamId
} as AgendaItemInput)
)
.run()

await getKysely()
.insertInto('AgendaItem')
.values({
id: agendaItemId,
content: newAgendaItem.content,
meetingId: newAgendaItem.meetingId,
pinned: newAgendaItem.pinned,
sortOrder,
teamId,
teamMemberId: newAgendaItem.teamMemberId
})
.execute()
const meetingId = await addAgendaItemToActiveActionMeeting(agendaItemId, teamId, dataLoader)
analytics.addedAgendaItem(viewer, teamId, meetingId)
const data = {agendaItemId, meetingId}
Expand Down
44 changes: 31 additions & 13 deletions packages/server/graphql/mutations/endCheckIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import {SubscriptionChannel} from 'parabol-client/types/constEnums'
import {AGENDA_ITEMS, DONE, LAST_CALL} from 'parabol-client/utils/constants'
import getMeetingPhase from 'parabol-client/utils/getMeetingPhase'
import findStageById from 'parabol-client/utils/meetings/findStageById'
import {positionAfter} from '../../../client/shared/sortOrder'
import {checkTeamsLimit} from '../../billing/helpers/teamLimitsCheck'
import getRethink from '../../database/rethinkDriver'
import {RDatum} from '../../database/stricterR'
import AgendaItem from '../../database/types/AgendaItem'
import MeetingAction from '../../database/types/MeetingAction'
import Task from '../../database/types/Task'
import TimelineEventCheckinComplete from '../../database/types/TimelineEventCheckinComplete'
import {DataLoaderInstance} from '../../dataloader/RootDataLoader'
import generateUID from '../../generateUID'
import getKysely from '../../postgres/getKysely'
import archiveTasksForDB from '../../safeMutations/archiveTasksForDB'
Expand Down Expand Up @@ -61,8 +63,14 @@ const updateTaskSortOrders = async (userIds: string[], tasks: SortOrderTask[]) =
return tasks
}

const clearAgendaItems = async (teamId: string) => {
const clearAgendaItems = async (teamId: string, dataLoader: DataLoaderInstance) => {
await getKysely()
.updateTable('AgendaItem')
.set({isActive: false})
.where('teamId', '=', teamId)
.execute()
const r = await getRethink()
dataLoader.clearAll('agendaItems')
return r
.table('AgendaItem')
.getAll(teamId, {index: 'teamId'})
Expand All @@ -72,16 +80,15 @@ const clearAgendaItems = async (teamId: string) => {
.run()
}

const getPinnedAgendaItems = async (teamId: string) => {
const r = await getRethink()
return r
.table('AgendaItem')
.getAll(teamId, {index: 'teamId'})
.filter({isActive: true, pinned: true})
.run()
const getPinnedAgendaItems = async (teamId: string, dataLoader: DataLoaderInstance) => {
const agendaItems = await dataLoader.get('agendaItemsByTeamId').load(teamId)
return agendaItems.filter((agendaItem) => agendaItem.pinned)
}

const clonePinnedAgendaItems = async (pinnedAgendaItems: AgendaItem[]) => {
const clonePinnedAgendaItems = async (
pinnedAgendaItems: AgendaItem[],
dataLoader: DataLoaderInstance
) => {
const r = await getRethink()
const clonedPins = pinnedAgendaItems.map((agendaItem) => {
const agendaItemId = `${agendaItem.teamId}::${generateUID()}`
Expand All @@ -96,6 +103,17 @@ const clonePinnedAgendaItems = async (pinnedAgendaItems: AgendaItem[]) => {
})
})
await r.table('AgendaItem').insert(clonedPins).run()
let curSortOrder = ''
const pgClonedPins = clonedPins.map((agendaItems) => {
const sortOrder = positionAfter(curSortOrder)
curSortOrder = sortOrder
return {
...agendaItems,
sortOrder
}
})
await getKysely().insertInto('AgendaItem').values(pgClonedPins).execute()
dataLoader.clearAll('agendaItems')
}

const summarizeCheckInMeeting = async (meeting: MeetingAction, dataLoader: DataLoaderWorker) => {
Expand All @@ -120,20 +138,20 @@ const summarizeCheckInMeeting = async (meeting: MeetingAction, dataLoader: DataL
.filter({status: DONE})
.filter((task: RDatum) => task('tags').contains('archived').not())
.run(),
r.table('AgendaItem').getAll(teamId, {index: 'teamId'}).filter({isActive: true}).run()
dataLoader.get('agendaItemsByTeamId').load(teamId)
])

const agendaItemPhase = getPhase(phases, 'agendaitems')
const {stages} = agendaItemPhase
const discussionIds = stages.map((stage) => stage.discussionId)
const userIds = meetingMembers.map(({userId}) => userId)
const meetingPhase = getMeetingPhase(phases)
const pinnedAgendaItems = await getPinnedAgendaItems(teamId)
const pinnedAgendaItems = await getPinnedAgendaItems(teamId, dataLoader)
const isKill = !!(meetingPhase && ![AGENDA_ITEMS, LAST_CALL].includes(meetingPhase.phaseType))
if (!isKill) await clearAgendaItems(teamId)
if (!isKill) await clearAgendaItems(teamId, dataLoader)
await Promise.all([
isKill ? undefined : archiveTasksForDB(doneTasks, meetingId),
isKill ? undefined : clonePinnedAgendaItems(pinnedAgendaItems),
isKill ? undefined : clonePinnedAgendaItems(pinnedAgendaItems, dataLoader),
updateTaskSortOrders(userIds, tasks),
r
.table('NewMeeting')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import getRethink from '../../../database/rethinkDriver'
import AgendaItemsStage from '../../../database/types/AgendaItemsStage'
import MeetingAction from '../../../database/types/MeetingAction'
import getKysely from '../../../postgres/getKysely'
import insertDiscussions from '../../../postgres/queries/insertDiscussions'
import getPhase from '../../../utils/getPhase'
import {DataLoaderWorker} from '../../graphql'
Expand Down Expand Up @@ -47,6 +48,7 @@ const addAgendaItemToActiveActionMeeting = async (
})
.run(),
r.table('AgendaItem').get(agendaItemId).update({meetingId: meetingId}).run(),
getKysely().updateTable('AgendaItem').set({meetingId}).where('id', '=', agendaItemId).execute(),
insertDiscussions([
{
id: discussionId,
Expand Down
12 changes: 5 additions & 7 deletions packages/server/graphql/mutations/helpers/removeTeamMember.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,11 @@ const removeTeamMember = async (

const archivedTasks = await archiveTasksForDB(integratedTasksToArchive)
const archivedTaskIds = archivedTasks.map(({id}) => id)
const agendaItemIds = await r
.table('AgendaItem')
.getAll(teamId, {index: 'teamId'})
.filter((row: RDatum) => row('teamMemberId').eq(teamMemberId))
.getField('id')
.run()

const teamAgendaItems = await dataLoader.get('agendaItemsByTeamId').load(teamId)
const agendaItemIds = teamAgendaItems
.filter((agendaItem) => agendaItem.teamMemberId === teamMemberId)
.map(({id}) => id)
dataLoader.clearAll('agendaItems')
// if a new meeting was currently running, remove them from it
const filterFn = (stage: CheckInStage | UpdatesStage | EstimateStage | AgendaItemsStage) =>
(stage as CheckInStage | UpdatesStage).teamMemberId === teamMemberId ||
Expand Down
7 changes: 7 additions & 0 deletions packages/server/graphql/mutations/removeAgendaItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {GraphQLID, GraphQLNonNull} from 'graphql'
import {SubscriptionChannel} from 'parabol-client/types/constEnums'
import getRethink from '../../database/rethinkDriver'
import AgendaItemsStage from '../../database/types/AgendaItemsStage'
import getKysely from '../../postgres/getKysely'
import {getUserId, isTeamMember} from '../../utils/authorization'
import publish from '../../utils/publish'
import standardError from '../../utils/standardError'
Expand Down Expand Up @@ -42,6 +43,12 @@ export default {
.update({isActive: false}, {returnChanges: true})('changes')(0)('old_val')
.default(null)
.run()
await getKysely()
.updateTable('AgendaItem')
.set({isActive: false})
.where('id', '=', agendaItemId)
.returning('id')
.execute()
if (!agendaItem) {
return standardError(new Error('Agenda item not found'), {userId: viewerId})
}
Expand Down
24 changes: 24 additions & 0 deletions packages/server/graphql/mutations/updateAgendaItem.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {GraphQLNonNull} from 'graphql'
import {SubscriptionChannel} from 'parabol-client/types/constEnums'
import makeUpdateAgendaItemSchema from 'parabol-client/validation/makeUpdateAgendaItemSchema'
import {getSortOrder} from '../../../client/shared/sortOrder'
import getRethink from '../../database/rethinkDriver'
import AgendaItemsStage from '../../database/types/AgendaItemsStage'
import getKysely from '../../postgres/getKysely'
import {getUserId, isTeamMember} from '../../utils/authorization'
import getPhase from '../../utils/getPhase'
import publish from '../../utils/publish'
Expand All @@ -27,6 +29,7 @@ export default {
) {
const now = new Date()
const r = await getRethink()
const pg = getKysely()
const operationId = dataLoader.share()
const subOptions = {mutatorId, operationId}
const viewerId = getUserId(authToken)
Expand All @@ -49,6 +52,8 @@ export default {
}

// RESOLUTION
const oldAgendaItems = await dataLoader.get('agendaItemsByTeamId').load(teamId)
const fromIdx = oldAgendaItems.findIndex((agendaItem) => agendaItem.id === id)
await r
.table('AgendaItem')
.get(id)
Expand All @@ -57,6 +62,25 @@ export default {
updatedAt: now
})
.run()
dataLoader.clearAll('agendaItems')
if (doc.sortOrder !== null && doc.sortOrder !== undefined) {
const nextAgendaItems = await dataLoader.get('agendaItemsByTeamId').load(teamId)
const pgagendaItems = await dataLoader.get('_pgagendaItemsByTeamId').load(teamId)
const toIdx = nextAgendaItems.findIndex((agendaItem) => agendaItem.id === id)
const pgSortOrder = getSortOrder(pgagendaItems, fromIdx, toIdx)
await pg
.updateTable('AgendaItem')
.set({sortOrder: pgSortOrder})
.where('id', '=', id)
.execute()
} else {
await pg
.updateTable('AgendaItem')
.set({pinned: doc.pinned, content: doc.content})
.where('id', '=', id)
.execute()
}

const activeMeetings = await dataLoader.get('activeMeetingsByTeamId').load(teamId)
const actionMeeting = activeMeetings.find(
(activeMeeting) => activeMeeting.meetingType === 'action'
Expand Down
8 changes: 7 additions & 1 deletion packages/server/graphql/public/mutations/startCheckIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import getRethink from '../../../database/rethinkDriver'
import ActionMeetingMember from '../../../database/types/ActionMeetingMember'
import MeetingAction from '../../../database/types/MeetingAction'
import generateUID from '../../../generateUID'
import getKysely from '../../../postgres/getKysely'
import updateTeamByTeamId from '../../../postgres/queries/updateTeamByTeamId'
import {MeetingTypeEnum} from '../../../postgres/types/Meeting'
import {analytics} from '../../../utils/analytics/analytics'
Expand Down Expand Up @@ -89,7 +90,12 @@ const startCheckIn: MutationResolvers['startCheckIn'] = async (
.insert(new ActionMeetingMember({meetingId, userId: viewerId, teamId}))
.run(),
updateTeamByTeamId(updates, teamId),
r.table('AgendaItem').getAll(r.args(agendaItemIds)).update({meetingId}).run()
r.table('AgendaItem').getAll(r.args(agendaItemIds)).update({meetingId}).run(),
getKysely()
.updateTable('AgendaItem')
.set({meetingId})
.where('id', 'in', agendaItemIds)
.execute()
])
IntegrationNotifier.startMeeting(dataLoader, meetingId, teamId)
analytics.meetingStarted(viewer, meeting)
Expand Down
2 changes: 2 additions & 0 deletions packages/server/postgres/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,5 @@ export const selectMeetingSettings = () =>
fn<JiraSearchQuery[]>('to_json', ['jiraSearchQueries']).as('jiraSearchQueries'),
fn<NewMeetingPhaseTypeEnum[]>('to_json', ['phaseTypes']).as('phaseTypes')
])

export const selectAgendaItems = () => getKysely().selectFrom('AgendaItem').selectAll()

0 comments on commit 4ead218

Please sign in to comment.