Skip to content

Commit

Permalink
chore(rethinkdb): Organization: Phase 3 (#9933)
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Krick <matt.krick@gmail.com>
  • Loading branch information
mattkrick authored Jul 10, 2024
1 parent 3cdf5d4 commit 70084f8
Show file tree
Hide file tree
Showing 109 changed files with 752 additions and 1,378 deletions.
9 changes: 5 additions & 4 deletions codegen.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"LoginsPayload": "./types/LoginsPayload#LoginsPayloadSource",
"MeetingTemplate": "../../database/types/MeetingTemplate#default as IMeetingTemplate",
"NewMeeting": "../../postgres/types/Meeting#AnyMeeting",
"Organization": "../../database/types/Organization#default as Organization",
"Organization": "../public/types/Organization#OrganizationSource",
"PingableServices": "./types/PingableServices#PingableServicesSource",
"ProcessRecurrenceSuccess": "./types/ProcessRecurrenceSuccess#ProcessRecurrenceSuccessSource",
"RemoveAuthIdentitySuccess": "./types/RemoveAuthIdentitySuccess#RemoveAuthIdentitySuccessSource",
Expand All @@ -30,7 +30,7 @@
"SignupsPayload": "./types/SignupsPayload#SignupsPayloadSource",
"StartTrialSuccess": "./types/StartTrialSuccess#StartTrialSuccessSource",
"StripeFailPaymentPayload": "./mutations/stripeFailPayment#StripeFailPaymentPayloadSource",
"Team": "../../postgres/queries/getTeamsByIds#Team",
"Team": "../public/types/Team#TeamSource",
"UpdateOrgFeatureFlagSuccess": "./types/UpdateOrgFeatureFlagSuccess#UpdateOrgFeatureFlagSuccessSource",
"UpgradeToTeamTierSuccess": "./mutations/upgradeToTeamTier#UpgradeToTeamTierSuccessSource",
"User": "../../postgres/types/IUser#default as IUser",
Expand Down Expand Up @@ -91,10 +91,11 @@
"NotifyResponseReplied": "../../database/types/NotifyResponseReplied#default as NotifyResponseRepliedDB",
"NotifyTaskInvolves": "../../database/types/NotificationTaskInvolves#default",
"NotifyTeamArchived": "../../database/types/NotificationTeamArchived#default",
"Organization": "../../database/types/Organization#default as Organization",
"Organization": "./types/Organization#OrganizationSource",
"OrganizationUser": "../../database/types/OrganizationUser#default as OrganizationUser",
"PokerMeeting": "../../database/types/MeetingPoker#default as MeetingPoker",
"PokerMeetingMember": "../../database/types/MeetingPokerMeetingMember#default as PokerMeetingMemberDB",
"PokerTemplate": "../../database/types/PokerTemplate#default as PokerTemplateDB",
"RRule": "rrule#RRule",
"Reactable": "../../database/types/Reactable#Reactable",
"Reactji": "../types/Reactji#ReactjiSource",
Expand All @@ -120,7 +121,7 @@
"StartTeamPromptSuccess": "./types/StartTeamPromptSuccess#StartTeamPromptSuccessSource",
"StripeFailPaymentPayload": "./types/StripeFailPaymentPayload#StripeFailPaymentPayloadSource",
"Task": "../../database/types/Task#default",
"Team": "../../postgres/queries/getTeamsByIds#Team",
"Team": "./types/Team#TeamSource",
"TeamHealthPhase": "./types/TeamHealthPhase#TeamHealthPhaseSource",
"TeamHealthStage": "./types/TeamHealthStage#TeamHealthStageSource",
"TeamInvitation": "../../database/types/TeamInvitation#default",
Expand Down
68 changes: 0 additions & 68 deletions packages/client/modules/email/components/UpcomingInvoiceEmail.tsx

This file was deleted.

24 changes: 24 additions & 0 deletions packages/server/__tests__/common.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import base64url from 'base64url'
import crypto from 'crypto'
import faker from 'faker'
import {sql} from 'kysely'
import getRethink from '../database/rethinkDriver'
import ServerAuthToken from '../database/types/ServerAuthToken'
import getKysely from '../postgres/getKysely'
import encodeAuthToken from '../utils/encodeAuthToken'

const HOST = process.env.GRAPHQL_HOST || 'localhost:3000'
Expand Down Expand Up @@ -201,3 +203,25 @@ export const getUserTeams = async (userId: string) => {
})
return user.data.user.teams as [{id: string}, ...{id: string}[]]
}

