Metadata api create entity in workspace custom app (#15911)
# Introduction Cleaner and fewer scope version of https://github.com/twentyhq/twenty/pull/15745 ( removed sync-metadata hack through, too ambitious migration and upgrade ) Please note that this PR won't have any interaction with the existing sync-metadata Which mean that the sync metadata does not update the standard entities applicationId and universalIdentifier, and it won't we will deprecate it on favor of a workspace migration aka twenty-standard app installation ## API Metadata Any operation going through the api metadata nows automatically scope the related entity to the workspace custom application instance. ( optionally passing an applicationId to allow current hacky implem of app sync service ) We need to either ignore the tests or remove the cli status check from the blocking status badges for a PR to be merged ## New workspace Already handled in previous https://github.com/twentyhq/twenty/pull/15625, when a workspace is created it gets created a twenty standard and custom workspace instance All his views and permissions will be prefilled to the its twenty standard app instance with a specific universalIdentifier ## New universalIdentifier At the contrary as before with standardIds, universalIdentifier are unique for a given workspace This means that createdAt field of both object company and opportunity will have a unique universalIdentifier whereas they share the same standardId ## FlatApplication Introduced the flatApplication and cache. Will migrate existing `MetadataName` to be `SyncableMetadataName` in a following PR ## What's next Next we will describe a twenty standard app configuration as json that will be used to generate a workspace migration that will be run instead of the sync metadata, in a nutshell we aim to deprecated the sync metadata So we can standardize any entity to have a non nullable applicationId and universalIdentifier ## Upgrade command Introduced an upgrade command that will create a custom workspace instance for any workspace that do not have one in order to align with the new behavior when creating a new workspace
This commit is contained in:
+2
@@ -1,6 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
|
||||
import { TokenModule } from 'src/engine/core-modules/auth/token/token.module';
|
||||
import { WorkspaceDomainsModule } from 'src/engine/core-modules/domain/workspace-domains/workspace-domains.module';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
@@ -17,6 +18,7 @@ import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspa
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([RouteTriggerEntity]),
|
||||
ApplicationModule,
|
||||
TokenModule,
|
||||
WorkspaceDomainsModule,
|
||||
ServerlessFunctionModule,
|
||||
|
||||
+16
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
@@ -23,12 +24,25 @@ export class RouteTriggerV2Service {
|
||||
constructor(
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
) {}
|
||||
|
||||
async createOne(
|
||||
routeTriggerInput: CreateRouteTriggerInput,
|
||||
workspaceId: string,
|
||||
/**
|
||||
* @deprecated do not use call validateBuildAndRunWorkspaceMigration contextually
|
||||
* when interacting with another application than workspace custom one
|
||||
* */
|
||||
applicationId?: string,
|
||||
) {
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
const flatEntityMaps =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
@@ -43,6 +57,8 @@ export class RouteTriggerV2Service {
|
||||
fromCreateRouteTriggerInputToFlatRouteTrigger({
|
||||
createRouteTriggerInput: routeTriggerInput,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId:
|
||||
applicationId ?? workspaceCustomFlatApplication.id,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
|
||||
+6
-4
@@ -6,16 +6,18 @@ import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger
|
||||
export const fromCreateRouteTriggerInputToFlatRouteTrigger = ({
|
||||
createRouteTriggerInput,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId,
|
||||
}: {
|
||||
createRouteTriggerInput: CreateRouteTriggerInput;
|
||||
workspaceId: string;
|
||||
workspaceCustomApplicationId: string;
|
||||
}): FlatRouteTrigger => {
|
||||
const now = new Date();
|
||||
const id = uuidV4();
|
||||
|
||||
return {
|
||||
id: uuidV4(),
|
||||
universalIdentifier:
|
||||
createRouteTriggerInput.universalIdentifier ?? uuidV4(),
|
||||
id,
|
||||
universalIdentifier: createRouteTriggerInput.universalIdentifier ?? id,
|
||||
path: createRouteTriggerInput.path,
|
||||
isAuthRequired: createRouteTriggerInput.isAuthRequired,
|
||||
httpMethod: createRouteTriggerInput.httpMethod,
|
||||
@@ -23,6 +25,6 @@ export const fromCreateRouteTriggerInputToFlatRouteTrigger = ({
|
||||
workspaceId,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
applicationId: createRouteTriggerInput.applicationId ?? null,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user