Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(rethinkdb): TimelineEvent: Phase 1 #9871

Merged
merged 35 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
bfa5c21
chore: read ReflectionGroups from PG
mattkrick May 29, 2024
7ac086e
Merge branch 'master' into chore/retrogroups3
mattkrick May 29, 2024
9844960
Merge branch 'master' into chore/retrogroups3
mattkrick May 30, 2024
62e123c
chore: add PG RetroReflection table
mattkrick May 30, 2024
c38f86c
chore: write to PG RetroReflection table
mattkrick Jun 3, 2024
d318560
fixup: inserts and updates
mattkrick Jun 4, 2024
16843dc
Merge branch 'master' into retroReflection-phase1e
mattkrick Jun 4, 2024
abb3bdf
fix: move to record literal types
mattkrick Jun 4, 2024
9911448
fix types
mattkrick Jun 4, 2024
af03b31
chore: migrate reflections to PG
mattkrick Jun 6, 2024
2a3c0ca
Merge branch 'master' into retroReflection-phase1e
mattkrick Jun 6, 2024
8dfa870
fix: remove hard delete of inactive groups
mattkrick Jun 6, 2024
3b48d22
Merge branch 'retroReflection-phase1e' into chore/retroReflection-phase2
mattkrick Jun 6, 2024
24da04b
fixup: remove unused var
mattkrick Jun 6, 2024
c60e502
Merge branch 'retroReflection-phase1e' into chore/retroReflection-phase2
mattkrick Jun 6, 2024
0d2c7d7
handle escape chars and commas
mattkrick Jun 6, 2024
9ef9346
chore: begin building equality checker
mattkrick Jun 6, 2024
76aeff9
fixup: account for lots of formatting in content
mattkrick Jun 7, 2024
0830c8e
Merge branch 'retroReflection-phase1e' into chore/retroReflection-phase2
mattkrick Jun 24, 2024
a12b08a
fix: rename extra spaces for conversion from plaintext to content
mattkrick Jun 24, 2024
a732657
fix: rename Reactji composite type attributes
mattkrick Jun 24, 2024
954503d
fix: constructor prop in lookup table
mattkrick Jun 25, 2024
c7775ad
handle reactji migration
mattkrick Jun 25, 2024
d53aca4
change dataloaders to pg
mattkrick Jun 25, 2024
6689e39
fix: self-review
mattkrick Jun 25, 2024
a6fd0d3
Merge branch 'master' into chore/retroReflection-phase2
mattkrick Jun 25, 2024
00964a8
Merge branch 'chore/retroReflection-phase2' into chore/retroReflectio…
mattkrick Jun 25, 2024
50ca56b
fix: migration order rename
mattkrick Jun 25, 2024
b220f22
Merge branch 'chore/retroReflection-phase2' into chore/retroReflectio…
mattkrick Jun 25, 2024
22ca4f3
chore: write to PG
mattkrick Jun 25, 2024
9dfd35c
fix: add teamid FK
mattkrick Jun 25, 2024
4fdd64d
Merge branch 'master' into chore/timeline-phase1
mattkrick Jun 26, 2024
c203ce3
write timeline event after user is created
mattkrick Jun 26, 2024
ecfaf6b
fix: create team before insert
mattkrick Jun 26, 2024
4e6bb44
fix: odd ts fixes keep popping up
mattkrick Jun 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/client/components/SelectMeetingDropdownItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const SelectMeetingDropdownItem = (props: Props) => {
history.push(`/meet/${meetingId}`)
}
//FIXME 6062: change to React.ComponentType
const IconOrSVG = meetingTypeToIcon[meetingType]
const IconOrSVG = meetingTypeToIcon[meetingType]!
const meetingPhase = getMeetingPhase(phases)
const meetingPhaseLabel = (meetingPhase && phaseLabelLookup[meetingPhase.phaseType]) || 'Complete'

