Added all field types on pet custom object (#9248)

- Added all usable composite field types on pet custom object
- Fixed missing createdBy on people and company seeds
- DEFAULT_SUBDOMAIN is now used for login (could be improved for multi
workspace)
- Refactored ObjectMetadataStandardIdToIdMap to disambiguate from
ObjectMetadataMap
- Refactored seedCustomObjects
This commit is contained in:
Lucas Bordeau
2024-12-27 15:01:09 +01:00
committed by GitHub
parent 58c92e036b
commit a8bb3e6bdf
27 changed files with 742 additions and 5428 deletions

View File

@ -1,18 +1,17 @@
import { Logger } from '@nestjs/common';
import { Command, CommandRunner } from 'nest-commander';
import { EntityManager } from 'typeorm';
import { DataSource, EntityManager } from 'typeorm';
import { seedCoreSchema } from 'src/database/typeorm-seeds/core';
import {
SEED_APPLE_WORKSPACE_ID,
SEED_ACME_WORKSPACE_ID,
SEED_APPLE_WORKSPACE_ID,
} from 'src/database/typeorm-seeds/core/workspaces';
import {
getDevSeedCompanyCustomFields,
getDevSeedPeopleCustomFields,
} from 'src/database/typeorm-seeds/metadata/fieldsMetadata';
import { getDevSeedCustomObjects } from 'src/database/typeorm-seeds/metadata/objectsMetadata';
import { seedCalendarChannels } from 'src/database/typeorm-seeds/workspace/calendar-channel';
import { seedCalendarChannelEventAssociations } from 'src/database/typeorm-seeds/workspace/calendar-channel-event-association';
import { seedCalendarEventParticipants } from 'src/database/typeorm-seeds/workspace/calendar-event-participants';
@ -27,7 +26,7 @@ import { seedMessageThreadSubscribers } from 'src/database/typeorm-seeds/workspa
import { seedMessageThread } from 'src/database/typeorm-seeds/workspace/message-threads';
import { seedMessage } from 'src/database/typeorm-seeds/workspace/messages';
import { seedOpportunity } from 'src/database/typeorm-seeds/workspace/opportunities';
import { seedPeople } from 'src/database/typeorm-seeds/workspace/people';
import { seedPeople } from 'src/database/typeorm-seeds/workspace/seedPeople';
import { seedWorkspaceMember } from 'src/database/typeorm-seeds/workspace/workspace-members';
import { rawDataSource } from 'src/database/typeorm/raw/raw.datasource';
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
@ -36,10 +35,15 @@ import { CacheStorageService } from 'src/engine/core-modules/cache-storage/servi
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
import { PETS_DATA_SEEDS } from 'src/engine/seeder/data-seeds/pets-data-seeds';
import { SURVEY_RESULTS_DATA_SEEDS } from 'src/engine/seeder/data-seeds/survey-results-data-seeds';
import { PETS_METADATA_SEEDS } from 'src/engine/seeder/metadata-seeds/pets-metadata-seeds';
import { SURVEY_RESULTS_METADATA_SEEDS } from 'src/engine/seeder/metadata-seeds/survey-results-metadata-seeds';
import { SeederService } from 'src/engine/seeder/seeder.service';
import { shouldSeedWorkspaceFavorite } from 'src/engine/utils/should-seed-workspace-favorite';
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
import { seedViewWithDemoData } from 'src/engine/workspace-manager/standard-objects-prefill-data/seed-view-with-demo-data';
@ -66,6 +70,7 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
@InjectCacheStorage(CacheStorageNamespace.EngineWorkspace)
private readonly workspaceSchemaCache: CacheStorageService,
private readonly featureFlagService: FeatureFlagService,
private readonly seederService: SeederService,
) {
super();
}
@ -73,29 +78,7 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
async run(): Promise<void> {
try {
for (const workspaceId of this.workspaceIds) {
await this.workspaceSchemaCache.flush();
await rawDataSource.initialize();
await seedCoreSchema(rawDataSource, workspaceId);
await rawDataSource.destroy();
const schemaName =
await this.workspaceDataSourceService.createWorkspaceDBSchema(
workspaceId,
);
const dataSourceMetadata =
await this.dataSourceService.createDataSourceMetadata(
workspaceId,
schemaName,
);
await this.workspaceSyncMetadataService.synchronize({
workspaceId: workspaceId,
dataSourceId: dataSourceMetadata.id,
});
await this.createWorkspaceSchema(workspaceId);
}
} catch (error) {
this.logger.error(error);
@ -104,150 +87,185 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
}
for (const workspaceId of this.workspaceIds) {
const dataSourceMetadata =
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
await this.seedWorkspace(workspaceId);
}
}
async createWorkspaceSchema(workspaceId: string) {
await this.workspaceSchemaCache.flush();
await rawDataSource.initialize();
await seedCoreSchema(rawDataSource, workspaceId);
await rawDataSource.destroy();
const schemaName =
await this.workspaceDataSourceService.createWorkspaceDBSchema(
workspaceId,
);
const dataSourceMetadata =
await this.dataSourceService.createDataSourceMetadata(
workspaceId,
schemaName,
);
await this.workspaceSyncMetadataService.synchronize({
workspaceId: workspaceId,
dataSourceId: dataSourceMetadata.id,
});
}
async seedWorkspace(workspaceId: string) {
const dataSourceMetadata =
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
workspaceId,
);
const workspaceDataSource =
await this.typeORMService.connectToDataSource(dataSourceMetadata);
if (!workspaceDataSource) {
throw new Error('Could not connect to workspace data source');
}
try {
const { objectMetadataStandardIdToIdMap } =
await this.objectMetadataService.getObjectMetadataStandardIdToIdMap(
workspaceId,
);
const workspaceDataSource =
await this.typeORMService.connectToDataSource(dataSourceMetadata);
await this.seedCompanyCustomFields(
objectMetadataStandardIdToIdMap[STANDARD_OBJECT_IDS.company].id,
workspaceId,
);
if (!workspaceDataSource) {
throw new Error('Could not connect to workspace data source');
}
await this.seedPeopleCustomFields(
objectMetadataStandardIdToIdMap[STANDARD_OBJECT_IDS.person].id,
workspaceId,
);
try {
const objectMetadata =
await this.objectMetadataService.findManyWithinWorkspace(workspaceId);
const objectMetadataMap = objectMetadata.reduce((acc, object) => {
acc[object.standardId ?? ''] = {
id: object.id,
fields: object.fields.reduce((acc, field) => {
acc[field.standardId ?? ''] = field.id;
await this.seedStandardObjectRecords(
workspaceDataSource,
dataSourceMetadata,
);
return acc;
}, {}),
};
await this.seederService.seedCustomObjects(
dataSourceMetadata.id,
workspaceId,
PETS_METADATA_SEEDS,
PETS_DATA_SEEDS,
);
return acc;
}, {});
await this.seederService.seedCustomObjects(
dataSourceMetadata.id,
workspaceId,
SURVEY_RESULTS_METADATA_SEEDS,
SURVEY_RESULTS_DATA_SEEDS,
);
} catch (error) {
this.logger.error(error);
}
await this.typeORMService.disconnectFromDataSource(dataSourceMetadata.id);
}
async seedStandardObjectRecords(
workspaceDataSource: DataSource,
dataSourceMetadata: DataSourceEntity,
) {
await workspaceDataSource.transaction(
async (entityManager: EntityManager) => {
const { objectMetadataStandardIdToIdMap } =
await this.objectMetadataService.getObjectMetadataStandardIdToIdMap(
dataSourceMetadata.workspaceId,
);
const isMessageThreadSubscriberEnabled =
await this.featureFlagService.isFeatureEnabled(
FeatureFlagKey.IsMessageThreadSubscriberEnabled,
workspaceId,
dataSourceMetadata.workspaceId,
);
const isWorkflowEnabled =
await this.featureFlagService.isFeatureEnabled(
FeatureFlagKey.IsWorkflowEnabled,
workspaceId,
dataSourceMetadata.workspaceId,
);
await this.seedCompanyCustomFields(
objectMetadataMap[STANDARD_OBJECT_IDS.company],
workspaceId,
await seedCompanies(entityManager, dataSourceMetadata.schema);
await seedPeople(entityManager, dataSourceMetadata.schema);
await seedOpportunity(entityManager, dataSourceMetadata.schema);
await seedWorkspaceMember(
entityManager,
dataSourceMetadata.schema,
dataSourceMetadata.workspaceId,
);
await this.seedPeopleCustomFields(
objectMetadataMap[STANDARD_OBJECT_IDS.person],
workspaceId,
);
await this.seedCustomObjects(workspaceId, dataSourceMetadata.id);
await workspaceDataSource.transaction(
async (entityManager: EntityManager) => {
await seedCompanies(entityManager, dataSourceMetadata.schema);
await seedPeople(entityManager, dataSourceMetadata.schema);
await seedOpportunity(entityManager, dataSourceMetadata.schema);
await seedWorkspaceMember(
entityManager,
dataSourceMetadata.schema,
workspaceId,
);
if (dataSourceMetadata.workspaceId === SEED_APPLE_WORKSPACE_ID) {
await seedMessageThread(entityManager, dataSourceMetadata.schema);
await seedConnectedAccount(entityManager, dataSourceMetadata.schema);
if (workspaceId === SEED_APPLE_WORKSPACE_ID) {
await seedMessageThread(entityManager, dataSourceMetadata.schema);
await seedConnectedAccount(
entityManager,
dataSourceMetadata.schema,
);
if (isMessageThreadSubscriberEnabled) {
await seedMessageThreadSubscribers(
entityManager,
dataSourceMetadata.schema,
);
}
await seedMessage(entityManager, dataSourceMetadata.schema);
await seedMessageChannel(
entityManager,
dataSourceMetadata.schema,
);
await seedMessageChannelMessageAssociation(
entityManager,
dataSourceMetadata.schema,
);
await seedMessageParticipant(
entityManager,
dataSourceMetadata.schema,
);
await seedCalendarEvents(
entityManager,
dataSourceMetadata.schema,
);
await seedCalendarChannels(
entityManager,
dataSourceMetadata.schema,
);
await seedCalendarChannelEventAssociations(
entityManager,
dataSourceMetadata.schema,
);
await seedCalendarEventParticipants(
entityManager,
dataSourceMetadata.schema,
);
}
const viewDefinitionsWithId = await seedViewWithDemoData(
entityManager,
dataSourceMetadata.schema,
objectMetadataMap,
isWorkflowEnabled,
);
await seedWorkspaceFavorites(
viewDefinitionsWithId
.filter(
(view) =>
view.key === 'INDEX' &&
shouldSeedWorkspaceFavorite(
view.objectMetadataId,
objectMetadataMap,
),
)
.map((view) => view.id),
if (isMessageThreadSubscriberEnabled) {
await seedMessageThreadSubscribers(
entityManager,
dataSourceMetadata.schema,
);
},
);
} catch (error) {
this.logger.error(error);
}
}
await this.typeORMService.disconnectFromDataSource(dataSourceMetadata.id);
}
await seedMessage(entityManager, dataSourceMetadata.schema);
await seedMessageChannel(entityManager, dataSourceMetadata.schema);
await seedMessageChannelMessageAssociation(
entityManager,
dataSourceMetadata.schema,
);
await seedMessageParticipant(
entityManager,
dataSourceMetadata.schema,
);
await seedCalendarEvents(entityManager, dataSourceMetadata.schema);
await seedCalendarChannels(entityManager, dataSourceMetadata.schema);
await seedCalendarChannelEventAssociations(
entityManager,
dataSourceMetadata.schema,
);
await seedCalendarEventParticipants(
entityManager,
dataSourceMetadata.schema,
);
}
const viewDefinitionsWithId = await seedViewWithDemoData(
entityManager,
dataSourceMetadata.schema,
objectMetadataStandardIdToIdMap,
isWorkflowEnabled,
);
await seedWorkspaceFavorites(
viewDefinitionsWithId
.filter(
(view) =>
view.key === 'INDEX' &&
shouldSeedWorkspaceFavorite(
view.objectMetadataId,
objectMetadataStandardIdToIdMap,
),
)
.map((view) => view.id),
entityManager,
dataSourceMetadata.schema,
);
},
);
}
async seedCompanyCustomFields(
companyObjectMetadata: ObjectMetadataEntity,
companyObjectMetadataId: string,
workspaceId: string,
) {
const companyObjectMetadataId = companyObjectMetadata?.id;
if (!companyObjectMetadataId) {
throw new Error(
`Company object metadata not found for workspace ${workspaceId}, can't seed custom fields`,
@ -269,11 +287,9 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
}
async seedPeopleCustomFields(
personObjectMetadata: ObjectMetadataEntity,
personObjectMetadataId: string,
workspaceId: string,
) {
const personObjectMetadataId = personObjectMetadata?.id;
if (!personObjectMetadataId) {
throw new Error(
`Person object metadata not found for workspace ${workspaceId}, can't seed custom fields`,
@ -292,15 +308,4 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
});
}
}
async seedCustomObjects(workspaceId: string, dataSourceId: string) {
const devSeedCustomObjects = getDevSeedCustomObjects(
workspaceId,
dataSourceId,
);
for (const customObject of devSeedCustomObjects) {
await this.objectMetadataService.createOne(customObject);
}
}
}

