diff --git a/packages/server/modules/core/services/streams/onboarding.ts b/packages/server/modules/core/services/streams/onboarding.ts index d747c7163..a71ae917d 100644 --- a/packages/server/modules/core/services/streams/onboarding.ts +++ b/packages/server/modules/core/services/streams/onboarding.ts @@ -7,8 +7,11 @@ import { cloneStream } from '@/modules/core/services/streams/clone' import { StreamRecord } from '@/modules/core/helpers/types' import { logger } from '@/logging/logging' import { createStreamReturnRecord } from '@/modules/core/services/streams/management' -import { getOnboardingBaseProject } from '@/modules/cross-server-sync/services/onboardingProject' -import { updateStream } from '@/modules/core/repositories/streams' +import { getOnboardingBaseProjectFactory } from '@/modules/cross-server-sync/services/onboardingProject' +import { + getOnboardingBaseStream, + updateStream +} from '@/modules/core/repositories/streams' import { getUser } from '@/modules/core/services/users' import { ContextResourceAccessRules, @@ -30,7 +33,9 @@ export async function createOnboardingStream( ) } - const sourceStream = await getOnboardingBaseProject() + const sourceStream = await getOnboardingBaseProjectFactory({ + getOnboardingBaseStream + })() // clone from base let newStream: Optional = undefined if (sourceStream) { diff --git a/packages/server/modules/cross-server-sync/domain/operations.ts b/packages/server/modules/cross-server-sync/domain/operations.ts index b54c8100b..d9c4be767 100644 --- a/packages/server/modules/cross-server-sync/domain/operations.ts +++ b/packages/server/modules/cross-server-sync/domain/operations.ts @@ -64,3 +64,6 @@ export type DownloadProject = ( projectId: string project: StreamRecord }> + +export type GetOnboardingBaseProject = () => Promise +export type EnsureOnboardingProject = () => Promise diff --git a/packages/server/modules/cross-server-sync/index.ts b/packages/server/modules/cross-server-sync/index.ts index 4108fa818..bb38c6281 100644 --- a/packages/server/modules/cross-server-sync/index.ts +++ b/packages/server/modules/cross-server-sync/index.ts @@ -1,5 +1,24 @@ import { moduleLogger, crossServerSyncLogger } from '@/logging/logging' -import { ensureOnboardingProject } from '@/modules/cross-server-sync/services/onboardingProject' +import { + createCommentReplyAndNotify, + createCommentThreadAndNotify +} from '@/modules/comments/services/management' +import { getStreamBranchByName } from '@/modules/core/repositories/branches' +import { getObject } from '@/modules/core/repositories/objects' +import { + getOnboardingBaseStream, + getStream, + getStreamCollaborators, + markOnboardingBaseStream +} from '@/modules/core/repositories/streams' +import { getFirstAdmin, getUser } from '@/modules/core/repositories/users' +import { createBranchAndNotify } from '@/modules/core/services/branch/management' +import { createCommitByBranchId } from '@/modules/core/services/commit/management' +import { createObject } from '@/modules/core/services/objects' +import { createStreamReturnRecord } from '@/modules/core/services/streams/management' +import { downloadCommitFactory } from '@/modules/cross-server-sync/services/commit' +import { ensureOnboardingProjectFactory } from '@/modules/cross-server-sync/services/onboardingProject' +import { downloadProjectFactory } from '@/modules/cross-server-sync/services/project' import { SpeckleModule } from '@/modules/shared/helpers/typeHelper' const crossServerSyncModule: SpeckleModule = { @@ -8,6 +27,29 @@ const crossServerSyncModule: SpeckleModule = { }, finalize() { crossServerSyncLogger.info('⬇️ Ensuring base onboarding stream asynchronously...') + const ensureOnboardingProject = ensureOnboardingProjectFactory({ + getOnboardingBaseStream, + getFirstAdmin, + downloadProject: downloadProjectFactory({ + downloadCommit: downloadCommitFactory({ + getStream, + getStreamBranchByName, + getStreamCollaborators, + getUser, + createCommitByBranchId, + createObject, + getObject, + createCommentThreadAndNotify, + createCommentReplyAndNotify + }), + createStreamReturnRecord, + getUser, + getStreamBranchByName, + createBranchAndNotify + }), + markOnboardingBaseStream + }) + void ensureOnboardingProject().catch((err) => crossServerSyncLogger.error(err, 'Error ensuring onboarding stream') ) diff --git a/packages/server/modules/cross-server-sync/services/onboardingProject.ts b/packages/server/modules/cross-server-sync/services/onboardingProject.ts index a83cef85f..7fc60c396 100644 --- a/packages/server/modules/cross-server-sync/services/onboardingProject.ts +++ b/packages/server/modules/cross-server-sync/services/onboardingProject.ts @@ -1,23 +1,14 @@ import { crossServerSyncLogger } from '@/logging/logging' -import { - createCommentReplyAndNotify, - createCommentThreadAndNotify -} from '@/modules/comments/services/management' -import { getStreamBranchByName } from '@/modules/core/repositories/branches' -import { getObject } from '@/modules/core/repositories/objects' import { getOnboardingBaseStream, - getStream, - getStreamCollaborators, markOnboardingBaseStream } from '@/modules/core/repositories/streams' -import { getFirstAdmin, getUser } from '@/modules/core/repositories/users' -import { createBranchAndNotify } from '@/modules/core/services/branch/management' -import { createCommitByBranchId } from '@/modules/core/services/commit/management' -import { createObject } from '@/modules/core/services/objects' -import { createStreamReturnRecord } from '@/modules/core/services/streams/management' -import { downloadCommitFactory } from '@/modules/cross-server-sync/services/commit' -import { downloadProjectFactory } from '@/modules/cross-server-sync/services/project' +import { getFirstAdmin } from '@/modules/core/repositories/users' +import { + DownloadProject, + EnsureOnboardingProject, + GetOnboardingBaseProject +} from '@/modules/cross-server-sync/domain/operations' import { getOnboardingStreamCacheBustNumber, getOnboardingStreamUrl @@ -32,70 +23,64 @@ const getMetadata = () => { return { url, cacheBustNumber, version } } -export async function getOnboardingBaseProject() { - const metadata = getMetadata() - if (!metadata) { - return undefined +export const getOnboardingBaseProjectFactory = + (deps: { + getOnboardingBaseStream: typeof getOnboardingBaseStream + }): GetOnboardingBaseProject => + async () => { + const metadata = getMetadata() + if (!metadata) { + return undefined + } + + return await deps.getOnboardingBaseStream(metadata.version) } - return await getOnboardingBaseStream(metadata.version) -} +export const ensureOnboardingProjectFactory = + (deps: { + getOnboardingBaseStream: typeof getOnboardingBaseStream + getFirstAdmin: typeof getFirstAdmin + downloadProject: DownloadProject + markOnboardingBaseStream: typeof markOnboardingBaseStream + }): EnsureOnboardingProject => + async () => { + const logger = crossServerSyncLogger + logger.info('Ensuring onboarding project is present...') -export async function ensureOnboardingProject() { - const logger = crossServerSyncLogger - logger.info('Ensuring onboarding project is present...') + const metadata = getMetadata() + if (!metadata) { + logger.info('No base onboarding stream configured through env vars...') + return undefined + } - const metadata = getMetadata() - if (!metadata) { - logger.info('No base onboarding stream configured through env vars...') - return undefined + const [existingStream, admin] = await Promise.all([ + deps.getOnboardingBaseStream(metadata.version), + deps.getFirstAdmin() + ]) + if (existingStream) { + logger.info('Onboarding stream already exists, skipping...') + return existingStream + } + if (!admin) { + logger.info('No admin user found, skipping onboarding stream creation...') + return undefined + } + + logger.info('Onboarding stream not found, pulling from target server...') + + const res = await deps.downloadProject( + { + projectUrl: metadata.url, + authorId: admin.id, + syncComments: true + }, + { logger } + ) + + logger.info('Marking stream as onboarding base...') + await deps.markOnboardingBaseStream(res.projectId, metadata.version) + + logger.info('Onboarding base stream created successfully!') + + return res.project } - - const [existingStream, admin] = await Promise.all([ - getOnboardingBaseStream(metadata.version), - getFirstAdmin() - ]) - if (existingStream) { - logger.info('Onboarding stream already exists, skipping...') - return existingStream - } - if (!admin) { - logger.info('No admin user found, skipping onboarding stream creation...') - return undefined - } - - logger.info('Onboarding stream not found, pulling from target server...') - - const downloadProject = downloadProjectFactory({ - downloadCommit: downloadCommitFactory({ - getStream, - getStreamBranchByName, - getStreamCollaborators, - getUser, - createCommitByBranchId, - createObject, - getObject, - createCommentThreadAndNotify, - createCommentReplyAndNotify - }), - createStreamReturnRecord, - getUser, - getStreamBranchByName, - createBranchAndNotify - }) - const res = await downloadProject( - { - projectUrl: metadata.url, - authorId: admin.id, - syncComments: true - }, - { logger } - ) - - logger.info('Marking stream as onboarding base...') - await markOnboardingBaseStream(res.projectId, metadata.version) - - logger.info('Onboarding base stream created successfully!') - - return res.project -}