chore(gatekeeper): get workspace plan repository and dataloader function

This commit is contained in:
Alessandro Magionami
2025-04-04 10:51:46 +02:00
parent 5fbf2e500d
commit 5c004f85b1
4 changed files with 100 additions and 1 deletions
@@ -20,6 +20,10 @@ export type GetWorkspacePlan = (args: {
workspaceId: string
}) => Promise<WorkspacePlan | null>
export type GetWorkspacePlansByWorkspaceId = (args: {
workspaceIds: string[]
}) => Promise<Record<string, WorkspacePlan>>
export type GetWorkspaceWithPlan = (args: {
workspaceId: string
}) => Promise<Optional<Workspace & { plan: Nullable<WorkspacePlan> }>>
@@ -1,10 +1,12 @@
import { WorkspaceSeat } from '@/modules/gatekeeper/domain/billing'
import { getWorkspacePlansByWorkspaceIdFactory } from '@/modules/gatekeeper/repositories/billing'
import {
getProjectsUsersSeatsFactory,
getWorkspacesUsersSeatsFactory
} from '@/modules/gatekeeper/repositories/workspaceSeat'
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
import { defineRequestDataloaders } from '@/modules/shared/helpers/graphqlHelper'
import { WorkspacePlan } from '@speckle/shared'
const { FF_GATEKEEPER_MODULE_ENABLED } = getFeatureFlags()
@@ -17,6 +19,7 @@ const dataLoadersDefinition = defineRequestDataloaders(
({ createLoader, deps: { db } }) => {
const getWorkspacesUsersSeats = getWorkspacesUsersSeatsFactory({ db })
const getProjectsUsersSeats = getProjectsUsersSeatsFactory({ db })
const getWorkspacePlansByWorkspaceId = getWorkspacePlansByWorkspaceIdFactory({ db })
return {
gatekeeper: {
@@ -55,6 +58,22 @@ const dataLoadersDefinition = defineRequestDataloaders(
{
cacheKeyFn: ({ projectId, userId }) => `${projectId}-${userId}`
}
),
getWorkspacePlan: createLoader<
{ workspaceId: string },
WorkspacePlan | null,
string
>(
async (requests) => {
const results = await getWorkspacePlansByWorkspaceId({
workspaceIds: requests.map((request) => request.workspaceId)
})
return requests.map(({ workspaceId }) => results[workspaceId] || null)
},
{
cacheKeyFn: ({ workspaceId }) => workspaceId
}
)
}
}
@@ -16,7 +16,8 @@ import {
GetWorkspaceSubscriptions,
UpsertTrialWorkspacePlan,
UpsertUnpaidWorkspacePlan,
GetWorkspaceWithPlan
GetWorkspaceWithPlan,
GetWorkspacePlansByWorkspaceId
} from '@/modules/gatekeeper/domain/billing'
import {
ChangeExpiredTrialWorkspacePlanStatuses,
@@ -93,6 +94,15 @@ export const getWorkspacePlanFactory =
return workspacePlan ?? null
}
export const getWorkspacePlansByWorkspaceIdFactory =
({ db }: { db: Knex }): GetWorkspacePlansByWorkspaceId =>
async ({ workspaceIds }) => {
const results = await tables
.workspacePlans(db)
.whereIn(WorkspacePlans.col.workspaceId, workspaceIds)
return results.reduce((acc, curr) => ({ ...acc, [curr.workspaceId]: curr }), {})
}
export const upsertWorkspacePlanFactory =
({ db }: { db: Knex }): UpsertWorkspacePlan =>
async ({ workspacePlan }) => {
@@ -0,0 +1,66 @@
import { db } from '@/db/knex'
import { createRandomString } from '@/modules/core/helpers/testHelpers'
import {
getWorkspacePlansByWorkspaceIdFactory,
upsertWorkspacePlanFactory
} from '@/modules/gatekeeper/repositories/billing'
import { createTestWorkspace } from '@/modules/workspaces/tests/helpers/creation'
import { createTestUser } from '@/test/authHelper'
import { PaidWorkspacePlans, PaidWorkspacePlanStatuses } from '@speckle/shared'
import { expect } from 'chai'
describe('Module @gatekeeper', () => {
const upsertWorkspacePlan = upsertWorkspacePlanFactory({ db })
describe('Repositories WorkspacePlan', () => {
describe('getWorkspacePlansByWorkspaceIdFactory should return a function that, ', () => {
const getWorkspacePlansByWorkspaceId = getWorkspacePlansByWorkspaceIdFactory({
db
})
it('should return a map of workspacePlans by their workspaceId', async () => {
const now = new Date()
const user = await createTestUser()
const workspace1 = {
id: '',
name: createRandomString(),
ownerId: user.id
}
await createTestWorkspace(workspace1, user)
const plan1 = {
workspaceId: workspace1.id,
name: PaidWorkspacePlans.Team,
createdAt: now,
status: PaidWorkspacePlanStatuses.Valid
}
await upsertWorkspacePlan({
workspacePlan: plan1
})
const workspace2 = {
id: '',
name: createRandomString(),
ownerId: user.id
}
await createTestWorkspace(workspace2, user)
const plan2 = {
workspaceId: workspace2.id,
name: PaidWorkspacePlans.Team,
createdAt: now,
status: PaidWorkspacePlanStatuses.Valid
}
await upsertWorkspacePlan({
workspacePlan: plan2
})
const results = await getWorkspacePlansByWorkspaceId({
workspaceIds: [workspace1.id, workspace2.id]
})
for (const [workspaceId, workspacePlan] of Object.entries(results)) {
const { createdAt, ...plan } = workspacePlan
expect(createdAt).to.not.eq(null)
expect(plan.workspaceId).to.eq(workspaceId)
expect(plan).to.deep.eq(plan)
}
})
})
})
})