View File

@ -23,6 +23,7 @@ import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
import { SeederModule } from 'src/engine/seeder/seeder.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module';
@ -30,6 +31,7 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp
@Module({
imports: [
SeederModule,
WorkspaceManagerModule,
DataSourceModule,
TypeORMModule,

View File

@ -1,6 +1,6 @@
import { EntityManager } from 'typeorm';
import { DEV_SEED_PERSON_IDS } from 'src/database/typeorm-seeds/workspace/people';
import { DEV_SEED_PERSON_IDS } from 'src/database/typeorm-seeds/workspace/seedPeople';
import { DEV_SEED_WORKSPACE_MEMBER_IDS } from 'src/database/typeorm-seeds/workspace/workspace-members';
import { CalendarEventParticipantResponseStatus } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity';

View File

@ -264,8 +264,8 @@ export const seedCompanies = async (
tagline: "Algolia's tagline",
workPolicy: ['ON_SITE'],
createdBySource: 'MANUAL',
createdByWorkspaceMemberId: null,
createdByName: '',
createdByWorkspaceMemberId: DEV_SEED_WORKSPACE_MEMBER_IDS.TIM,
createdByName: 'Tim Apple',
},
])
.execute();

View File

@ -1,8 +1,8 @@
import { EntityManager } from 'typeorm';
import { DEV_SEED_WORKSPACE_MEMBER_IDS } from 'src/database/typeorm-seeds/workspace/workspace-members';
import { DEV_SEED_PERSON_IDS } from 'src/database/typeorm-seeds/workspace/people';
import { DEV_SEED_MESSAGE_IDS } from 'src/database/typeorm-seeds/workspace/messages';
import { DEV_SEED_PERSON_IDS } from 'src/database/typeorm-seeds/workspace/seedPeople';
import { DEV_SEED_WORKSPACE_MEMBER_IDS } from 'src/database/typeorm-seeds/workspace/workspace-members';
const tableName = 'messageParticipant';

View File

@ -1,7 +1,7 @@
import { EntityManager } from 'typeorm';
import { DEV_SEED_COMPANY_IDS } from 'src/database/typeorm-seeds/workspace/companies';
import { DEV_SEED_PERSON_IDS } from 'src/database/typeorm-seeds/workspace/people';
import { DEV_SEED_PERSON_IDS } from 'src/database/typeorm-seeds/workspace/seedPeople';
import { DEV_SEED_WORKSPACE_MEMBER_IDS } from 'src/database/typeorm-seeds/workspace/workspace-members';
const tableName = 'opportunity';

View File

@ -317,8 +317,8 @@ export const seedPeople = async (
whatsappPrimaryPhoneCallingCode: '+33',
whatsappPrimaryPhoneNumber: '788901235',
createdBySource: 'MANUAL',
createdByWorkspaceMemberId: null,
createdByName: '',
createdByWorkspaceMemberId: DEV_SEED_WORKSPACE_MEMBER_IDS.TIM,
createdByName: 'Tim Apple',
},
])
.execute();