+41
-25
@@ -46,10 +46,12 @@ export class DevSeederPermissionsService {
|
||||
twentyStandardFlatApplication,
|
||||
workspaceCustomFlatApplication,
|
||||
workspaceId,
|
||||
light = false,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
workspaceCustomFlatApplication: FlatApplication;
|
||||
light?: boolean;
|
||||
}) {
|
||||
const adminRole = await this.roleRepository.findOne({
|
||||
where: {
|
||||
@@ -80,35 +82,49 @@ export class DevSeederPermissionsService {
|
||||
let guestUserWorkspaceId: string | undefined;
|
||||
|
||||
if (workspaceId === SEED_APPLE_WORKSPACE_ID) {
|
||||
adminUserWorkspaceId = USER_WORKSPACE_DATA_SEED_IDS.JANE;
|
||||
limitedUserWorkspaceId = USER_WORKSPACE_DATA_SEED_IDS.TIM;
|
||||
memberUserWorkspaceIds = [
|
||||
USER_WORKSPACE_DATA_SEED_IDS.JONY,
|
||||
...Object.values(RANDOM_USER_WORKSPACE_IDS),
|
||||
];
|
||||
guestUserWorkspaceId = USER_WORKSPACE_DATA_SEED_IDS.PHIL;
|
||||
if (light) {
|
||||
// In light mode, Tim is admin (prefilled login user needs full
|
||||
// access for SDK development). No demo permission roles needed.
|
||||
adminUserWorkspaceId = USER_WORKSPACE_DATA_SEED_IDS.TIM;
|
||||
memberUserWorkspaceIds = [
|
||||
USER_WORKSPACE_DATA_SEED_IDS.JANE,
|
||||
USER_WORKSPACE_DATA_SEED_IDS.JONY,
|
||||
USER_WORKSPACE_DATA_SEED_IDS.PHIL,
|
||||
...Object.values(RANDOM_USER_WORKSPACE_IDS),
|
||||
];
|
||||
} else {
|
||||
adminUserWorkspaceId = USER_WORKSPACE_DATA_SEED_IDS.JANE;
|
||||
limitedUserWorkspaceId = USER_WORKSPACE_DATA_SEED_IDS.TIM;
|
||||
guestUserWorkspaceId = USER_WORKSPACE_DATA_SEED_IDS.PHIL;
|
||||
memberUserWorkspaceIds = [
|
||||
USER_WORKSPACE_DATA_SEED_IDS.JONY,
|
||||
...Object.values(RANDOM_USER_WORKSPACE_IDS),
|
||||
];
|
||||
|
||||
const guestRole = await this.roleService.createGuestRole({
|
||||
workspaceId,
|
||||
ownerFlatApplication: workspaceCustomFlatApplication,
|
||||
});
|
||||
const guestRole = await this.roleService.createGuestRole({
|
||||
workspaceId,
|
||||
ownerFlatApplication: workspaceCustomFlatApplication,
|
||||
});
|
||||
|
||||
await this.userRoleService.assignRoleToManyUserWorkspace({
|
||||
workspaceId,
|
||||
userWorkspaceIds: [guestUserWorkspaceId],
|
||||
roleId: guestRole.id,
|
||||
});
|
||||
await this.userRoleService.assignRoleToManyUserWorkspace({
|
||||
workspaceId,
|
||||
userWorkspaceIds: [guestUserWorkspaceId],
|
||||
roleId: guestRole.id,
|
||||
});
|
||||
|
||||
const limitedRole = await this.createLimitedRoleForSeedWorkspace({
|
||||
workspaceId,
|
||||
ownerFlatApplication: workspaceCustomFlatApplication,
|
||||
});
|
||||
// The limited role restricts access to Pet and Rocket objects,
|
||||
// which are only created in full (non-light) mode
|
||||
const limitedRole = await this.createLimitedRoleForSeedWorkspace({
|
||||
workspaceId,
|
||||
ownerFlatApplication: workspaceCustomFlatApplication,
|
||||
});
|
||||
|
||||
await this.userRoleService.assignRoleToManyUserWorkspace({
|
||||
workspaceId,
|
||||
userWorkspaceIds: [limitedUserWorkspaceId],
|
||||
roleId: limitedRole.id,
|
||||
});
|
||||
await this.userRoleService.assignRoleToManyUserWorkspace({
|
||||
workspaceId,
|
||||
userWorkspaceIds: [limitedUserWorkspaceId],
|
||||
roleId: limitedRole.id,
|
||||
});
|
||||
}
|
||||
} else if (workspaceId === SEED_YCOMBINATOR_WORKSPACE_ID) {
|
||||
adminUserWorkspaceId = USER_WORKSPACE_DATA_SEED_IDS.TIM_ACME;
|
||||
memberUserWorkspaceIds = [
|
||||
|
||||
+21
-10
@@ -300,10 +300,12 @@ export class DevSeederDataService {
|
||||
schemaName,
|
||||
workspaceId,
|
||||
featureFlags,
|
||||
light = false,
|
||||
}: {
|
||||
schemaName: string;
|
||||
workspaceId: string;
|
||||
featureFlags?: Record<FeatureFlagKey, boolean>;
|
||||
light?: boolean;
|
||||
}) {
|
||||
const objectMetadataItems =
|
||||
await this.objectMetadataService.findManyWithinWorkspace(workspaceId);
|
||||
@@ -328,19 +330,22 @@ export class DevSeederDataService {
|
||||
attachmentSeeds,
|
||||
featureFlags,
|
||||
objectMetadataItems,
|
||||
light,
|
||||
});
|
||||
|
||||
await this.timelineActivitySeederService.seedTimelineActivities({
|
||||
entityManager,
|
||||
schemaName,
|
||||
workspaceId,
|
||||
});
|
||||
if (!light) {
|
||||
await this.timelineActivitySeederService.seedTimelineActivities({
|
||||
entityManager,
|
||||
schemaName,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.seedAttachmentFiles(
|
||||
workspaceId,
|
||||
entityManager,
|
||||
attachmentFileMeta,
|
||||
);
|
||||
await this.seedAttachmentFiles(
|
||||
workspaceId,
|
||||
entityManager,
|
||||
attachmentFileMeta,
|
||||
);
|
||||
}
|
||||
|
||||
await prefillWorkflows(
|
||||
entityManager,
|
||||
@@ -359,6 +364,7 @@ export class DevSeederDataService {
|
||||
attachmentSeeds,
|
||||
featureFlags,
|
||||
objectMetadataItems,
|
||||
light = false,
|
||||
}: {
|
||||
entityManager: WorkspaceEntityManager;
|
||||
schemaName: string;
|
||||
@@ -366,6 +372,7 @@ export class DevSeederDataService {
|
||||
attachmentSeeds: RecordSeedConfig['recordSeeds'];
|
||||
featureFlags?: Record<FeatureFlagKey, boolean>;
|
||||
objectMetadataItems: FlatObjectMetadata[];
|
||||
light?: boolean;
|
||||
}) {
|
||||
const batches = getRecordSeedsBatches(
|
||||
workspaceId,
|
||||
@@ -378,6 +385,10 @@ export class DevSeederDataService {
|
||||
for (const batch of batches) {
|
||||
await Promise.all(
|
||||
batch.map(async (recordSeedsConfig) => {
|
||||
if (light && recordSeedsConfig.tableName.startsWith('_')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const objectMetadata = objectMetadataItems.find(
|
||||
(item) =>
|
||||
computeTableName(item.nameSingular, item.isCustom) ===
|
||||
|
||||
+39
-28
@@ -51,6 +51,14 @@ type JunctionConfigSeed = {
|
||||
label?: string;
|
||||
};
|
||||
|
||||
type WorkspaceSeedConfig = {
|
||||
objects: { seed: ObjectMetadataSeed; fields?: FieldMetadataSeed[] }[];
|
||||
fields: { objectName: string; seeds: FieldMetadataSeed[] }[];
|
||||
morphRelations?: { objectName: string; seeds: MorphRelationSeed[] }[];
|
||||
junctionFields?: JunctionFieldSeed[];
|
||||
junctionConfigs?: JunctionConfigSeed[];
|
||||
};
|
||||
|
||||
type FlatMaps = {
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
|
||||
flatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>;
|
||||
@@ -65,18 +73,7 @@ export class DevSeederMetadataService {
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
) {}
|
||||
|
||||
private readonly workspaceConfigs: Record<
|
||||
string,
|
||||
{
|
||||
objects: { seed: ObjectMetadataSeed; fields?: FieldMetadataSeed[] }[];
|
||||
fields: { objectName: string; seeds: FieldMetadataSeed[] }[];
|
||||
morphRelations?: { objectName: string; seeds: MorphRelationSeed[] }[];
|
||||
// Junction fields create relations to junction objects (inverses auto-created)
|
||||
junctionFields?: JunctionFieldSeed[];
|
||||
// Configure junction settings on fields after all relations exist
|
||||
junctionConfigs?: JunctionConfigSeed[];
|
||||
}
|
||||
> = {
|
||||
private readonly workspaceConfigs: Record<string, WorkspaceSeedConfig> = {
|
||||
[SEED_APPLE_WORKSPACE_ID]: {
|
||||
objects: [
|
||||
{ seed: ROCKET_CUSTOM_OBJECT_SEED },
|
||||
@@ -178,13 +175,14 @@ export class DevSeederMetadataService {
|
||||
},
|
||||
};
|
||||
|
||||
public async seed({
|
||||
dataSourceMetadata,
|
||||
workspaceId,
|
||||
}: {
|
||||
dataSourceMetadata: DataSourceEntity;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
private getLightConfig(config: WorkspaceSeedConfig): WorkspaceSeedConfig {
|
||||
return {
|
||||
objects: [],
|
||||
fields: [],
|
||||
};
|
||||
}
|
||||
|
||||
private getConfig(workspaceId: string, light: boolean): WorkspaceSeedConfig {
|
||||
const config = this.workspaceConfigs[workspaceId];
|
||||
|
||||
if (!config) {
|
||||
@@ -193,6 +191,20 @@ export class DevSeederMetadataService {
|
||||
);
|
||||
}
|
||||
|
||||
return light ? this.getLightConfig(config) : config;
|
||||
}
|
||||
|
||||
public async seed({
|
||||
dataSourceMetadata,
|
||||
workspaceId,
|
||||
light = false,
|
||||
}: {
|
||||
dataSourceMetadata: DataSourceEntity;
|
||||
workspaceId: string;
|
||||
light?: boolean;
|
||||
}) {
|
||||
const config = this.getConfig(workspaceId, light);
|
||||
|
||||
for (const obj of config.objects) {
|
||||
await this.seedCustomObject({
|
||||
dataSourceId: dataSourceMetadata.id,
|
||||
@@ -266,14 +278,14 @@ export class DevSeederMetadataService {
|
||||
});
|
||||
}
|
||||
|
||||
public async seedRelations({ workspaceId }: { workspaceId: string }) {
|
||||
const config = this.workspaceConfigs[workspaceId];
|
||||
|
||||
if (!config) {
|
||||
throw new Error(
|
||||
`Workspace configuration not found for workspaceId: ${workspaceId}`,
|
||||
);
|
||||
}
|
||||
public async seedRelations({
|
||||
workspaceId,
|
||||
light = false,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
light?: boolean;
|
||||
}) {
|
||||
const config = this.getConfig(workspaceId, light);
|
||||
|
||||
// 1. Seed morph relations (creates inverses on target objects)
|
||||
let maps = await this.getFreshFlatMaps(workspaceId);
|
||||
@@ -287,7 +299,6 @@ export class DevSeederMetadataService {
|
||||
}
|
||||
|
||||
// 2. Seed junction fields (creates relations + inverses on junction objects)
|
||||
// Use same maps for all - matches original working behavior
|
||||
maps = await this.getFreshFlatMaps(workspaceId);
|
||||
|
||||
for (const field of config.junctionFields ?? []) {
|
||||
|
||||
+9
-1
@@ -43,7 +43,11 @@ export class DevSeederService {
|
||||
private readonly coreDataSource: DataSource,
|
||||
) {}
|
||||
|
||||
public async seedDev(workspaceId: SeededWorkspacesIds): Promise<void> {
|
||||
public async seedDev(
|
||||
workspaceId: SeededWorkspacesIds,
|
||||
options?: { light?: boolean },
|
||||
): Promise<void> {
|
||||
const light = options?.light ?? false;
|
||||
const isBillingEnabled = this.twentyConfigService.get('IS_BILLING_ENABLED');
|
||||
const appVersion = this.twentyConfigService.get('APP_VERSION');
|
||||
|
||||
@@ -89,16 +93,19 @@ export class DevSeederService {
|
||||
await this.devSeederMetadataService.seed({
|
||||
dataSourceMetadata,
|
||||
workspaceId,
|
||||
light,
|
||||
});
|
||||
|
||||
await this.devSeederMetadataService.seedRelations({
|
||||
workspaceId,
|
||||
light,
|
||||
});
|
||||
|
||||
await this.devSeederPermissionsService.initPermissions({
|
||||
workspaceId,
|
||||
twentyStandardFlatApplication,
|
||||
workspaceCustomFlatApplication,
|
||||
light,
|
||||
});
|
||||
|
||||
await seedPageLayouts(
|
||||
@@ -148,6 +155,7 @@ export class DevSeederService {
|
||||
schemaName: dataSourceMetadata.schema,
|
||||
workspaceId,
|
||||
featureFlags: featureFlagsMap,
|
||||
light,
|
||||
});
|
||||
|
||||
await this.workspaceCacheStorageService.flush(workspaceId, undefined);
|
||||
|
||||
Reference in New Issue
Block a user