2024-08-04 18:37:36 +00:00
|
|
|
import { Logger } from '@nestjs/common';
|
|
|
|
|
|
2023-11-03 13:33:45 +00:00
|
|
|
import { Command, CommandRunner } from 'nest-commander';
|
2025-05-05 14:06:54 +00:00
|
|
|
import { DataSource } from 'typeorm';
|
2023-10-28 10:25:43 +00:00
|
|
|
|
2023-11-19 17:25:47 +00:00
|
|
|
import { seedCoreSchema } from 'src/database/typeorm-seeds/core';
|
2024-03-20 13:43:41 +00:00
|
|
|
import {
|
2024-11-22 15:03:18 +00:00
|
|
|
SEED_ACME_WORKSPACE_ID,
|
2024-12-27 14:01:09 +00:00
|
|
|
SEED_APPLE_WORKSPACE_ID,
|
2024-03-20 13:43:41 +00:00
|
|
|
} from 'src/database/typeorm-seeds/core/workspaces';
|
2024-08-05 16:19:19 +00:00
|
|
|
import {
|
|
|
|
|
getDevSeedCompanyCustomFields,
|
|
|
|
|
getDevSeedPeopleCustomFields,
|
|
|
|
|
} from 'src/database/typeorm-seeds/metadata/fieldsMetadata';
|
2025-04-23 15:57:48 +00:00
|
|
|
import { seedApiKey } from 'src/database/typeorm-seeds/workspace/api-key';
|
2024-07-25 15:53:57 +00:00
|
|
|
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';
|
|
|
|
|
import { seedCalendarEvents } from 'src/database/typeorm-seeds/workspace/calendar-events';
|
|
|
|
|
import { seedCompanies } from 'src/database/typeorm-seeds/workspace/companies';
|
2024-03-26 13:19:40 +00:00
|
|
|
import { seedConnectedAccount } from 'src/database/typeorm-seeds/workspace/connected-account';
|
2024-09-05 14:41:06 +00:00
|
|
|
import { seedWorkspaceFavorites } from 'src/database/typeorm-seeds/workspace/favorites';
|
2024-03-26 13:19:40 +00:00
|
|
|
import { seedMessageChannelMessageAssociation } from 'src/database/typeorm-seeds/workspace/message-channel-message-associations';
|
2024-07-25 15:53:57 +00:00
|
|
|
import { seedMessageChannel } from 'src/database/typeorm-seeds/workspace/message-channels';
|
2024-03-26 13:19:40 +00:00
|
|
|
import { seedMessageParticipant } from 'src/database/typeorm-seeds/workspace/message-participants';
|
|
|
|
|
import { seedMessageThread } from 'src/database/typeorm-seeds/workspace/message-threads';
|
2024-07-25 15:53:57 +00:00
|
|
|
import { seedMessage } from 'src/database/typeorm-seeds/workspace/messages';
|
|
|
|
|
import { seedOpportunity } from 'src/database/typeorm-seeds/workspace/opportunities';
|
2024-12-27 14:01:09 +00:00
|
|
|
import { seedPeople } from 'src/database/typeorm-seeds/workspace/seedPeople';
|
2024-07-25 15:53:57 +00:00
|
|
|
import { seedWorkspaceMember } from 'src/database/typeorm-seeds/workspace/workspace-members';
|
Uniformize datasources (#5196)
## Context
We recently enabled the option to bypass SSL certificate authority
validation when establishing a connection to PostgreSQL. Previously, if
this validation failed, the server would revert to unencrypted traffic.
Now, it maintains encryption even if the SSL certificate check fails. In
the process, we overlooked a few DataSource setups, prompting a review
of DataSource creation within our code.
## Current State
Our DataSource initialization is distributed as follows:
- **Database folder**: Contains 'core', 'metadata', and 'raw'
DataSources. The 'core' and 'metadata' DataSources manage migrations and
static resolver calls to the database. The 'raw' DataSource is utilized
in scripts and commands that require handling both aspects.
- **typeorm.service.ts script**: These DataSources facilitate
multi-schema connections.
## Vision for Discussion
- **SystemSchema (formerly core) DataSource**: Manages system schema
migrations and system resolvers/repos. The 'core' schema will be renamed
to 'system' as the Core API will include parts of the system and
workspace schemas.
- **MetadataSchema DataSource**: Handles metadata schema migrations and
metadata API resolvers/repos.
- **(Dynamic) WorkspaceSchema DataSource**: Will be used in the Twenty
ORM to access a specific workspace schema.
We currently do not support cross-schema joins, so maintaining these
DataSources separately should be feasible. Core API resolvers will
select the appropriate DataSource based on the field context.
- **To be discussed**: The potential need for an AdminDataSource (akin
to 'Raw'), which would be used in commands, setup scripts, and the admin
panel to connect to any database schema without loading any model. This
DataSource should be reserved for cases where utilizing metadata,
system, or workspace entities is impractical.
## In This PR
- Ensuring all existing DataSources are compliant with the SSL update.
- Introducing RawDataSource to eliminate the need for declaring new
DataSource() instances in commands.
2024-04-27 09:43:44 +00:00
|
|
|
import { rawDataSource } from 'src/database/typeorm/raw/raw.datasource';
|
2024-07-25 15:53:57 +00:00
|
|
|
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
2025-04-09 12:11:26 +00:00
|
|
|
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
2024-12-27 14:01:09 +00:00
|
|
|
import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
|
2024-07-25 15:53:57 +00:00
|
|
|
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
2024-08-05 16:19:19 +00:00
|
|
|
import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service';
|
2024-07-25 15:53:57 +00:00
|
|
|
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
2024-12-27 14:01:09 +00:00
|
|
|
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';
|
2025-05-05 14:06:54 +00:00
|
|
|
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
2024-10-07 11:45:29 +00:00
|
|
|
import { shouldSeedWorkspaceFavorite } from 'src/engine/utils/should-seed-workspace-favorite';
|
2025-05-07 08:42:51 +00:00
|
|
|
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
2025-01-15 08:37:15 +00:00
|
|
|
import { createWorkspaceViews } from 'src/engine/workspace-manager/standard-objects-prefill-data/create-workspace-views';
|
2024-12-24 13:44:52 +00:00
|
|
|
import { seedViewWithDemoData } from 'src/engine/workspace-manager/standard-objects-prefill-data/seed-view-with-demo-data';
|
2025-01-15 08:37:15 +00:00
|
|
|
import { opportunitiesTableByStageView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/opportunity-table-by-stage.view';
|
2025-02-12 17:49:50 +00:00
|
|
|
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
|
2024-08-05 16:19:19 +00:00
|
|
|
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
|
2023-10-28 10:25:43 +00:00
|
|
|
// TODO: implement dry-run
|
|
|
|
|
@Command({
|
2023-12-02 17:37:45 +00:00
|
|
|
name: 'workspace:seed:dev',
|
2023-11-03 13:33:45 +00:00
|
|
|
description:
|
2023-11-17 10:26:33 +00:00
|
|
|
'Seed workspace with initial data. This command is intended for development only.',
|
2023-10-28 10:25:43 +00:00
|
|
|
})
|
2023-11-17 10:26:33 +00:00
|
|
|
export class DataSeedWorkspaceCommand extends CommandRunner {
|
2024-11-22 15:03:18 +00:00
|
|
|
workspaceIds = [SEED_APPLE_WORKSPACE_ID, SEED_ACME_WORKSPACE_ID];
|
2024-08-04 18:37:36 +00:00
|
|
|
private readonly logger = new Logger(DataSeedWorkspaceCommand.name);
|
2023-11-03 13:33:45 +00:00
|
|
|
|
2023-10-28 10:25:43 +00:00
|
|
|
constructor(
|
2023-11-10 10:48:44 +00:00
|
|
|
private readonly dataSourceService: DataSourceService,
|
2023-11-10 14:33:25 +00:00
|
|
|
private readonly typeORMService: TypeORMService,
|
2024-08-05 16:19:19 +00:00
|
|
|
private readonly fieldMetadataService: FieldMetadataService,
|
2023-12-07 18:22:34 +00:00
|
|
|
private readonly objectMetadataService: ObjectMetadataService,
|
2024-12-27 14:01:09 +00:00
|
|
|
private readonly seederService: SeederService,
|
2025-02-12 17:49:50 +00:00
|
|
|
private readonly workspaceManagerService: WorkspaceManagerService,
|
2025-04-09 12:11:26 +00:00
|
|
|
private readonly twentyConfigService: TwentyConfigService,
|
2025-05-07 08:42:51 +00:00
|
|
|
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
|
2023-10-28 10:25:43 +00:00
|
|
|
) {
|
|
|
|
|
super();
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-03 13:33:45 +00:00
|
|
|
async run(): Promise<void> {
|
2023-11-19 17:25:47 +00:00
|
|
|
try {
|
2024-03-20 13:43:41 +00:00
|
|
|
for (const workspaceId of this.workspaceIds) {
|
2024-12-27 14:01:09 +00:00
|
|
|
await this.createWorkspaceSchema(workspaceId);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
this.logger.error(error);
|
2024-04-30 13:03:24 +00:00
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const workspaceId of this.workspaceIds) {
|
|
|
|
|
await this.seedWorkspace(workspaceId);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-19 17:25:47 +00:00
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
async createWorkspaceSchema(workspaceId: string) {
|
2025-05-07 08:42:51 +00:00
|
|
|
const workspaceCachedMetadataVersion =
|
|
|
|
|
await this.workspaceCacheStorageService.getMetadataVersion(workspaceId);
|
|
|
|
|
|
|
|
|
|
await this.workspaceCacheStorageService.flush(
|
|
|
|
|
workspaceId,
|
|
|
|
|
workspaceCachedMetadataVersion,
|
|
|
|
|
);
|
2023-12-07 18:22:34 +00:00
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
await rawDataSource.initialize();
|
2023-12-07 18:22:34 +00:00
|
|
|
|
2025-04-09 12:11:26 +00:00
|
|
|
const isBillingEnabled = this.twentyConfigService.get('IS_BILLING_ENABLED');
|
|
|
|
|
const appVersion = this.twentyConfigService.get('APP_VERSION');
|
2025-03-13 16:48:29 +00:00
|
|
|
|
2025-03-17 14:32:49 +00:00
|
|
|
await seedCoreSchema({
|
2025-05-07 08:42:51 +00:00
|
|
|
dataSource: rawDataSource,
|
2025-03-17 14:32:49 +00:00
|
|
|
workspaceId,
|
|
|
|
|
seedBilling: isBillingEnabled,
|
|
|
|
|
appVersion,
|
|
|
|
|
});
|
2023-12-07 18:22:34 +00:00
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
await rawDataSource.destroy();
|
2023-12-07 18:22:34 +00:00
|
|
|
|
2025-02-12 17:49:50 +00:00
|
|
|
await this.workspaceManagerService.initDev(workspaceId);
|
2024-12-27 14:01:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async seedWorkspace(workspaceId: string) {
|
|
|
|
|
const dataSourceMetadata =
|
|
|
|
|
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
|
|
|
|
workspaceId,
|
|
|
|
|
);
|
|
|
|
|
|
2025-05-07 08:42:51 +00:00
|
|
|
const mainDataSource = this.typeORMService.getMainDataSource();
|
2024-12-27 14:01:09 +00:00
|
|
|
|
2025-05-07 08:42:51 +00:00
|
|
|
if (!mainDataSource) {
|
2024-12-27 14:01:09 +00:00
|
|
|
throw new Error('Could not connect to workspace data source');
|
2023-11-19 17:25:47 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
try {
|
|
|
|
|
const { objectMetadataStandardIdToIdMap } =
|
|
|
|
|
await this.objectMetadataService.getObjectMetadataStandardIdToIdMap(
|
2024-03-20 13:43:41 +00:00
|
|
|
workspaceId,
|
|
|
|
|
);
|
2023-11-03 13:33:45 +00:00
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
await this.seedCompanyCustomFields(
|
|
|
|
|
objectMetadataStandardIdToIdMap[STANDARD_OBJECT_IDS.company].id,
|
|
|
|
|
workspaceId,
|
|
|
|
|
);
|
2024-03-20 13:43:41 +00:00
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
await this.seedPeopleCustomFields(
|
|
|
|
|
objectMetadataStandardIdToIdMap[STANDARD_OBJECT_IDS.person].id,
|
|
|
|
|
workspaceId,
|
|
|
|
|
);
|
2024-03-20 13:43:41 +00:00
|
|
|
|
2025-05-23 15:23:09 +00:00
|
|
|
await this.seedCustomObjects({
|
|
|
|
|
dataSourceMetadata,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await this.seedRecords({
|
|
|
|
|
mainDataSource,
|
|
|
|
|
dataSourceMetadata,
|
|
|
|
|
});
|
2024-12-27 14:01:09 +00:00
|
|
|
} catch (error) {
|
|
|
|
|
this.logger.error(error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-23 15:23:09 +00:00
|
|
|
async seedCustomObjects({
|
|
|
|
|
dataSourceMetadata,
|
|
|
|
|
}: {
|
|
|
|
|
dataSourceMetadata: DataSourceEntity;
|
|
|
|
|
}) {
|
|
|
|
|
await this.seederService.seedCustomObjects(
|
|
|
|
|
dataSourceMetadata.id,
|
|
|
|
|
dataSourceMetadata.workspaceId,
|
|
|
|
|
PETS_METADATA_SEEDS,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await this.seederService.seedCustomObjects(
|
|
|
|
|
dataSourceMetadata.id,
|
|
|
|
|
dataSourceMetadata.workspaceId,
|
|
|
|
|
SURVEY_RESULTS_METADATA_SEEDS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async seedRecords({
|
|
|
|
|
mainDataSource,
|
|
|
|
|
dataSourceMetadata,
|
|
|
|
|
}: {
|
|
|
|
|
mainDataSource: DataSource;
|
|
|
|
|
dataSourceMetadata: DataSourceEntity;
|
|
|
|
|
}) {
|
|
|
|
|
await this.seedStandardObjectRecords(mainDataSource, dataSourceMetadata);
|
|
|
|
|
|
|
|
|
|
await this.seederService.seedCustomObjectRecords(
|
|
|
|
|
dataSourceMetadata.workspaceId,
|
|
|
|
|
PETS_METADATA_SEEDS,
|
|
|
|
|
PETS_DATA_SEEDS,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await this.seederService.seedCustomObjectRecords(
|
|
|
|
|
dataSourceMetadata.workspaceId,
|
|
|
|
|
SURVEY_RESULTS_METADATA_SEEDS,
|
|
|
|
|
SURVEY_RESULTS_DATA_SEEDS,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
async seedStandardObjectRecords(
|
2025-05-07 08:42:51 +00:00
|
|
|
mainDataSource: DataSource,
|
2024-12-27 14:01:09 +00:00
|
|
|
dataSourceMetadata: DataSourceEntity,
|
|
|
|
|
) {
|
2025-05-07 08:42:51 +00:00
|
|
|
await mainDataSource.transaction(
|
2025-05-05 14:06:54 +00:00
|
|
|
async (entityManager: WorkspaceEntityManager) => {
|
2024-12-27 14:01:09 +00:00
|
|
|
const { objectMetadataStandardIdToIdMap } =
|
|
|
|
|
await this.objectMetadataService.getObjectMetadataStandardIdToIdMap(
|
|
|
|
|
dataSourceMetadata.workspaceId,
|
|
|
|
|
);
|
2024-03-20 13:43:41 +00:00
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
await seedCompanies(entityManager, dataSourceMetadata.schema);
|
|
|
|
|
await seedPeople(entityManager, dataSourceMetadata.schema);
|
|
|
|
|
await seedOpportunity(entityManager, dataSourceMetadata.schema);
|
|
|
|
|
await seedWorkspaceMember(
|
|
|
|
|
entityManager,
|
|
|
|
|
dataSourceMetadata.schema,
|
|
|
|
|
dataSourceMetadata.workspaceId,
|
2024-08-05 16:19:19 +00:00
|
|
|
);
|
2024-03-26 13:19:40 +00:00
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
if (dataSourceMetadata.workspaceId === SEED_APPLE_WORKSPACE_ID) {
|
2025-04-23 15:57:48 +00:00
|
|
|
await seedApiKey(entityManager, dataSourceMetadata.schema);
|
2024-12-27 14:01:09 +00:00
|
|
|
await seedMessageThread(entityManager, dataSourceMetadata.schema);
|
|
|
|
|
await seedConnectedAccount(entityManager, dataSourceMetadata.schema);
|
2024-09-05 14:41:06 +00:00
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
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,
|
2024-03-20 13:43:41 +00:00
|
|
|
);
|
2023-10-28 10:25:43 +00:00
|
|
|
|
2025-01-15 08:37:15 +00:00
|
|
|
const devViewDefinitionsWithId = await createWorkspaceViews(
|
|
|
|
|
entityManager,
|
|
|
|
|
dataSourceMetadata.schema,
|
|
|
|
|
[opportunitiesTableByStageView(objectMetadataStandardIdToIdMap)],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
viewDefinitionsWithId.push(...devViewDefinitionsWithId);
|
|
|
|
|
|
2024-12-27 14:01:09 +00:00
|
|
|
await seedWorkspaceFavorites(
|
|
|
|
|
viewDefinitionsWithId
|
|
|
|
|
.filter(
|
|
|
|
|
(view) =>
|
|
|
|
|
view.key === 'INDEX' &&
|
|
|
|
|
shouldSeedWorkspaceFavorite(
|
|
|
|
|
view.objectMetadataId,
|
|
|
|
|
objectMetadataStandardIdToIdMap,
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
.map((view) => view.id),
|
|
|
|
|
entityManager,
|
|
|
|
|
dataSourceMetadata.schema,
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
2023-10-28 10:25:43 +00:00
|
|
|
}
|
2024-08-05 16:19:19 +00:00
|
|
|
|
|
|
|
|
async seedCompanyCustomFields(
|
2024-12-27 14:01:09 +00:00
|
|
|
companyObjectMetadataId: string,
|
2024-08-05 16:19:19 +00:00
|
|
|
workspaceId: string,
|
|
|
|
|
) {
|
|
|
|
|
if (!companyObjectMetadataId) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
`Company object metadata not found for workspace ${workspaceId}, can't seed custom fields`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DEV_SEED_COMPANY_CUSTOM_FIELDS = getDevSeedCompanyCustomFields(
|
|
|
|
|
companyObjectMetadataId,
|
|
|
|
|
workspaceId,
|
|
|
|
|
);
|
|
|
|
|
|
2025-02-04 10:18:57 +00:00
|
|
|
await this.fieldMetadataService.createMany(
|
|
|
|
|
DEV_SEED_COMPANY_CUSTOM_FIELDS.map((customField) => ({
|
2024-08-05 16:19:19 +00:00
|
|
|
...customField,
|
|
|
|
|
isCustom: true,
|
2025-02-04 10:18:57 +00:00
|
|
|
})),
|
|
|
|
|
);
|
2024-08-05 16:19:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async seedPeopleCustomFields(
|
2024-12-27 14:01:09 +00:00
|
|
|
personObjectMetadataId: string,
|
2024-08-05 16:19:19 +00:00
|
|
|
workspaceId: string,
|
|
|
|
|
) {
|
|
|
|
|
if (!personObjectMetadataId) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
`Person object metadata not found for workspace ${workspaceId}, can't seed custom fields`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DEV_SEED_PERSON_CUSTOM_FIELDS = getDevSeedPeopleCustomFields(
|
|
|
|
|
personObjectMetadataId,
|
|
|
|
|
workspaceId,
|
|
|
|
|
);
|
|
|
|
|
|
2025-02-04 10:18:57 +00:00
|
|
|
await this.fieldMetadataService.createMany(
|
|
|
|
|
DEV_SEED_PERSON_CUSTOM_FIELDS.map((customField) => ({
|
2024-08-05 16:19:19 +00:00
|
|
|
...customField,
|
|
|
|
|
isCustom: true,
|
2025-02-04 10:18:57 +00:00
|
|
|
})),
|
|
|
|
|
);
|
2024-08-05 16:19:19 +00:00
|
|
|
}
|
2023-10-28 10:25:43 +00:00
|
|
|
}
|