From d067c5148c1432cea8dbce97ac0bfe57366cd996 Mon Sep 17 00:00:00 2001 From: Alessandro Magionami Date: Fri, 4 Apr 2025 10:54:15 +0200 Subject: [PATCH] chore(core): limit versions --- .../modules/core/graph/resolvers/versions.ts | 34 +++++++++++++++++- .../modules/core/services/versions/limits.ts | 36 +++++++++++++++++++ packages/shared/src/environment/index.ts | 12 +++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 packages/server/modules/core/services/versions/limits.ts diff --git a/packages/server/modules/core/graph/resolvers/versions.ts b/packages/server/modules/core/graph/resolvers/versions.ts index 475a039fc..21b809bed 100644 --- a/packages/server/modules/core/graph/resolvers/versions.ts +++ b/packages/server/modules/core/graph/resolvers/versions.ts @@ -5,7 +5,7 @@ import { filteredSubscribe, ProjectSubscriptions } from '@/modules/shared/utils/subscriptions' -import { getServerOrigin } from '@/modules/shared/helpers/envHelper' +import { getFeatureFlags, getServerOrigin } from '@/modules/shared/helpers/envHelper' import { batchDeleteCommitsFactory, batchMoveCommitsFactory @@ -50,6 +50,12 @@ import { getProjectDbClient } from '@/modules/multiregion/utils/dbSelector' import coreModule from '@/modules/core' import { getEventBus } from '@/modules/shared/services/eventBus' import { StreamNotFoundError } from '@/modules/core/errors/stream' +import { getLimitedReferencedObjectFactory } from '@/modules/core/services/versions/limits' + +const { + FF_FORCE_PERSONAL_PROJECTS_LIMITS_ENABLED, + FF_WEB_2944_VERSIONS_LIMITS_ENABLED +} = getFeatureFlags() export = { Project: { @@ -93,6 +99,32 @@ export = { }) const path = `/preview/${stream.id}/commits/${parent.id}` return new URL(path, getServerOrigin()).toString() + }, + referencedObject: async (parent, _args, ctx) => { + if (!FF_WEB_2944_VERSIONS_LIMITS_ENABLED) { + return parent.referencedObject + } + const projectDB = await getProjectDbClient({ projectId: parent.streamId }) + const project = await ctx.loaders + .forRegion({ db: projectDB }) + .commits.getCommitStream.load(parent.id) + + if (!project) { + throw new StreamNotFoundError('Project not found', { + info: { streamId: parent.streamId } + }) + } + + const lastVersion = await ctx.loaders.streams.getLastVersion.load(project.id) + if (lastVersion?.id === parent.id) return parent.referencedObject + + return await getLimitedReferencedObjectFactory({ + environment: { + personalProjectsLimitEnabled: FF_FORCE_PERSONAL_PROJECTS_LIMITS_ENABLED + } + // getWorkspacePlan: ctx.loaders.gatekeeper?.getWorkspacePlan + // .load as GetWorkspacePlan + })({ version: parent, project }) } }, Mutation: { diff --git a/packages/server/modules/core/services/versions/limits.ts b/packages/server/modules/core/services/versions/limits.ts new file mode 100644 index 000000000..42ffcec21 --- /dev/null +++ b/packages/server/modules/core/services/versions/limits.ts @@ -0,0 +1,36 @@ +import { Version } from '@/modules/core/domain/commits/types' +import { Project } from '@/modules/core/domain/streams/types' +import dayjs from 'dayjs' + +export const getLimitedReferencedObjectFactory = + ({ + environment: { personalProjectsLimitEnabled } + }: // getWorkspacePlan + { + environment: { personalProjectsLimitEnabled: boolean } + // getWorkspacePlan: GetWorkspacePlan + }) => + async ({ + version, + project + }: { + version: Pick + project: Pick + }) => { + if (project?.workspaceId) { + // TODO: needs the plan to get limits according to it + // const workspacePlan = await getWorkspacePlan({ + // workspaceId: project.workspaceId + // }) + // TODO: get plan limits + } + + if (!personalProjectsLimitEnabled) { + return version.referencedObject + } + + const oneWeekAgo = dayjs().subtract(1, 'week') + + if (oneWeekAgo.isAfter(version.createdAt)) return '' + return version.referencedObject + } diff --git a/packages/shared/src/environment/index.ts b/packages/shared/src/environment/index.ts index b037457ae..87607ac5b 100644 --- a/packages/shared/src/environment/index.ts +++ b/packages/shared/src/environment/index.ts @@ -83,6 +83,16 @@ export const parseFeatureFlags = ( FF_MOVE_PROJECT_REGION_ENABLED: { schema: z.boolean(), defaults: { production: false, _: true } + }, + // Enable limits on personal projects + FF_FORCE_PERSONAL_PROJECTS_LIMITS_ENABLED: { + schema: z.boolean(), + defaults: { production: false, _: false } + }, + // Temporary FF to enable WIP on version limits + FF_WEB_2944_VERSIONS_LIMITS_ENABLED: { + schema: z.boolean(), + defaults: { production: false, _: false } } }) @@ -113,6 +123,8 @@ export type FeatureFlags = { FF_OBJECTS_STREAMING_FIX: boolean FF_MOVE_PROJECT_REGION_ENABLED: boolean FF_NO_PERSONAL_EMAILS_ENABLED: boolean + FF_FORCE_PERSONAL_PROJECTS_LIMITS_ENABLED: boolean + FF_WEB_2944_VERSIONS_LIMITS_ENABLED: boolean } export function getFeatureFlags(): FeatureFlags {