export const createPGTables = async (...tables: string[]) => {
const pg = getKysely()
await Promise.all(
tables.map(async (table) => {
return sql`
CREATE TABLE IF NOT EXISTS ${sql.table(table)} (like "public".${sql.table(table)} including ALL)`.execute(
pg
)
})
)
await truncatePGTables(...tables)
}

export const truncatePGTables = async (...tables: string[]) => {
const pg = getKysely()
await Promise.all(
tables.map(async (table) => {
return sql`TRUNCATE TABLE ${sql.table(table)} CASCADE`.execute(pg)
})
)
}
8 changes: 1 addition & 7 deletions packages/server/__tests__/globalSetup.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import '../../../scripts/webpack/utils/dotenv'
import getRethink from '../database/rethinkDriver'
import getKysely from '../postgres/getKysely'

async function setup() {
const r = await getRethink()
const pg = getKysely()
// The IP address is always localhost
// so the safety checks will eventually fail if run too much

await Promise.all([
pg.deleteFrom('FailedAuthRequest').execute(),
r.table('PasswordResetRequest').delete().run(),
pg.deleteFrom('SAMLDomain').where('domain', '=', 'example.com').execute()
])
await Promise.all([r.table('PasswordResetRequest').delete().run()])
}

export default setup
14 changes: 2 additions & 12 deletions packages/server/billing/helpers/adjustUserCount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ const maybeUpdateOrganizationActiveDomain = async (
newUserEmail: string,
dataLoader: DataLoaderWorker
) => {
const r = await getRethink()
const organization = await dataLoader.get('organizations').load(orgId)
const organization = await dataLoader.get('organizations').loadNonNull(orgId)
const {isActiveDomainTouched, activeDomain} = organization
// don't modify if the domain was set manually
if (isActiveDomainTouched) return
Expand All @@ -41,16 +40,7 @@ const maybeUpdateOrganizationActiveDomain = async (
if (!domain || domain === activeDomain) return
organization.activeDomain = domain
const pg = getKysely()
await Promise.all([
pg.updateTable('Organization').set({activeDomain: domain}).where('id', '=', orgId).execute(),
r
.table('Organization')
.get(orgId)
.update({
activeDomain: domain
})
.run()
])
await pg.updateTable('Organization').set({activeDomain: domain}).where('id', '=', orgId).execute()
}

const changePause = (inactive: boolean) => async (_orgIds: string[], user: IUser) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/billing/helpers/fetchAllLines.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Stripe from 'stripe'
import {getStripeManager} from '../../utils/stripe'

export default async function fetchAllLines(invoiceId: string, customerId?: string) {
export default async function fetchAllLines(invoiceId: string, customerId?: string | null) {
const stripeLineItems = [] as Stripe.InvoiceLineItem[]
const options = {limit: 100} as Stripe.InvoiceLineItemListParams & {customer: string}
// used for upcoming invoices
Expand Down
5 changes: 3 additions & 2 deletions packages/server/billing/helpers/generateInvoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ export default async function generateInvoice(
? fromEpochSeconds(invoice.status_transitions.paid_at)
: undefined
const [organization, billingLeaderIds] = await Promise.all([
dataLoader.get('organizations').load(orgId),
dataLoader.get('organizations').loadNonNull(orgId),
r
.table('OrganizationUser')
.getAll(orgId, {index: 'orgId'})
Expand All @@ -378,14 +378,15 @@ export default async function generateInvoice(
})) ||
null

const {creditCard} = organization
const dbInvoice = new Invoice({
id: invoiceId,
amountDue: invoice.amount_due,
createdAt: now,
coupon,
total: invoice.total,
billingLeaderEmails,
creditCard: organization.creditCard,
creditCard: creditCard ? {...creditCard, last4: String(creditCard.last4)} : undefined,
endAt: fromEpochSeconds(invoice.period_end),
invoiceDate: fromEpochSeconds(invoice.due_date!),
lines: invoiceLineItems,
Expand Down
2 changes: 1 addition & 1 deletion packages/server/billing/helpers/generateUpcomingInvoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import generateInvoice from './generateInvoice'

const generateUpcomingInvoice = async (orgId: string, dataLoader: DataLoaderWorker) => {
const invoiceId = getUpcomingInvoiceId(orgId)
const organization = await dataLoader.get('organizations').load(orgId)
const organization = await dataLoader.get('organizations').loadNonNull(orgId)
const {stripeId} = organization
const manager = getStripeManager()
const [stripeLineItems, upcomingInvoice] = await Promise.all([
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import getRethink from '../../database/rethinkDriver'
import {RDatum} from '../../database/stricterR'
import Organization from '../../database/types/Organization'
import {DataLoaderWorker} from '../../graphql/graphql'
import {OrganizationSource} from '../../graphql/public/types/Organization'
import {analytics} from '../../utils/analytics/analytics'
import {getStripeManager} from '../../utils/stripe'

const sendEnterpriseOverageEvent = async (
organization: Organization,
organization: OrganizationSource,
dataLoader: DataLoaderWorker
) => {
const r = await getRethink()
Expand Down Expand Up @@ -41,7 +41,7 @@ const sendEnterpriseOverageEvent = async (
}

const handleEnterpriseOrgQuantityChanges = async (
paidOrgs: Organization[],
paidOrgs: OrganizationSource[],
dataLoader: DataLoaderWorker
) => {
const enterpriseOrgs = paidOrgs.filter((org) => org.tier === 'enterprise')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Organization from '../../database/types/Organization'
import {OrganizationSource} from '../../graphql/public/types/Organization'
import updateSubscriptionQuantity from './updateSubscriptionQuantity'

const handleTeamOrgQuantityChanges = async (paidOrgs: Organization[]) => {
const handleTeamOrgQuantityChanges = async (paidOrgs: OrganizationSource[]) => {
const teamOrgs = paidOrgs.filter((org) => org.tier === 'team')
if (teamOrgs.length === 0) return

Expand Down
29 changes: 5 additions & 24 deletions packages/server/billing/helpers/teamLimitsCheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import {Threshold} from 'parabol-client/types/constEnums'
import {sql} from 'kysely'
import {r} from 'rethinkdb-ts'
import NotificationTeamsLimitExceeded from '../../database/types/NotificationTeamsLimitExceeded'
import Organization from '../../database/types/Organization'
import scheduleTeamLimitsJobs from '../../database/types/scheduleTeamLimitsJobs'
import {DataLoaderWorker} from '../../graphql/graphql'
import publishNotification from '../../graphql/public/mutations/helpers/publishNotification'
import {OrganizationSource} from '../../graphql/public/types/Organization'
import getActiveTeamCountByTeamIds from '../../graphql/public/types/helpers/getActiveTeamCountByTeamIds'
import {getFeatureTier} from '../../graphql/types/helpers/getFeatureTier'
import {domainHasActiveDeals} from '../../hubSpot/hubSpotApi'
Expand All @@ -35,7 +35,7 @@ const enableUsageStats = async (userIds: string[], orgId: string) => {
}

const sendWebsiteNotifications = async (
organization: Organization,
organization: OrganizationSource,
userIds: string[],
dataLoader: DataLoaderWorker
) => {
Expand Down Expand Up @@ -72,7 +72,7 @@ const isLimitExceeded = async (orgId: string) => {

// Warning: the function might be expensive
export const maybeRemoveRestrictions = async (orgId: string, dataLoader: DataLoaderWorker) => {
const organization = await dataLoader.get('organizations').load(orgId)
const organization = await dataLoader.get('organizations').loadNonNull(orgId)

if (!organization.tierLimitExceededAt) {
return
Expand All @@ -87,16 +87,6 @@ export const maybeRemoveRestrictions = async (orgId: string, dataLoader: DataLoa
.set({tierLimitExceededAt: null, scheduledLockAt: null, lockedAt: null})
.where('id', '=', orgId)
.execute(),
r
.table('Organization')
.get(orgId)
.update({
tierLimitExceededAt: null,
scheduledLockAt: null,
lockedAt: null,
updatedAt: new Date()
})
.run(),
r
.table('OrganizationUser')
.getAll(r.args(billingLeadersIds), {index: 'userId'})
Expand All @@ -111,7 +101,7 @@ export const maybeRemoveRestrictions = async (orgId: string, dataLoader: DataLoa

// Warning: the function might be expensive
export const checkTeamsLimit = async (orgId: string, dataLoader: DataLoaderWorker) => {
const organization = await dataLoader.get('organizations').load(orgId)
const organization = await dataLoader.get('organizations').loadNonNull(orgId)
const {tierLimitExceededAt, tier, trialStartDate, featureFlags, name: orgName} = organization

if (!featureFlags?.includes('teamsLimit')) return
Expand Down Expand Up @@ -144,16 +134,7 @@ export const checkTeamsLimit = async (orgId: string, dataLoader: DataLoaderWorke
scheduledLockAt
})
.where('id', '=', orgId)
.execute(),
r
.table('Organization')
.get(orgId)
.update({
tierLimitExceededAt: now,
scheduledLockAt,
updatedAt: now
})
.run()
.execute()
])
dataLoader.get('organizations').clear(orgId)

Expand Down
Loading

0 comments on commit 70084f8

Please sign in to comment.