diff --git a/packages/server/modules/gatekeeper/graph/resolvers/index.ts b/packages/server/modules/gatekeeper/graph/resolvers/index.ts index 777078fc1..4b6afe3ae 100644 --- a/packages/server/modules/gatekeeper/graph/resolvers/index.ts +++ b/packages/server/modules/gatekeeper/graph/resolvers/index.ts @@ -218,7 +218,7 @@ export = FF_GATEKEEPER_MODULE_ENABLED const assigned = await countSeatsByTypeInWorkspaceFactory({ db })({ workspaceId, - type: 'editor' + type: WorkspaceSeatType.Editor }) let available = 0 @@ -261,7 +261,7 @@ export = FF_GATEKEEPER_MODULE_ENABLED return { assigned: await countSeatsByTypeInWorkspaceFactory({ db })({ workspaceId, - type: 'viewer' + type: WorkspaceSeatType.Viewer }), available: 0 } @@ -274,8 +274,7 @@ export = FF_GATEKEEPER_MODULE_ENABLED userId: parent.id }) - // Defaults to Editor for old plans that don't have seat types - return seat?.type || WorkspaceSeatType.Editor + return seat?.type || WorkspaceSeatType.Viewer } }, ServerWorkspacesInfo: { diff --git a/packages/server/modules/gatekeeper/services/checkout/startCheckoutSession.ts b/packages/server/modules/gatekeeper/services/checkout/startCheckoutSession.ts index 37ff88c13..00f4b6498 100644 --- a/packages/server/modules/gatekeeper/services/checkout/startCheckoutSession.ts +++ b/packages/server/modules/gatekeeper/services/checkout/startCheckoutSession.ts @@ -5,7 +5,8 @@ import { DeleteCheckoutSession, GetWorkspaceCheckoutSession, GetWorkspacePlan, - SaveCheckoutSession + SaveCheckoutSession, + WorkspaceSeatType } from '@/modules/gatekeeper/domain/billing' import { CountSeatsByTypeInWorkspace } from '@/modules/gatekeeper/domain/operations' import { @@ -123,7 +124,7 @@ export const startCheckoutSessionFactory = const editorsCount = await countSeatsByTypeInWorkspace({ workspaceId, - type: 'editor' + type: WorkspaceSeatType.Editor }) if (!editorsCount) { throw new InvalidWorkspacePlanUpgradeError('Workspace has no seats') diff --git a/packages/server/modules/gatekeeper/services/subscriptions/manageSubscriptionDownscale.ts b/packages/server/modules/gatekeeper/services/subscriptions/manageSubscriptionDownscale.ts index 7ca812e9a..b26bf3902 100644 --- a/packages/server/modules/gatekeeper/services/subscriptions/manageSubscriptionDownscale.ts +++ b/packages/server/modules/gatekeeper/services/subscriptions/manageSubscriptionDownscale.ts @@ -5,6 +5,7 @@ import { GetWorkspaceSubscriptions, ReconcileSubscriptionData, UpsertWorkspaceSubscription, + WorkspaceSeatType, WorkspaceSubscription } from '@/modules/gatekeeper/domain/billing' import { CountSeatsByTypeInWorkspace } from '@/modules/gatekeeper/domain/operations' @@ -59,7 +60,7 @@ export const downscaleWorkspaceSubscriptionFactory = const editorsCount = await countSeatsByTypeInWorkspace({ workspaceId, - type: 'editor' + type: WorkspaceSeatType.Editor }) const subscriptionData = cloneDeep(workspaceSubscription.subscriptionData) diff --git a/packages/server/modules/gatekeeper/services/subscriptions/upgradeWorkspaceSubscription.ts b/packages/server/modules/gatekeeper/services/subscriptions/upgradeWorkspaceSubscription.ts index f64f8dbf0..ca453e6c0 100644 --- a/packages/server/modules/gatekeeper/services/subscriptions/upgradeWorkspaceSubscription.ts +++ b/packages/server/modules/gatekeeper/services/subscriptions/upgradeWorkspaceSubscription.ts @@ -6,7 +6,8 @@ import { ReconcileSubscriptionData, SubscriptionDataInput, UpsertPaidWorkspacePlan, - UpsertWorkspaceSubscription + UpsertWorkspaceSubscription, + WorkspaceSeatType } from '@/modules/gatekeeper/domain/billing' import { CountSeatsByTypeInWorkspace } from '@/modules/gatekeeper/domain/operations' import { @@ -151,7 +152,7 @@ export const upgradeWorkspaceSubscriptionFactory = const editorsCount = await countSeatsByTypeInWorkspace({ workspaceId, - type: 'editor' + type: WorkspaceSeatType.Editor }) workspaceSubscription.updatedAt = new Date() diff --git a/packages/server/modules/workspaces/services/projects.ts b/packages/server/modules/workspaces/services/projects.ts index cb5a4f21b..44a9589e8 100644 --- a/packages/server/modules/workspaces/services/projects.ts +++ b/packages/server/modules/workspaces/services/projects.ts @@ -178,7 +178,7 @@ export const moveProjectToWorkspaceFactory = const workspaceSeat = await createWorkspaceSeat({ userId, workspaceId, - type: 'viewer' + type: WorkspaceSeatType.Viewer }) // Update workspace team in-memory @@ -193,7 +193,8 @@ export const moveProjectToWorkspaceFactory = const requiresEditorSeat = currentProjectRole === Roles.Stream.Owner || currentProjectRole === Roles.Stream.Contributor - const hasEditorSeat = workspaceTeam[userId]?.seat?.type === 'editor' + const hasEditorSeat = + workspaceTeam[userId]?.seat?.type === WorkspaceSeatType.Editor if (requiresEditorSeat && !hasEditorSeat) { await updateProjectRole( diff --git a/packages/server/modules/workspaces/services/workspaceSeat.ts b/packages/server/modules/workspaces/services/workspaceSeat.ts index 47fd62f28..f8a4b46f1 100644 --- a/packages/server/modules/workspaces/services/workspaceSeat.ts +++ b/packages/server/modules/workspaces/services/workspaceSeat.ts @@ -21,23 +21,29 @@ const getDefaultWorkspaceSeatTypeByWorkspaceRole = ({ workspaceRole: WorkspaceRoles }): WorkspaceSeatType => { if (workspaceRole === Roles.Workspace.Admin) { - return 'editor' + return WorkspaceSeatType.Editor } - return 'viewer' + return WorkspaceSeatType.Viewer } const WorkspaceRoleWorkspaceSeatTypeMapping = z.union([ z.object({ workspaceRole: z.literal(Roles.Workspace.Admin), - workspaceSeatType: z.literal('editor') + workspaceSeatType: z.literal(WorkspaceSeatType.Editor) }), z.object({ workspaceRole: z.literal(Roles.Workspace.Member), - workspaceSeatType: z.union([z.literal('editor'), z.literal('viewer')]) + workspaceSeatType: z.union([ + z.literal(WorkspaceSeatType.Editor), + z.literal(WorkspaceSeatType.Viewer) + ]) }), z.object({ workspaceRole: z.literal(Roles.Workspace.Guest), - workspaceSeatType: z.union([z.literal('editor'), z.literal('viewer')]) + workspaceSeatType: z.union([ + z.literal(WorkspaceSeatType.Editor), + z.literal(WorkspaceSeatType.Viewer) + ]) }) ]) diff --git a/packages/server/modules/workspaces/tests/integration/workspaceSeat.spec.ts b/packages/server/modules/workspaces/tests/integration/workspaceSeat.spec.ts index 71eae2caa..16457dd37 100644 --- a/packages/server/modules/workspaces/tests/integration/workspaceSeat.spec.ts +++ b/packages/server/modules/workspaces/tests/integration/workspaceSeat.spec.ts @@ -61,7 +61,7 @@ describe('Workspace workspaceSeat services', () => { .where({ userId: user.id, workspaceId: workspace.id }) .first() - expect(workspaceSeat.type).to.eq('viewer') + expect(workspaceSeat.type).to.eq(WorkspaceSeatType.Viewer) // Change workspace role await assignToWorkspace(workspace, user, Roles.Workspace.Admin) @@ -70,7 +70,7 @@ describe('Workspace workspaceSeat services', () => { .where({ userId: user.id, workspaceId: workspace.id }) .first() - expect(workspaceSeatUpdated.type).to.eq('editor') + expect(workspaceSeatUpdated.type).to.eq(WorkspaceSeatType.Editor) }) }) diff --git a/packages/server/modules/workspaces/tests/integration/workspaces.graph.spec.ts b/packages/server/modules/workspaces/tests/integration/workspaces.graph.spec.ts index a5dd7f2fc..043ae83fb 100644 --- a/packages/server/modules/workspaces/tests/integration/workspaces.graph.spec.ts +++ b/packages/server/modules/workspaces/tests/integration/workspaces.graph.spec.ts @@ -392,7 +392,7 @@ describe('Workspaces GQL CRUD', () => { })({ workspaceId: workspace.id, userId: memberEditor.id, - type: 'editor', + type: WorkspaceSeatType.Editor, assignedByUserId: admin.id }) // Assign the same user editor to another workspace @@ -404,7 +404,7 @@ describe('Workspaces GQL CRUD', () => { })({ workspaceId: otherWorkspace.id, userId: memberEditor.id, - type: 'editor', + type: WorkspaceSeatType.Editor, assignedByUserId: admin.id }) @@ -422,14 +422,14 @@ describe('Workspaces GQL CRUD', () => { })({ workspaceId: workspace.id, userId: memberViewer.id, - type: 'viewer', + type: WorkspaceSeatType.Viewer, assignedByUserId: admin.id }) const res = await session.execute(GetWorkspaceTeamDocument, { workspaceId: workspace.id, filter: { - seatType: 'editor' + seatType: WorkspaceSeatType.Editor } }) diff --git a/packages/server/modules/workspaces/tests/unit/services/management.spec.ts b/packages/server/modules/workspaces/tests/unit/services/management.spec.ts index d68ab707e..eda636e2e 100644 --- a/packages/server/modules/workspaces/tests/unit/services/management.spec.ts +++ b/packages/server/modules/workspaces/tests/unit/services/management.spec.ts @@ -2,6 +2,7 @@ import { Workspace, WorkspaceAcl, WorkspaceDomain, + WorkspaceSeatType, WorkspaceWithDomains } from '@/modules/workspacesCore/domain/types' import { @@ -654,7 +655,7 @@ const buildUpdateWorkspaceRoleAndTestContext = ( }, ensureValidWorkspaceRoleSeat: async () => { return { - type: 'editor', + type: WorkspaceSeatType.Editor, workspaceId: 'test', userId: 'test', createdAt: new Date(), diff --git a/packages/server/modules/workspaces/tests/unit/services/projects.spec.ts b/packages/server/modules/workspaces/tests/unit/services/projects.spec.ts index 7a965b4f8..b3f2144f7 100644 --- a/packages/server/modules/workspaces/tests/unit/services/projects.spec.ts +++ b/packages/server/modules/workspaces/tests/unit/services/projects.spec.ts @@ -114,34 +114,34 @@ describe('Project management services', () => { [ Roles.Stream.Owner, Roles.Workspace.Admin, - 'editor', + WorkspaceSeatType.Editor, Roles.Stream.Owner, Roles.Workspace.Admin, - 'editor' + WorkspaceSeatType.Editor ], [ Roles.Stream.Owner, Roles.Workspace.Member, - 'editor', + WorkspaceSeatType.Editor, Roles.Stream.Owner, Roles.Workspace.Member, - 'editor' + WorkspaceSeatType.Editor ], [ Roles.Stream.Owner, Roles.Workspace.Member, - 'viewer', + WorkspaceSeatType.Viewer, Roles.Stream.Reviewer, Roles.Workspace.Member, - 'viewer' + WorkspaceSeatType.Viewer ], [ Roles.Stream.Owner, Roles.Workspace.Guest, - 'viewer', + WorkspaceSeatType.Viewer, Roles.Stream.Reviewer, Roles.Workspace.Guest, - 'viewer' + WorkspaceSeatType.Viewer ], [ Roles.Stream.Owner, @@ -149,39 +149,39 @@ describe('Project management services', () => { null, Roles.Stream.Reviewer, Roles.Workspace.Member, - 'viewer' + WorkspaceSeatType.Viewer ], [ Roles.Stream.Contributor, Roles.Workspace.Admin, - 'editor', + WorkspaceSeatType.Editor, Roles.Stream.Contributor, Roles.Workspace.Admin, - 'editor' + WorkspaceSeatType.Editor ], [ Roles.Stream.Contributor, Roles.Workspace.Member, - 'editor', + WorkspaceSeatType.Editor, Roles.Stream.Contributor, Roles.Workspace.Member, - 'editor' + WorkspaceSeatType.Editor ], [ Roles.Stream.Contributor, Roles.Workspace.Member, - 'viewer', + WorkspaceSeatType.Viewer, Roles.Stream.Reviewer, Roles.Workspace.Member, - 'viewer' + WorkspaceSeatType.Viewer ], [ Roles.Stream.Contributor, Roles.Workspace.Guest, - 'viewer', + WorkspaceSeatType.Viewer, Roles.Stream.Reviewer, Roles.Workspace.Guest, - 'viewer' + WorkspaceSeatType.Viewer ], [ Roles.Stream.Contributor, @@ -189,39 +189,39 @@ describe('Project management services', () => { null, Roles.Stream.Reviewer, Roles.Workspace.Member, - 'viewer' + WorkspaceSeatType.Viewer ], [ Roles.Stream.Reviewer, Roles.Workspace.Admin, - 'editor', + WorkspaceSeatType.Editor, Roles.Stream.Reviewer, Roles.Workspace.Admin, - 'editor' + WorkspaceSeatType.Editor ], [ Roles.Stream.Reviewer, Roles.Workspace.Member, - 'editor', + WorkspaceSeatType.Editor, Roles.Stream.Reviewer, Roles.Workspace.Member, - 'editor' + WorkspaceSeatType.Editor ], [ Roles.Stream.Reviewer, Roles.Workspace.Member, - 'viewer', + WorkspaceSeatType.Viewer, Roles.Stream.Reviewer, Roles.Workspace.Member, - 'viewer' + WorkspaceSeatType.Viewer ], [ Roles.Stream.Reviewer, Roles.Workspace.Guest, - 'viewer', + WorkspaceSeatType.Viewer, Roles.Stream.Reviewer, Roles.Workspace.Guest, - 'viewer' + WorkspaceSeatType.Viewer ], [ Roles.Stream.Reviewer, @@ -229,7 +229,7 @@ describe('Project management services', () => { null, Roles.Stream.Reviewer, Roles.Workspace.Member, - 'viewer' + WorkspaceSeatType.Viewer ] ] diff --git a/packages/server/modules/workspaces/tests/unit/services/workspaceSeat.spec.ts b/packages/server/modules/workspaces/tests/unit/services/workspaceSeat.spec.ts index c184e4165..eaf179139 100644 --- a/packages/server/modules/workspaces/tests/unit/services/workspaceSeat.spec.ts +++ b/packages/server/modules/workspaces/tests/unit/services/workspaceSeat.spec.ts @@ -1,4 +1,5 @@ import { isWorkspaceRoleWorkspaceSeatTypeValid } from '@/modules/workspaces/services/workspaceSeat' +import { WorkspaceSeatType } from '@/modules/workspacesCore/domain/types' import { Roles } from '@speckle/shared' import { expect } from 'chai' @@ -7,42 +8,42 @@ describe('Workspace workspaceSeat services', () => { it('should return true if the role is admin and seat type is editor', () => { const result = isWorkspaceRoleWorkspaceSeatTypeValid({ workspaceRole: Roles.Workspace.Admin, - workspaceSeatType: 'editor' + workspaceSeatType: WorkspaceSeatType.Editor }) expect(result).to.be.true }) it('should return false if the role is admin and seat type is viewer', () => { const result = isWorkspaceRoleWorkspaceSeatTypeValid({ workspaceRole: Roles.Workspace.Admin, - workspaceSeatType: 'viewer' as 'editor' + workspaceSeatType: WorkspaceSeatType.Viewer as typeof WorkspaceSeatType.Editor }) expect(result).to.be.false }) it('should return true if the role is member and seat type is editor', () => { const result = isWorkspaceRoleWorkspaceSeatTypeValid({ workspaceRole: Roles.Workspace.Member, - workspaceSeatType: 'editor' + workspaceSeatType: WorkspaceSeatType.Editor }) expect(result).to.be.true }) it('should return true if the role is member and seat type is viewer', () => { const result = isWorkspaceRoleWorkspaceSeatTypeValid({ workspaceRole: Roles.Workspace.Member, - workspaceSeatType: 'viewer' + workspaceSeatType: WorkspaceSeatType.Viewer }) expect(result).to.be.true }) it('should return true if the role is guest and seat type is editor', () => { const result = isWorkspaceRoleWorkspaceSeatTypeValid({ workspaceRole: Roles.Workspace.Guest, - workspaceSeatType: 'editor' + workspaceSeatType: WorkspaceSeatType.Editor }) expect(result).to.be.true }) it('should return true if the role is member and seat type is viewer', () => { const result = isWorkspaceRoleWorkspaceSeatTypeValid({ workspaceRole: Roles.Workspace.Guest, - workspaceSeatType: 'viewer' + workspaceSeatType: WorkspaceSeatType.Viewer }) expect(result).to.be.true })