Skip to content

Commit

Permalink
chore(rethinkdb): TeamMember: Phase 3 (#10003)
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Krick <[email protected]>
  • Loading branch information
mattkrick authored Jul 24, 2024
1 parent 0bb8ead commit 73a5881
Show file tree
Hide file tree
Showing 46 changed files with 339 additions and 561 deletions.
4 changes: 2 additions & 2 deletions codegen.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
"NotifyTaskInvolves": "../../database/types/NotificationTaskInvolves#default",
"NotifyTeamArchived": "../../database/types/NotificationTeamArchived#default",
"Organization": "./types/Organization#OrganizationSource",
"OrganizationUser": "../../postgres/types/index#OrganizationUser",
"OrganizationUser": "../../postgres/types/index#OrganizationUser as OrganizationUserDB",
"PokerMeeting": "../../database/types/MeetingPoker#default as MeetingPoker",
"PokerMeetingMember": "../../database/types/MeetingPokerMeetingMember#default as PokerMeetingMemberDB",
"PokerTemplate": "../../database/types/PokerTemplate#default as PokerTemplateDB",
Expand Down Expand Up @@ -145,7 +145,7 @@
"TeamHealthPhase": "./types/TeamHealthPhase#TeamHealthPhaseSource",
"TeamHealthStage": "./types/TeamHealthStage#TeamHealthStageSource",
"TeamInvitation": "../../database/types/TeamInvitation#default",
"TeamMember": "../../database/types/TeamMember#default as TeamMemberDB",
"TeamMember": "../../postgres/types/index#TeamMember as TeamMember",
"TeamMemberIntegrationAuthWebhook": "../../postgres/queries/getTeamMemberIntegrationAuth#TeamMemberIntegrationAuth",
"TeamMemberIntegrationAuthOAuth1": "../../postgres/queries/getTeamMemberIntegrationAuth#TeamMemberIntegrationAuth",
"TeamMemberIntegrationAuthOAuth2": "../../postgres/queries/getTeamMemberIntegrationAuth#TeamMemberIntegrationAuth",
Expand Down
5 changes: 0 additions & 5 deletions packages/server/database/rethinkDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {MasterPool, r} from 'rethinkdb-ts'
import SlackAuth from '../database/types/SlackAuth'
import SlackNotification from '../database/types/SlackNotification'
import TeamInvitation from '../database/types/TeamInvitation'
import TeamMember from '../database/types/TeamMember'
import {AnyMeeting, AnyMeetingSettings, AnyMeetingTeamMember} from '../postgres/types/Meeting'
import {ScheduledJobUnion} from '../types/custom'
import getRethinkConfig from './getRethinkConfig'
Expand Down Expand Up @@ -156,10 +155,6 @@ export type RethinkSchema = {
type: TeamInvitation
index: 'email' | 'teamId' | 'token'
}
TeamMember: {
type: TeamMember
index: 'teamId' | 'userId'
}
TemplateDimension: {
type: TemplateDimension
index: 'teamId' | 'templateId' | 'scaleId'
Expand Down
55 changes: 0 additions & 55 deletions packages/server/database/types/TeamMember.ts

This file was deleted.

17 changes: 17 additions & 0 deletions packages/server/dataloader/foreignKeyLoaderMakers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ export const teamsByOrgIds = foreignKeyLoaderMaker('teams', 'orgId', (orgIds) =>
selectTeams().where('orgId', 'in', orgIds).where('isArchived', '=', false).execute()
)

export const teamMembersByTeamId = foreignKeyLoaderMaker('teamMembers', 'teamId', (teamIds) =>
getKysely()
.selectFrom('TeamMember')
.selectAll()
.where('teamId', 'in', teamIds)
.where('isNotRemoved', '=', true)
.execute()
)

export const teamMembersByUserId = foreignKeyLoaderMaker('teamMembers', 'userId', (userIds) =>
getKysely()
.selectFrom('TeamMember')
.selectAll()
.where('userId', 'in', userIds)
.where('isNotRemoved', '=', true)
.execute()
)
export const discussionsByMeetingId = foreignKeyLoaderMaker(
'discussions',
'meetingId',
Expand Down
4 changes: 4 additions & 0 deletions packages/server/dataloader/primaryKeyLoaderMakers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,7 @@ export const saml = primaryKeyLoaderMaker((ids: readonly string[]) => {
export const organizationUsers = primaryKeyLoaderMaker((ids: readonly string[]) => {
return getKysely().selectFrom('OrganizationUser').selectAll().where('id', 'in', ids).execute()
})

export const teamMembers = primaryKeyLoaderMaker((ids: readonly string[]) => {
return getKysely().selectFrom('TeamMember').selectAll().where('id', 'in', ids).execute()
})
28 changes: 0 additions & 28 deletions packages/server/dataloader/rethinkForeignKeyLoaderMakers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,31 +221,3 @@ export const teamInvitationsByTeamId = new RethinkForeignKeyLoaderMaker(
.run()
}
)

export const teamMembersByTeamId = new RethinkForeignKeyLoaderMaker(
'teamMembers',
'teamId',
async (teamIds) => {
// tasksByUserId is expensive since we have to look up each team to check the team archive status
const r = await getRethink()
return r
.table('TeamMember')
.getAll(r.args(teamIds), {index: 'teamId'})
.filter({isNotRemoved: true})
.run()
}
)

export const teamMembersByUserId = new RethinkForeignKeyLoaderMaker(
'teamMembers',
'userId',
async (userIds) => {
// tasksByUserId is expensive since we have to look up each team to check the team archive status
const r = await getRethink()
return r
.table('TeamMember')
.getAll(r.args(userIds), {index: 'userId'})
.filter({isNotRemoved: true})
.run()
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,5 @@ export const slackAuths = new RethinkPrimaryKeyLoaderMaker('SlackAuth')
export const slackNotifications = new RethinkPrimaryKeyLoaderMaker('SlackNotification')
export const suggestedActions = new RethinkPrimaryKeyLoaderMaker('SuggestedAction')
export const tasks = new RethinkPrimaryKeyLoaderMaker('Task')
export const teamMembers = new RethinkPrimaryKeyLoaderMaker('TeamMember')
export const teamInvitations = new RethinkPrimaryKeyLoaderMaker('TeamInvitation')
export const templateDimensions = new RethinkPrimaryKeyLoaderMaker('TemplateDimension')
10 changes: 6 additions & 4 deletions packages/server/graphql/mutations/archiveTeam.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import {GraphQLID, GraphQLNonNull, GraphQLObjectType} from 'graphql'
import {SubscriptionChannel} from 'parabol-client/types/constEnums'
import TeamMemberId from '../../../client/shared/gqlIds/TeamMemberId'
import {maybeRemoveRestrictions} from '../../billing/helpers/teamLimitsCheck'
import getRethink from '../../database/rethinkDriver'
import NotificationTeamArchived from '../../database/types/NotificationTeamArchived'
import removeMeetingTemplatesForTeam from '../../postgres/queries/removeMeetingTemplatesForTeam'
import safeArchiveTeam from '../../safeMutations/safeArchiveTeam'
import {analytics} from '../../utils/analytics/analytics'
import {getUserId, isSuperUser, isTeamLead, isUserOrgAdmin} from '../../utils/authorization'
import {getUserId, isSuperUser, isUserOrgAdmin} from '../../utils/authorization'
import publish from '../../utils/publish'
import standardError from '../../utils/standardError'
import {GQLContext} from '../graphql'
Expand Down Expand Up @@ -35,13 +36,14 @@ export default {

// AUTH
const viewerId = getUserId(authToken)
const [teamLead, viewer, teamToArchive] = await Promise.all([
isTeamLead(viewerId, teamId, dataLoader),
const [teamMember, viewer, teamToArchive] = await Promise.all([
dataLoader.get('teamMembers').load(TeamMemberId.join(teamId, viewerId)),
dataLoader.get('users').loadNonNull(viewerId),
dataLoader.get('teams').loadNonNull(teamId)
])
const isTeamLead = teamMember?.isLead
const isOrgAdmin = await isUserOrgAdmin(viewerId, teamToArchive.orgId, dataLoader)
if (!teamLead && !isSuperUser(authToken) && !isOrgAdmin) {
if (!isTeamLead && !isSuperUser(authToken) && !isOrgAdmin) {
return standardError(new Error('Not team lead or org admin'), {userId: viewerId})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import TimelineEventCreatedTeam from '../../../database/types/TimelineEventCreat
import {DataLoaderInstance} from '../../../dataloader/RootDataLoader'
import getKysely from '../../../postgres/getKysely'
import IUser from '../../../postgres/types/IUser'
import insertNewTeamMember from '../../../safeMutations/insertNewTeamMember'

interface ValidNewTeam {
id: string
Expand Down Expand Up @@ -68,9 +67,7 @@ export default async function createTeamAndLeader(
.values(timelineEvent)
.execute(),
// add meeting settings
r.table('MeetingSettings').insert(meetingSettings).run(),
// denormalize common fields to team member
insertNewTeamMember(user, teamId, dataLoader)
r.table('MeetingSettings').insert(meetingSettings).run()
])
dataLoader.clearAll(['teams', 'users', 'teamMembers', 'timelineEvents', 'meetingSettings'])
}
12 changes: 1 addition & 11 deletions packages/server/graphql/mutations/helpers/removeTeamMember.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,12 @@ const removeTeamMember = async (
r.table('Task').getAll(teamId, {index: 'teamId'}).delete()
])
} else if (isLead) {
// assign new leader, remove old leader flag
await pg
.updateTable('TeamMember')
.set(({not}) => ({isLead: not('isLead')}))
.where('id', 'in', [teamMemberId, teamLeader.id])
.execute()
// assign new leader, remove old leader flag
await r({
newTeamLead: r.table('TeamMember').get(teamLeader.id).update({
isLead: true
}),
oldTeamLead: r.table('TeamMember').get(teamMemberId).update({isLead: false})
}).run()
}

await pg
Expand All @@ -68,10 +62,6 @@ const removeTeamMember = async (
.execute()
// assign active tasks to the team lead
const {integratedTasksToArchive, reassignedTasks} = await r({
teamMember: r.table('TeamMember').get(teamMemberId).update({
isNotRemoved: false,
updatedAt: now
}),
integratedTasksToArchive: r
.table('Task')
.getAll(userId, {index: 'userId'})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Meeting from '../../../database/types/Meeting'
import MeetingMember from '../../../database/types/MeetingMember'
import TeamMember from '../../../database/types/TeamMember'
import {TeamMember} from '../../../postgres/types'
import {analytics} from '../../../utils/analytics/analytics'
import {DataLoaderWorker} from '../../graphql'

Expand Down
4 changes: 2 additions & 2 deletions packages/server/graphql/mutations/joinMeeting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import Meeting from '../../database/types/Meeting'
import MeetingRetrospective from '../../database/types/MeetingRetrospective'
import PokerMeetingMember from '../../database/types/PokerMeetingMember'
import RetroMeetingMember from '../../database/types/RetroMeetingMember'
import TeamMember from '../../database/types/TeamMember'
import TeamPromptMeetingMember from '../../database/types/TeamPromptMeetingMember'
import TeamPromptResponseStage from '../../database/types/TeamPromptResponseStage'
import UpdatesStage from '../../database/types/UpdatesStage'
import insertDiscussions from '../../postgres/queries/insertDiscussions'
import {TeamMember} from '../../postgres/types'
import {analytics} from '../../utils/analytics/analytics'
import {getUserId, isTeamMember} from '../../utils/authorization'
import getPhase from '../../utils/getPhase'
Expand Down Expand Up @@ -82,7 +82,7 @@ const joinMeeting = {
return {error: {message: 'Not on the team'}}
}
const teamMemberId = toTeamMemberId(teamId, viewerId)
const teamMember = await dataLoader.get('teamMembers').load(teamMemberId)
const teamMember = await dataLoader.get('teamMembers').loadNonNull(teamMemberId)
const meetingMember = createMeetingMember(meeting, teamMember)
const {errors} = await r.table('MeetingMember').insert(meetingMember).run()
// if this is called concurrently, only 1 will be error free
Expand Down
10 changes: 0 additions & 10 deletions packages/server/graphql/mutations/promoteToTeamLead.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {GraphQLID, GraphQLNonNull} from 'graphql'
import {SubscriptionChannel} from 'parabol-client/types/constEnums'
import TeamMemberId from '../../../client/shared/gqlIds/TeamMemberId'
import getRethink from '../../database/rethinkDriver'
import getKysely from '../../postgres/getKysely'
import {getUserId, isSuperUser, isUserOrgAdmin} from '../../utils/authorization'
import publish from '../../utils/publish'
Expand All @@ -27,7 +26,6 @@ export default {
{teamId, userId}: {teamId: string; userId: string},
{authToken, dataLoader, socketId: mutatorId}: GQLContext
) {
const r = await getRethink()
const pg = getKysely()
const operationId = dataLoader.share()
const subOptions = {mutatorId, operationId}
Expand Down Expand Up @@ -61,14 +59,6 @@ export default {
.where('id', 'in', [oldLeadTeamMemberId, promoteeOnTeam.id])
.execute()
dataLoader.clearAll('teamMembers')
await r({
teamLead: r.table('TeamMember').get(oldLeadTeamMemberId).update({
isLead: false
}),
promotee: r.table('TeamMember').get(promoteeOnTeam.id).update({
isLead: true
})
}).run()

const data = {teamId, oldLeaderId: oldLeadTeamMemberId, newLeaderId: promoteeOnTeam.id}
publish(SubscriptionChannel.TEAM, teamId, 'PromoteToTeamLeadPayload', data, subOptions)
Expand Down
8 changes: 5 additions & 3 deletions packages/server/graphql/mutations/removeTeamMember.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {GraphQLID, GraphQLNonNull, GraphQLObjectType} from 'graphql'
import {SubscriptionChannel} from 'parabol-client/types/constEnums'
import fromTeamMemberId from 'parabol-client/utils/relay/fromTeamMemberId'
import {getUserId, isTeamLead, isUserOrgAdmin} from '../../utils/authorization'
import TeamMemberId from '../../../client/shared/gqlIds/TeamMemberId'
import {getUserId, isUserOrgAdmin} from '../../utils/authorization'
import publish from '../../utils/publish'
import standardError from '../../utils/standardError'
import {GQLContext} from '../graphql'
Expand Down Expand Up @@ -31,10 +32,11 @@ export default {
const viewerId = getUserId(authToken)
const {userId, teamId} = fromTeamMemberId(teamMemberId)
const team = await dataLoader.get('teams').loadNonNull(teamId)
const [isOrgAdmin, isViewerTeamLead] = await Promise.all([
const [isOrgAdmin, teamMember] = await Promise.all([
isUserOrgAdmin(viewerId, team.orgId, dataLoader),
isTeamLead(viewerId, teamId, dataLoader)
dataLoader.get('teamMembers').loadNonNull(TeamMemberId.join(teamId, viewerId))
])
const isViewerTeamLead = teamMember?.isLead
const isSelf = viewerId === userId
if (!isSelf) {
if (!isOrgAdmin && !isViewerTeamLead) {
Expand Down
7 changes: 1 addition & 6 deletions packages/server/graphql/mutations/setPokerSpectate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const setPokerSpectate = {
const r = await getRethink()
const pg = getKysely()
const viewerId = getUserId(authToken)
const now = new Date()
const operationId = dataLoader.share()
const subOptions = {mutatorId, operationId}

Expand Down Expand Up @@ -68,11 +67,7 @@ const setPokerSpectate = {
.where('id', '=', teamMemberId)
.execute()
await r({
meetingMember: r.table('MeetingMember').get(meetingMemberId).update({isSpectating}),
teamMember: r
.table('TeamMember')
.get(teamMemberId)
.update({isSpectatingPoker: isSpectating, updatedAt: now})
meetingMember: r.table('MeetingMember').get(meetingMemberId).update({isSpectating})
}).run()
dataLoader.clearAll('teamMembers')
// mutate the dataLoader cache
Expand Down
2 changes: 1 addition & 1 deletion packages/server/graphql/mutations/startSprintPoker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export default {
}

const teamMemberId = toTeamMemberId(teamId, viewerId)
const teamMember = await dataLoader.get('teamMembers').load(teamMemberId)
const teamMember = await dataLoader.get('teamMembers').loadNonNull(teamMemberId)
const {isSpectatingPoker} = teamMember
const updates = {
lastMeetingType: meetingType
Expand Down
15 changes: 0 additions & 15 deletions packages/server/graphql/mutations/toggleTeamDrawer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {GraphQLID, GraphQLNonNull} from 'graphql'
import getRethink from '../../database/rethinkDriver'
import {RValue} from '../../database/stricterR'
import getKysely from '../../postgres/getKysely'
import {getUserId, isTeamMember} from '../../utils/authorization'
import standardError from '../../utils/standardError'
Expand All @@ -27,7 +25,6 @@ const toggleTeamDrawer = {
{teamId, teamDrawerType}: {teamId: string; teamDrawerType: TeamDrawer | null},
{authToken}: GQLContext
) => {
const r = await getRethink()
const pg = getKysely()
const viewerId = getUserId(authToken)

Expand All @@ -47,18 +44,6 @@ const toggleTeamDrawer = {
}))
.where('id', '=', viewerTeamMemberId)
.execute()
await r
.table('TeamMember')
.get(viewerTeamMemberId)
.update((teamMember: RValue) => ({
openDrawer: r.branch(
teamMember('openDrawer').default(null).eq(teamDrawerType),
null,
teamDrawerType
)
}))
.run()

return {teamMemberId: viewerTeamMemberId}
}
}
Expand Down
Loading

0 comments on commit 73a5881

Please sign in to comment.