gergo/web 2047 user joins the workspace event (#3412)

* feat(gatekeeper): add gatekeeper module feature flag

* feat(gatekeeper): add workspace pricing table domain

* feat(gatekeeper): add checkout session creation

* feat(gatekeeper): verify stripe signature

* wip(gatekeeper): checkout callbacks

* feat(gatekeeper): add unlimited and academia plan types

* refactor(envHelper): getStringFromEnv helper

* chore(gatekeeper): add future todos

* feat(gatekeeper): add productId to the subscription domain

* feat(gatekeeper): add in memory repositories

* feat(gatekeeper): add more errors

* feat(gatekeeper): complete checkout session service

* feat(gatekeeper): add stripe client implementation

* feat(gatekeeper): add checkout session completion webhook callback path

* feat(gendo): fix not needing env vars if gendo module is not enabled

* feat(gatekeeper): require a license for billing

* chore(gatekeeper): cleanup before testing

* feat(gatekeeper): subscriptionData parsing model

* ci: add billing integration and gatekeeper modules to test config

* test(gatekeeper): add checkout service tests

* feat(gatekeeper): make completeCheckout callback idempotent properly

* feat(gatekeeper): move to knex based repositories

* test(gatekeeper): billing repository tests

* feat(gatekeeper): add yearly billing cycle toggle

* feat(ci): add stripe integration context to test job

* feat(billingPage): conditionally render the checkout CTAs

* fix(gatekeeper): remove flaky test condition

* feat(helm): add billing integration feature flag

* WIP billing gql api

* feat(gatekeeper): cancel checkout session api

* feat(gatekeeper): handle existing checkout sessions, when trying to create a new one

* feat(gatekeeper): add workspace plans gql api

* feat(gatekeeper): handle cancelation and subscription updates

* fix(gatekeeper): scope initialization

* fix(gatekeeper): eliminate stripe client import sideeffect

* fix(gatekeeper): eliminate stripe client import sideeffect 2

* feat(gatekeeper): upsize subscription on workspace role change

* feat(shared): add command pattern implementation

* refactor(eventBus): remove return capabilities from the event bus

* refactor(workspaces): use new commandFactory in workspace resolver

* feat(core): facelift taskLock

* feat(gatekeeper): shedule subscription downscale

* feat(gatekeeper): manage subscription downscale

* feat(gatekeeper): get workspace subscriptions, that are about to expire

* feat(gatekeeper): manage subscription downscale

* fix(gatekeeper): do not update subscription to canceled subs

* ci: bump postgres and max connections

* feat(workspaces): fix command factory event bugs
This commit is contained in:
Gergő Jedlicska
2024-10-30 15:51:40 +01:00
committed by GitHub
parent 077587a7c1
commit da7f0dda0e
29 changed files with 1428 additions and 306 deletions
@@ -42,7 +42,6 @@ import {
import { createProjectInviteFactory } from '@/modules/serverinvites/services/projectInviteManagement'
import { getInvitationTargetUsersFactory } from '@/modules/serverinvites/services/retrieval'
import { authorizeResolver } from '@/modules/shared'
import { withTransaction } from '@/modules/shared/helpers/dbHelper'
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
import { getEventBus } from '@/modules/shared/services/eventBus'
import { WorkspaceInviteResourceType } from '@/modules/workspaces/domain/constants'
@@ -149,7 +148,10 @@ import { publish } from '@/modules/shared/utils/subscriptions'
import { updateStreamRoleAndNotifyFactory } from '@/modules/core/services/streams/management'
import { getUserFactory, getUsersFactory } from '@/modules/core/repositories/users'
import { getServerInfoFactory } from '@/modules/core/repositories/server'
import { commandFactory } from '@/modules/shared/command'
import { withTransaction } from '@/modules/shared/helpers/dbHelper'
const eventBus = getEventBus()
const getServerInfo = getServerInfoFactory({ db })
const getUser = getUserFactory({ db })
const getUsers = getUsersFactory({ db })
@@ -456,36 +458,34 @@ export = FF_WORKSPACES_MODULE_ENABLED
)
if (!role) {
// this is currently not working with the command factory
// TODO: include the onWorkspaceRoleDeletedFactory listener service
const trx = await db.transaction()
const deleteWorkspaceRole = deleteWorkspaceRoleFactory({
deleteWorkspaceRole: repoDeleteWorkspaceRoleFactory({ db: trx }),
getWorkspaceRoles: getWorkspaceRolesFactory({ db: trx }),
emitWorkspaceEvent: getEventBus().emit
})
await withTransaction(deleteWorkspaceRole(args.input), trx)
await withTransaction(deleteWorkspaceRole({ workspaceId, userId }), trx)
} else {
if (!isWorkspaceRole(role)) {
throw new WorkspaceInvalidRoleError()
}
const trx = await db.transaction()
const updateWorkspaceRole = updateWorkspaceRoleFactory({
upsertWorkspaceRole: upsertWorkspaceRoleFactory({ db: trx }),
getWorkspaceWithDomains: getWorkspaceWithDomainsFactory({ db: trx }),
findVerifiedEmailsByUserId: findVerifiedEmailsByUserIdFactory({
db: trx
}),
getWorkspaceRoles: getWorkspaceRolesFactory({ db: trx }),
emitWorkspaceEvent: getEventBus().emit
const updateWorkspaceRole = commandFactory({
db,
eventBus,
operationFactory: ({ db, emit }) =>
updateWorkspaceRoleFactory({
upsertWorkspaceRole: upsertWorkspaceRoleFactory({ db }),
getWorkspaceWithDomains: getWorkspaceWithDomainsFactory({ db }),
findVerifiedEmailsByUserId: findVerifiedEmailsByUserIdFactory({
db
}),
getWorkspaceRoles: getWorkspaceRolesFactory({ db }),
emitWorkspaceEvent: emit
})
})
await withTransaction(
updateWorkspaceRole({ userId, workspaceId, role }),
trx
)
await updateWorkspaceRole({ userId, workspaceId, role })
}
return await getWorkspaceFactory({ db })({ workspaceId })
@@ -559,19 +559,18 @@ export = FF_WORKSPACES_MODULE_ENABLED
})
},
leave: async (_parent, args, context) => {
// this is currently not working with the command factory
// TODO: include the onWorkspaceRoleDeletedFactory listener service
const trx = await db.transaction()
const deleteWorkspaceRole = deleteWorkspaceRoleFactory({
deleteWorkspaceRole: repoDeleteWorkspaceRoleFactory({ db: trx }),
getWorkspaceRoles: getWorkspaceRolesFactory({ db: trx }),
emitWorkspaceEvent: getEventBus().emit
})
await withTransaction(
deleteWorkspaceRole({ workspaceId: args.id, userId: context.userId! }),
trx
)
return true
},
invites: () => ({}),
@@ -770,33 +769,33 @@ export = FF_WORKSPACES_MODULE_ENABLED
context.resourceAccessRules
)
const trx = await db.transaction()
const moveProjectToWorkspace = moveProjectToWorkspaceFactory({
getProject: getProjectFactory({ db }),
updateProject: updateProjectFactory({ db: trx }),
upsertProjectRole: upsertProjectRoleFactory({ db: trx }),
getProjectCollaborators: getProjectCollaboratorsFactory({ db }),
getWorkspaceRoles: getWorkspaceRolesFactory({ db: trx }),
getWorkspaceRoleToDefaultProjectRoleMapping:
getWorkspaceRoleToDefaultProjectRoleMappingFactory({
getWorkspace: getWorkspaceFactory({ db })
}),
updateWorkspaceRole: updateWorkspaceRoleFactory({
getWorkspaceRoles: getWorkspaceRolesFactory({ db: trx }),
getWorkspaceWithDomains: getWorkspaceWithDomainsFactory({ db: trx }),
findVerifiedEmailsByUserId: findVerifiedEmailsByUserIdFactory({
db: trx
}),
upsertWorkspaceRole: upsertWorkspaceRoleFactory({ db: trx }),
emitWorkspaceEvent: getEventBus().emit
})
const moveProjectToWorkspace = commandFactory({
db,
eventBus,
operationFactory: ({ db, emit }) =>
moveProjectToWorkspaceFactory({
getProject: getProjectFactory({ db }),
updateProject: updateProjectFactory({ db }),
upsertProjectRole: upsertProjectRoleFactory({ db }),
getProjectCollaborators: getProjectCollaboratorsFactory({ db }),
getWorkspaceRoles: getWorkspaceRolesFactory({ db }),
getWorkspaceRoleToDefaultProjectRoleMapping:
getWorkspaceRoleToDefaultProjectRoleMappingFactory({
getWorkspace: getWorkspaceFactory({ db })
}),
updateWorkspaceRole: updateWorkspaceRoleFactory({
getWorkspaceRoles: getWorkspaceRolesFactory({ db }),
getWorkspaceWithDomains: getWorkspaceWithDomainsFactory({ db }),
findVerifiedEmailsByUserId: findVerifiedEmailsByUserIdFactory({
db
}),
upsertWorkspaceRole: upsertWorkspaceRoleFactory({ db }),
emitWorkspaceEvent: emit
})
})
})
return await withTransaction(
moveProjectToWorkspace({ projectId, workspaceId }),
trx
)
return await moveProjectToWorkspace({ projectId, workspaceId })
}
},
Workspace: {