feat(multiregion): apply prepared transactions to projects (#5322)

* 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>
This commit is contained in:
Daniel Gak Anagrov
2025-09-04 12:07:19 +01:00
committed by GitHub
parent 6692fdf4aa
commit 399c998fd7
45 changed files with 923 additions and 938 deletions
@@ -57,17 +57,11 @@ import { authorizeResolver } from '@/modules/shared'
import { Roles } from '@speckle/shared'
import { getDefaultRegionFactory } from '@/modules/workspaces/repositories/regions'
import { getDb } from '@/modules/multiregion/utils/dbSelector'
import { createNewProjectFactory } from '@/modules/core/services/projects'
import {
createNewProjectFactory,
waitForRegionProjectFactory
} from '@/modules/core/services/projects'
import {
deleteProjectFactory,
getProjectFactory,
storeProjectFactory,
storeProjectRoleFactory
} from '@/modules/core/repositories/projects'
import { storeModelFactory } from '@/modules/core/repositories/models'
import { getEventBus } from '@/modules/shared/services/eventBus'
import {
getViewerResourceGroupsFactory,
@@ -202,14 +196,11 @@ const command: CommandModule<
const getUser = getUserFactory({ db })
const createNewProject = createNewProjectFactory({
// TODO: this goes as event emmits outside (default model)
// This does not support multiregion
storeProject: storeProjectFactory({ db: projectDb }),
storeModel: storeModelFactory({ db: projectDb }),
// THIS MUST GO TO THE MAIN DB
storeProjectRole: storeProjectRoleFactory({ db }),
waitForRegionProject: waitForRegionProjectFactory({
getProject: getProjectFactory({ db: projectDb }),
deleteProject: deleteProjectFactory({ db: projectDb })
}),
emitEvent: getEventBus().emit
})
@@ -23,8 +23,9 @@ import {
import { getUserFactory } from '@/modules/core/repositories/users'
import { cloneStreamFactory } from '@/modules/core/services/streams/clone'
import type { CommandModule } from 'yargs'
import { asOperation } from '@/modules/shared/command'
import { asMultiregionalOperation, replicateFactory } from '@/modules/shared/command'
import { storeProjectRoleFactory } from '@/modules/core/repositories/projects'
import { db } from '@/db/knex'
const command: CommandModule<
unknown,
@@ -48,34 +49,34 @@ const command: CommandModule<
logger.info(
`Cloning stream ${sourceStreamId} into the account of user ${targetUserId}...`
)
const { id } = await asOperation(
({ emit, db }) => {
const { id } = await asMultiregionalOperation(
({ emit, mainDb, allDbs }) => {
const cloneStream = cloneStreamFactory({
getStream: getStreamFactory({ db }),
getUser: getUserFactory({ db }),
newProjectDb: db,
sourceProjectDb: db,
createStream: createStreamFactory({ db }),
insertCommits: insertCommitsFactory({ db }),
getBatchedStreamCommits: getBatchedStreamCommitsFactory({ db }),
insertStreamCommits: insertStreamCommitsFactory({ db }),
getBatchedStreamBranches: getBatchedStreamBranchesFactory({ db }),
insertBranches: insertBranchesFactory({ db }),
getBatchedBranchCommits: getBatchedBranchCommitsFactory({ db }),
insertBranchCommits: insertBranchCommitsFactory({ db }),
getBatchedStreamComments: getBatchedStreamCommentsFactory({ db }),
insertComments: insertCommentsFactory({ db }),
getCommentLinks: getCommentLinksFactory({ db }),
insertCommentLinks: insertCommentLinksFactory({ db }),
getStream: getStreamFactory({ db: mainDb }),
getUser: getUserFactory({ db: mainDb }),
newProjectDb: mainDb,
sourceProjectDb: mainDb,
createStream: replicateFactory(allDbs, createStreamFactory),
insertCommits: insertCommitsFactory({ db: mainDb }),
getBatchedStreamCommits: getBatchedStreamCommitsFactory({ db: mainDb }),
insertStreamCommits: insertStreamCommitsFactory({ db: mainDb }),
getBatchedStreamBranches: getBatchedStreamBranchesFactory({ db: mainDb }),
insertBranches: insertBranchesFactory({ db: mainDb }),
getBatchedBranchCommits: getBatchedBranchCommitsFactory({ db: mainDb }),
insertBranchCommits: insertBranchCommitsFactory({ db: mainDb }),
getBatchedStreamComments: getBatchedStreamCommentsFactory({ db: mainDb }),
insertComments: insertCommentsFactory({ db: mainDb }),
getCommentLinks: getCommentLinksFactory({ db: mainDb }),
insertCommentLinks: insertCommentLinksFactory({ db: mainDb }),
emitEvent: emit,
storeProjectRole: storeProjectRoleFactory({ db })
storeProjectRole: storeProjectRoleFactory({ db: mainDb })
})
return cloneStream(targetUserId, sourceStreamId)
},
{
transaction: true,
name: 'Clone Stream',
dbs: [db], // Cloning does not support multiregion
logger
}
)