diff --git a/packages/server/modules/cli/commands/test/test-meta.ts b/packages/server/modules/cli/commands/test/test-meta.ts index e9d9bb33f..39832b853 100644 --- a/packages/server/modules/cli/commands/test/test-meta.ts +++ b/packages/server/modules/cli/commands/test/test-meta.ts @@ -3,6 +3,7 @@ import { cliLogger } from '@/logging/logging' import { metaHelpers } from '@/modules/core/helpers/meta' import { Users } from '@/modules/core/dbSchema' import { UserRecord, UsersMetaRecord } from '@/modules/core/helpers/types' +import { db } from '@/db/knex' const command: CommandModule = { command: 'test-meta', @@ -18,7 +19,7 @@ const command: CommandModule = { return } - const meta = metaHelpers(Users) + const meta = metaHelpers(Users, db) // set value cliLogger.info(await meta.set(firstUserId, 'foo', false)) diff --git a/packages/server/modules/core/domain/streams/operations.ts b/packages/server/modules/core/domain/streams/operations.ts index f721999fe..cefcbc052 100644 --- a/packages/server/modules/core/domain/streams/operations.ts +++ b/packages/server/modules/core/domain/streams/operations.ts @@ -186,6 +186,11 @@ export type MarkBranchStreamUpdated = (branchId: string) => Promise export type MarkCommitStreamUpdated = (commitId: string) => Promise +export type MarkOnboardingBaseStream = ( + streamId: string, + version: string +) => Promise + export type GetBatchUserFavoriteData = (params: { userId: string streamIds: string[] diff --git a/packages/server/modules/core/helpers/meta.ts b/packages/server/modules/core/helpers/meta.ts index 223834884..8509a2296 100644 --- a/packages/server/modules/core/helpers/meta.ts +++ b/packages/server/modules/core/helpers/meta.ts @@ -3,6 +3,7 @@ import { Nullable } from '@speckle/shared' import { SchemaConfig, MetaSchemaConfig } from '@/modules/core/dbSchema' import { camelCase, isString } from 'lodash' +import { Knex } from 'knex' /** * All meta records must follow this interface @@ -20,7 +21,9 @@ export interface BaseMetaRecord { export function metaHelpers< R extends BaseMetaRecord, S extends SchemaConfig> ->(table: S) { +>(table: S, knex: Knex) { + const db = () => knex(table.meta.name) + return { /** * Get a single value @@ -29,8 +32,7 @@ export function metaHelpers< id: string, key: keyof S['meta']['metaKey'] ): Promise> => { - const q = table.meta - .knex() + const q = db() .where(table.meta.col.key, key) .andWhere(table.meta.parentIdentityCol, id) .first() @@ -50,8 +52,8 @@ export function metaHelpers< requests: Array<{ id: string; key: keyof S['meta']['metaKey'] }> ) => { const meta = table.meta.withoutTablePrefix - const q = table.meta - .knex>() + const q = db() + .select>('*') .whereIn( table.meta.col.key, requests.map((r) => r.key) @@ -84,8 +86,7 @@ export function metaHelpers< val: any ) => { const meta = table.meta.withoutTablePrefix - const q = table.meta - .knex() + const q = db() .insert({ [meta.parentIdentityCol]: id, [meta.col.key]: key, @@ -102,8 +103,7 @@ export function metaHelpers< * Delete meta entry entirely */ delete: async (id: string, key: keyof S['meta']['metaKey']) => { - const q = table.meta - .knex() + const q = db() .where(table.meta.col.key, key) .andWhere(table.meta.parentIdentityCol, id) .del() diff --git a/packages/server/modules/core/loaders.ts b/packages/server/modules/core/loaders.ts index 3fdf6bf4e..728f883c0 100644 --- a/packages/server/modules/core/loaders.ts +++ b/packages/server/modules/core/loaders.ts @@ -499,7 +499,7 @@ export function buildRequestLoaders( string >( async (requests) => { - const meta = metaHelpers(Users) + const meta = metaHelpers(Users, db) const results = await meta.getMultiple( requests.map((r) => ({ id: r.userId, diff --git a/packages/server/modules/core/repositories/streams.ts b/packages/server/modules/core/repositories/streams.ts index 6a4f632cc..6536ad72b 100644 --- a/packages/server/modules/core/repositories/streams.ts +++ b/packages/server/modules/core/repositories/streams.ts @@ -51,7 +51,6 @@ import { } from '@/modules/core/errors/stream' import { metaHelpers } from '@/modules/core/helpers/meta' import { removePrivateFields } from '@/modules/core/helpers/userHelper' -import { db } from '@/db/knex' import { DeleteProjectRole, GetProject, @@ -97,7 +96,8 @@ import { GetUserStreamsPage, GetUserStreamsCount, MarkBranchStreamUpdated, - MarkCommitStreamUpdated + MarkCommitStreamUpdated, + MarkOnboardingBaseStream } from '@/modules/core/domain/streams/operations' export type { StreamWithOptionalRole, StreamWithCommitId } @@ -1177,18 +1177,20 @@ export const revokeStreamPermissionsFactory = /** * Mark stream as the onboarding base stream from which user onboarding streams will be cloned */ -export async function markOnboardingBaseStream(streamId: string, version: string) { - const stream = await getStreamFactory({ db })({ streamId }) - if (!stream) { - throw new Error(`Stream ${streamId} not found`) +export const markOnboardingBaseStreamFactory = + (deps: { db: Knex }): MarkOnboardingBaseStream => + async (streamId: string, version: string) => { + const stream = await getStreamFactory(deps)({ streamId }) + if (!stream) { + throw new Error(`Stream ${streamId} not found`) + } + await updateStreamFactory(deps)({ + id: streamId, + name: 'Onboarding Stream Local Source - Do Not Delete' + }) + const meta = metaHelpers(Streams, deps.db) + await meta.set(streamId, Streams.meta.metaKey.onboardingBaseStream, version) } - await updateStreamFactory({ db })({ - id: streamId, - name: 'Onboarding Stream Local Source - Do Not Delete' - }) - const meta = metaHelpers(Streams) - await meta.set(streamId, Streams.meta.metaKey.onboardingBaseStream, version) -} /** * Get onboarding base stream, if any diff --git a/packages/server/modules/core/repositories/users.ts b/packages/server/modules/core/repositories/users.ts index 9fc4008ca..66bbf178d 100644 --- a/packages/server/modules/core/repositories/users.ts +++ b/packages/server/modules/core/repositories/users.ts @@ -206,7 +206,7 @@ export async function markUserAsVerified(email: string) { export async function markOnboardingComplete(userId: string) { if (!userId) return false - const meta = metaHelpers(Users) + const meta = metaHelpers(Users, db) const newMeta = await meta.set(userId, 'isOnboardingFinished', true) return !!newMeta.value diff --git a/packages/server/modules/cross-server-sync/index.ts b/packages/server/modules/cross-server-sync/index.ts index 16b4afa48..ad2563af0 100644 --- a/packages/server/modules/cross-server-sync/index.ts +++ b/packages/server/modules/cross-server-sync/index.ts @@ -49,7 +49,7 @@ import { getStreamCollaboratorsFactory, getStreamFactory, markCommitStreamUpdatedFactory, - markOnboardingBaseStream + markOnboardingBaseStreamFactory } from '@/modules/core/repositories/streams' import { getFirstAdmin, getUser, getUsers } from '@/modules/core/repositories/users' import { createBranchAndNotifyFactory } from '@/modules/core/services/branch/management' @@ -82,6 +82,7 @@ const crossServerSyncModule: SpeckleModule = { finalize() { crossServerSyncLogger.info('⬇️ Ensuring base onboarding stream asynchronously...') + const markOnboardingBaseStream = markOnboardingBaseStreamFactory({ db }) const markCommitStreamUpdated = markCommitStreamUpdatedFactory({ db }) const getStream = getStreamFactory({ db }) const getObject = getObjectFactory({ db }) diff --git a/packages/server/modules/cross-server-sync/services/onboardingProject.ts b/packages/server/modules/cross-server-sync/services/onboardingProject.ts index 2cb29cc66..da536388b 100644 --- a/packages/server/modules/cross-server-sync/services/onboardingProject.ts +++ b/packages/server/modules/cross-server-sync/services/onboardingProject.ts @@ -1,6 +1,8 @@ import { crossServerSyncLogger } from '@/logging/logging' -import { GetOnboardingBaseStream } from '@/modules/core/domain/streams/operations' -import { markOnboardingBaseStream } from '@/modules/core/repositories/streams' +import { + GetOnboardingBaseStream, + MarkOnboardingBaseStream +} from '@/modules/core/domain/streams/operations' import { getFirstAdmin } from '@/modules/core/repositories/users' import { DownloadProject, @@ -39,7 +41,7 @@ export const ensureOnboardingProjectFactory = getOnboardingBaseStream: GetOnboardingBaseStream getFirstAdmin: typeof getFirstAdmin downloadProject: DownloadProject - markOnboardingBaseStream: typeof markOnboardingBaseStream + markOnboardingBaseStream: MarkOnboardingBaseStream }): EnsureOnboardingProject => async () => { const logger = crossServerSyncLogger