399c998fd7
* feat(multiregion): replace user replication * chore(multiregion): optimise replication * maybe it's this * postgres is fun * once more * chore(multiregion): only replicate test user creation during multiregion tests * feat: improved replicate_query logic * fix: minor * fix: starting issue * feat: included user create and delete specs to multiregion * feat: removed console logs * fix: user defaults * fix: multiregion test helper * fix: update scenarios for users * refactor(multiregion): swap replicateQuery concept to asMultiregionOperation (#5301) feat(multiregion): introduced asMultregionOperator, refactor test to user builder classes * chore: renamings * fix: remove comments * feat: remove user replication * refactor: simplified spec usages * chore: comments * chore: branches and favs * chore: more tests * chore: more tests * fix linting * fix tests * feat: dropping replication * refactor: moved project delete to service * fix: comment * feat: updateStreamFactory and updateProjectFacotry * deleteProjectFactory + replicateFactory * deleteWorkspaceFactory * fix: selector * fix: tests * fix tests, finished createStreamFactory * feat: simplify changes * fix: remove comment * fix: minor strucutres * fix: moveProjectToRegion * fix: moved branch creation outside of multiregion scope * fix: branch creation * fix: tests * fix: ci tests * fix: removed log form test * fix: on specs, no random regionKeys * review fixes * fix: mr comments * feat: removed test --------- Co-authored-by: Charles Driesler <chuck@speckle.systems>
126 lines
3.5 KiB
TypeScript
126 lines
3.5 KiB
TypeScript
import { ProjectEvents } from '@/modules/core/domain/projects/events'
|
|
import { generateProjectName } from '@/modules/core/domain/projects/logic'
|
|
import type {
|
|
CreateProject,
|
|
DeleteProject,
|
|
DeleteProjectAndCommits,
|
|
QueryAllProjects,
|
|
StoreProject,
|
|
StoreProjectRole
|
|
} from '@/modules/core/domain/projects/operations'
|
|
import type {
|
|
Project,
|
|
StreamWithOptionalRole
|
|
} from '@/modules/core/domain/streams/types'
|
|
import { ProjectQueryError } from '@/modules/core/errors/projects'
|
|
import { ProjectVisibility } from '@/modules/core/graph/generated/graphql'
|
|
import { mapGqlToDbProjectVisibility } from '@/modules/core/helpers/project'
|
|
import type { EventBusEmit } from '@/modules/shared/services/eventBus'
|
|
import { Roles } from '@speckle/shared'
|
|
import cryptoRandomString from 'crypto-random-string'
|
|
import type { GetExplicitProjects } from '@/modules/core/domain/streams/operations'
|
|
import type { DeleteProjectCommits } from '@/modules/core/domain/commits/operations'
|
|
|
|
export const createNewProjectFactory =
|
|
({
|
|
storeProject,
|
|
storeProjectRole,
|
|
emitEvent
|
|
}: {
|
|
storeProject: StoreProject
|
|
storeProjectRole: StoreProjectRole
|
|
emitEvent: EventBusEmit
|
|
}): CreateProject =>
|
|
async ({ description, name, regionKey, visibility, workspaceId, ownerId }) => {
|
|
visibility =
|
|
visibility ||
|
|
(workspaceId ? ProjectVisibility.Workspace : ProjectVisibility.Private)
|
|
|
|
const project: Project = {
|
|
id: cryptoRandomString({ length: 10 }),
|
|
name: name || generateProjectName(),
|
|
description: description || '',
|
|
visibility: mapGqlToDbProjectVisibility(visibility),
|
|
createdAt: new Date(),
|
|
clonedFrom: null,
|
|
updatedAt: new Date(),
|
|
workspaceId: workspaceId || null,
|
|
regionKey: regionKey || null,
|
|
allowPublicComments: false
|
|
}
|
|
|
|
await storeProject({ project })
|
|
const projectId = project.id
|
|
|
|
await storeProjectRole({ projectId, userId: ownerId, role: Roles.Stream.Owner })
|
|
|
|
await emitEvent({
|
|
eventName: ProjectEvents.Created,
|
|
payload: {
|
|
project,
|
|
ownerId,
|
|
input: {
|
|
description: project.description,
|
|
name: project.name,
|
|
visibility
|
|
}
|
|
}
|
|
})
|
|
|
|
await emitEvent({
|
|
eventName: ProjectEvents.PermissionsAdded,
|
|
payload: {
|
|
project,
|
|
activityUserId: ownerId,
|
|
targetUserId: ownerId,
|
|
role: Roles.Stream.Owner,
|
|
previousRole: null
|
|
}
|
|
})
|
|
return project
|
|
}
|
|
|
|
export const queryAllProjectsFactory = ({
|
|
getExplicitProjects
|
|
}: {
|
|
getExplicitProjects: GetExplicitProjects
|
|
}): QueryAllProjects =>
|
|
async function* queryAllWorkspaceProjects({
|
|
userId,
|
|
workspaceId
|
|
}): AsyncGenerator<StreamWithOptionalRole[], void, unknown> {
|
|
let currentCursor: string | null = null
|
|
let iterationCount = 0
|
|
|
|
if (!userId && !workspaceId)
|
|
throw new ProjectQueryError('No user or workspace ID provided')
|
|
|
|
do {
|
|
if (iterationCount > 500) throw new ProjectQueryError('Too many iterations')
|
|
|
|
const { items, cursor } = await getExplicitProjects({
|
|
cursor: currentCursor,
|
|
limit: 100,
|
|
filter: {
|
|
workspaceId,
|
|
userId
|
|
}
|
|
})
|
|
|
|
yield items
|
|
|
|
currentCursor = cursor
|
|
iterationCount++
|
|
} while (!!currentCursor)
|
|
}
|
|
|
|
export const deleteProjectAndCommitsFactory =
|
|
(deps: {
|
|
deleteProject: DeleteProject
|
|
deleteProjectCommits: DeleteProjectCommits
|
|
}): DeleteProjectAndCommits =>
|
|
async (project) => {
|
|
await deps.deleteProjectCommits(project)
|
|
await deps.deleteProject(project)
|
|
}
|