Expand Down
4 changes: 2 additions & 2 deletions packages/server/dataloader/customLoaderMakers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ export const meetingSettingsByType = (parent: RootDataLoader) => {
keys.forEach((key) => {
const {meetingType} = key
types[meetingType] = types[meetingType] || []
types[meetingType].push(key.teamId)
types[meetingType]!.push(key.teamId)
})
const entries = Object.entries(types) as [MeetingTypeEnum, string[]][]
const resultsByType = await Promise.all(
Expand Down Expand Up @@ -422,7 +422,7 @@ export const meetingTemplatesByType = (parent: RootDataLoader) => {
keys.forEach((key) => {
const {meetingType} = key
types[meetingType] = types[meetingType] || []
types[meetingType].push(key.teamId)
types[meetingType]!.push(key.teamId)
})
const entries = Object.entries(types) as [MeetingTypeEnum, string[]][]
const resultsByType = await Promise.all(
Expand Down
11 changes: 10 additions & 1 deletion packages/server/graphql/mutations/archiveTimelineEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import TimelineEventCheckinComplete from 'parabol-server/database/types/Timeline
import TimelineEventRetroComplete from 'parabol-server/database/types/TimelineEventRetroComplete'
import getRethink from '../../database/rethinkDriver'
import {TimelineEventEnum} from '../../database/types/TimelineEvent'
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 @@ -57,7 +58,15 @@ const archiveTimelineEvent = {
.get('timelineEventsByMeetingId')
.load(meetingId)
const eventIds = meetingTimelineEvents.map(({id}) => id)
await r.table('TimelineEvent').getAll(r.args(eventIds)).update({isActive: false}).run()
const pg = getKysely()
await Promise.all([
pg
.updateTable('TimelineEvent')
.set({isActive: false})
.where('id', 'in', eventIds)
.execute(),
r.table('TimelineEvent').getAll(r.args(eventIds)).update({isActive: false}).run()
])
meetingTimelineEvents.map((event) => {
const {id: timelineEventId, userId} = event
publish(
Expand Down
7 changes: 6 additions & 1 deletion packages/server/graphql/mutations/endCheckIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import MeetingAction from '../../database/types/MeetingAction'
import Task from '../../database/types/Task'
import TimelineEventCheckinComplete from '../../database/types/TimelineEventCheckinComplete'
import generateUID from '../../generateUID'
import getKysely from '../../postgres/getKysely'
import archiveTasksForDB from '../../safeMutations/archiveTasksForDB'
import removeSuggestedAction from '../../safeMutations/removeSuggestedAction'
import {Logger} from '../../utils/Logger'
Expand Down Expand Up @@ -244,7 +245,11 @@ export default {
})
)
const timelineEventId = events[0]!.id
await r.table('TimelineEvent').insert(events).run()
const pg = getKysely()
await Promise.all([
pg.insertInto('TimelineEvent').values(events).execute(),
r.table('TimelineEvent').insert(events).run()
])
if (team.isOnboardTeam) {
const teamLeadUserId = await r
.table('TeamMember')
Expand Down
7 changes: 6 additions & 1 deletion packages/server/graphql/mutations/endSprintPoker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import getRethink from '../../database/rethinkDriver'
import Meeting from '../../database/types/Meeting'
import MeetingPoker from '../../database/types/MeetingPoker'
import TimelineEventPokerComplete from '../../database/types/TimelineEventPokerComplete'
import getKysely from '../../postgres/getKysely'
import {Logger} from '../../utils/Logger'
import {analytics} from '../../utils/analytics/analytics'
import {getUserId, isSuperUser, isTeamMember} from '../../utils/authorization'
Expand Down Expand Up @@ -127,7 +128,11 @@ export default {
meetingId
})
)
await r.table('TimelineEvent').insert(events).run()
const pg = getKysely()
await Promise.all([
pg.insertInto('TimelineEvent').values(events).execute(),
r.table('TimelineEvent').insert(events).run()
])

const data = {
meetingId,
Expand Down
21 changes: 15 additions & 6 deletions packages/server/graphql/mutations/helpers/bootstrapNewUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import SuggestedActionTryTheDemo from '../../../database/types/SuggestedActionTr
import TimelineEventJoinedParabol from '../../../database/types/TimelineEventJoinedParabol'
import User from '../../../database/types/User'
import generateUID from '../../../generateUID'
import getKysely from '../../../postgres/getKysely'
import getUsersbyDomain from '../../../postgres/queries/getUsersByDomain'
import insertUser from '../../../postgres/queries/insertUser'
import IUser from '../../../postgres/types/IUser'
import acceptTeamInvitation from '../../../safeMutations/acceptTeamInvitation'
import {analytics} from '../../../utils/analytics/analytics'
Expand Down Expand Up @@ -57,13 +57,22 @@ const bootstrapNewUser = async (
const hasSAMLURL = !!(await getSAMLURLFromEmail(email, dataLoader, false))
const isQualifiedForAutoJoin = (isVerified || hasSAMLURL) && isCompanyDomain
const orgIds = organizations.map(({id}) => id)

const pg = getKysely()
const [teamsWithAutoJoinRes] = await Promise.all([
isQualifiedForAutoJoin ? dataLoader.get('autoJoinTeamsByOrgId').loadMany(orgIds) : [],
insertUser({...newUser, isPatient0, featureFlags: experimentalFlags}),
r({
event: r.table('TimelineEvent').insert(joinEvent)
}).run()
pg
.with('User', (qc) =>
qc.insertInto('User').values({
...newUser,
isPatient0,
featureFlags: experimentalFlags,
identities: newUser.identities.map((identity) => JSON.stringify(identity))
})
)
.insertInto('TimelineEvent')
.values(joinEvent)
.execute(),
r.table('TimelineEvent').insert(joinEvent).run()
])

// Identify the user so user properties are set before any events are sent
Expand Down
11 changes: 7 additions & 4 deletions packages/server/graphql/mutations/helpers/createTeamAndLeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import MeetingSettingsPoker from '../../../database/types/MeetingSettingsPoker'
import MeetingSettingsRetrospective from '../../../database/types/MeetingSettingsRetrospective'
import Team from '../../../database/types/Team'
import TimelineEventCreatedTeam from '../../../database/types/TimelineEventCreatedTeam'
import getPg from '../../../postgres/getPg'
import {insertTeamQuery} from '../../../postgres/queries/generated/insertTeamQuery'
import getKysely from '../../../postgres/getKysely'
import IUser from '../../../postgres/types/IUser'
import catchAndLog from '../../../postgres/utils/catchAndLog'
import addTeamIdToTMS from '../../../safeMutations/addTeamIdToTMS'
import insertNewTeamMember from '../../../safeMutations/insertNewTeamMember'

Expand Down Expand Up @@ -38,8 +36,13 @@ export default async function createTeamAndLeader(user: IUser, newTeam: ValidNew
orgId
})

const pg = getKysely()
await Promise.all([
catchAndLog(() => insertTeamQuery.run(verifiedTeam, getPg())),
pg
.with('Team', (qc) => qc.insertInto('Team').values(verifiedTeam))
.insertInto('TimelineEvent')
.values(timelineEvent)
.execute(),
// add meeting settings
r.table('MeetingSettings').insert(meetingSettings).run(),
// denormalize common fields to team member
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const MSTeamsNotificationHelper: NotificationIntegrationHelper<MSTeamsNot
const card = new AdaptiveCards.AdaptiveCard()
card.version = new AdaptiveCards.Version(1.2, 0)

const meetingTitle = meetingTypeTitleLookup[meeting.meetingType](meeting.name)
const meetingTitle = meetingTypeTitleLookup[meeting.meetingType]!(meeting.name)
const titleTextBlock = GenerateACMeetingTitle(meetingTitle)
card.addItem(titleTextBlock)

Expand All @@ -104,7 +104,7 @@ export const MSTeamsNotificationHelper: NotificationIntegrationHelper<MSTeamsNot
const meetingLinkColumn = new AdaptiveCards.Column()
meetingLinkColumn.width = 'stretch'
const joinMeetingActionSet = new AdaptiveCards.ActionSet()
const joinMeetingAction = MeetingActionLookup[meeting.meetingType](meetingUrl)
const joinMeetingAction = MeetingActionLookup[meeting.meetingType]!(meetingUrl)
joinMeetingActionSet.addAction(joinMeetingAction)
meetingLinkColumn.addItem(joinMeetingActionSet)
meetingLinkColumnSet.addColumn(meetingLinkColumn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ const MattermostNotificationHelper: NotificationIntegrationHelper<MattermostNoti
}
const options = {searchParams}
const meetingUrl = makeAppURL(appOrigin, `meet/${meeting.id}`, options)
const notification = makeStartMeetingNotificationLookup[meeting.meetingType](
const notification = makeStartMeetingNotificationLookup[meeting.meetingType]!(
team,
meeting,
meetingUrl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ export const SlackSingleChannelNotifier: NotificationIntegrationHelper<SlackNoti
}
const options = {searchParams}
const meetingUrl = makeAppURL(appOrigin, `meet/${meeting.id}`, options)
const {title, blocks} = makeStartMeetingNotificationLookup[meeting.meetingType](
const {title, blocks} = makeStartMeetingNotificationLookup[meeting.meetingType]!(
team,
meeting,
meetingUrl
Expand Down Expand Up @@ -388,7 +388,7 @@ export const SlackSingleChannelNotifier: NotificationIntegrationHelper<SlackNoti
}
const options = {searchParams}
const meetingUrl = makeAppURL(appOrigin, `meet/${meeting.id}`, options)
const {blocks} = makeStartMeetingNotificationLookup[meeting.meetingType](
const {blocks} = makeStartMeetingNotificationLookup[meeting.meetingType]!(
team,
meeting,
meetingUrl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import getRethink from '../../../database/rethinkDriver'
import {RDatum} from '../../../database/stricterR'
import MeetingRetrospective from '../../../database/types/MeetingRetrospective'
import TimelineEventRetroComplete from '../../../database/types/TimelineEventRetroComplete'
import getKysely from '../../../postgres/getKysely'
import removeSuggestedAction from '../../../safeMutations/removeSuggestedAction'
import {Logger} from '../../../utils/Logger'
import RecallAIServerManager from '../../../utils/RecallAIServerManager'
Expand Down Expand Up @@ -163,7 +164,11 @@ const safeEndRetrospective = async ({
})
)
const timelineEventId = events[0]!.id
await r.table('TimelineEvent').insert(events).run()
const pg = getKysely()
await Promise.all([
pg.insertInto('TimelineEvent').values(events).execute(),
r.table('TimelineEvent').insert(events).run()
])

if (team.isOnboardTeam) {
const teamLeadUserId = await r
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {checkTeamsLimit} from '../../../billing/helpers/teamLimitsCheck'
import getRethink, {ParabolR} from '../../../database/rethinkDriver'
import MeetingTeamPrompt from '../../../database/types/MeetingTeamPrompt'
import TimelineEventTeamPromptComplete from '../../../database/types/TimelineEventTeamPromptComplete'
import getKysely from '../../../postgres/getKysely'
import {getTeamPromptResponsesByMeetingId} from '../../../postgres/queries/getTeamPromptResponsesByMeetingIds'
import {Logger} from '../../../utils/Logger'
import {analytics} from '../../../utils/analytics/analytics'
Expand Down Expand Up @@ -102,7 +103,11 @@ const safeEndTeamPrompt = async ({
})
)
const timelineEventId = events[0]!.id
await r.table('TimelineEvent').insert(events).run()
const pg = getKysely()
await Promise.all([
pg.insertInto('TimelineEvent').values(events).execute(),
r.table('TimelineEvent').insert(events).run()
])
summarizeTeamPrompt(meeting, context)
analytics.teamPromptEnd(completedTeamPrompt, meetingMembers, responses, dataLoader)
checkTeamsLimit(team.orgId, dataLoader)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {Client} from 'pg'
import getPgConfig from '../getPgConfig'

export async function up() {
const client = new Client(getPgConfig())
await client.connect()
// teamId, orgId, meetingId
await client.query(`
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'TimelineEventEnum') THEN
CREATE TYPE "TimelineEventEnum" AS ENUM (
'TEAM_PROMPT_COMPLETE',
'POKER_COMPLETE',
'actionComplete',
'createdTeam',
'joinedParabol',
'retroComplete'
);
END IF;

CREATE TABLE IF NOT EXISTS "TimelineEvent" (
"id" VARCHAR(100) PRIMARY KEY,
"createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
"interactionCount" SMALLINT NOT NULL DEFAULT 0,
"seenCount" SMALLINT NOT NULL DEFAULT 0,
"type" "TimelineEventEnum" NOT NULL,
"userId" VARCHAR(100) NOT NULL,
"teamId" VARCHAR(100),
"orgId" VARCHAR(100),
"meetingId" VARCHAR(100),
"isActive" BOOLEAN NOT NULL DEFAULT TRUE,
CONSTRAINT "fk_userId"
FOREIGN KEY("userId")
REFERENCES "User"("id")
ON DELETE CASCADE,
CONSTRAINT "fk_teamId"
FOREIGN KEY("teamId")
REFERENCES "Team"("id")
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_TimelineEvent_userId_createdAt" ON "TimelineEvent"("userId", "createdAt") WHERE "isActive" = TRUE;
CREATE INDEX IF NOT EXISTS "idx_TimelineEvent_meetingId" ON "TimelineEvent"("meetingId");
END $$;
`)
await client.end()
}

export async function down() {
const client = new Client(getPgConfig())
await client.connect()
await client.query(`
DROP TABLE "TimelineEvent";
DROP TYPE "TimelineEventEnum";
` /* Do undo magic */)
await client.end()
}
21 changes: 0 additions & 21 deletions packages/server/postgres/queries/insertUser.ts

This file was deleted.

30 changes: 0 additions & 30 deletions packages/server/postgres/queries/src/insertTeamQuery.sql

This file was deleted.

36 changes: 0 additions & 36 deletions packages/server/postgres/queries/src/insertUserQuery.sql

This file was deleted.

Loading