Get ready for 1000+ members (#14313)
The goal of this PR is to test if Twenty can support a large number of members, a question which was raised by a large company that is considering moving away from Salesforce. I was expecting the currentWorkspaceMembersState to cause a lot more issue. It would be very hard to get rid of it in the context of actors, I think that would require a big refactoring. I thought we'd have to do it but it turns out the perf are pretty good. One thing we need to improve is the pagination on the roles page, we'll wait for @Bonapara to update that
This commit is contained in:
+8
-8
@@ -20,7 +20,7 @@ import {
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/calendar-event-data-seeds.constant';
|
||||
import {
|
||||
CALENDAR_EVENT_PARTICIPANT_DATA_SEED_COLUMNS,
|
||||
CALENDAR_EVENT_PARTICIPANT_DATA_SEEDS,
|
||||
getCalendarEventParticipantDataSeeds,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/calendar-event-participant-data-seeds.constant';
|
||||
import {
|
||||
COMPANY_DATA_SEED_COLUMNS,
|
||||
@@ -43,8 +43,8 @@ import {
|
||||
MESSAGE_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/message-data-seeds.constant';
|
||||
import {
|
||||
getMessageParticipantDataSeeds,
|
||||
MESSAGE_PARTICIPANT_DATA_SEED_COLUMNS,
|
||||
MESSAGE_PARTICIPANT_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/message-participant-data-seeds.constant';
|
||||
import {
|
||||
MESSAGE_THREAD_DATA_SEED_COLUMNS,
|
||||
@@ -83,17 +83,17 @@ import {
|
||||
TASK_TARGET_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/task-target-data-seeds.constant';
|
||||
import {
|
||||
getWorkspaceMemberDataSeeds,
|
||||
WORKSPACE_MEMBER_DATA_SEED_COLUMNS,
|
||||
WORKSPACE_MEMBER_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/workspace-member-data-seeds.constant';
|
||||
import { TimelineActivitySeederService } from 'src/engine/workspace-manager/dev-seeder/data/services/timeline-activity-seeder.service';
|
||||
import { prefillWorkflows } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-workflows';
|
||||
|
||||
const RECORD_SEEDS_CONFIGS = [
|
||||
const getRecordSeedsConfigs = (workspaceId: string) => [
|
||||
{
|
||||
tableName: 'workspaceMember',
|
||||
pgColumns: WORKSPACE_MEMBER_DATA_SEED_COLUMNS,
|
||||
recordSeeds: WORKSPACE_MEMBER_DATA_SEEDS,
|
||||
recordSeeds: getWorkspaceMemberDataSeeds(workspaceId),
|
||||
},
|
||||
{
|
||||
tableName: 'company',
|
||||
@@ -143,7 +143,7 @@ const RECORD_SEEDS_CONFIGS = [
|
||||
{
|
||||
tableName: 'calendarEventParticipant',
|
||||
pgColumns: CALENDAR_EVENT_PARTICIPANT_DATA_SEED_COLUMNS,
|
||||
recordSeeds: CALENDAR_EVENT_PARTICIPANT_DATA_SEEDS,
|
||||
recordSeeds: getCalendarEventParticipantDataSeeds(workspaceId),
|
||||
},
|
||||
{
|
||||
tableName: 'messageChannel',
|
||||
@@ -168,7 +168,7 @@ const RECORD_SEEDS_CONFIGS = [
|
||||
{
|
||||
tableName: 'messageParticipant',
|
||||
pgColumns: MESSAGE_PARTICIPANT_DATA_SEED_COLUMNS,
|
||||
recordSeeds: MESSAGE_PARTICIPANT_DATA_SEEDS,
|
||||
recordSeeds: getMessageParticipantDataSeeds(workspaceId),
|
||||
},
|
||||
{
|
||||
tableName: '_pet',
|
||||
@@ -213,7 +213,7 @@ export class DevSeederDataService {
|
||||
|
||||
await this.coreDataSource.transaction(
|
||||
async (entityManager: WorkspaceEntityManager) => {
|
||||
for (const recordSeedsConfig of RECORD_SEEDS_CONFIGS) {
|
||||
for (const recordSeedsConfig of getRecordSeedsConfigs(workspaceId)) {
|
||||
const objectMetadata = objectMetadataItems.find(
|
||||
(item) =>
|
||||
computeTableName(item.nameSingular, item.isCustom) ===
|
||||
|
||||
+39
-10
@@ -5,10 +5,16 @@ import chunk from 'lodash.chunk';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { type WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { CALENDAR_EVENT_DATA_SEEDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/calendar-event-data-seeds.constant';
|
||||
import { CALENDAR_EVENT_PARTICIPANT_DATA_SEEDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/calendar-event-participant-data-seeds.constant';
|
||||
import {
|
||||
CalendarEventParticipantDataSeed,
|
||||
getCalendarEventParticipantDataSeeds,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/calendar-event-participant-data-seeds.constant';
|
||||
import { COMPANY_DATA_SEEDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/company-data-seeds.constant';
|
||||
import { MESSAGE_DATA_SEEDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/message-data-seeds.constant';
|
||||
import { MESSAGE_PARTICIPANT_DATA_SEEDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/message-participant-data-seeds.constant';
|
||||
import {
|
||||
getMessageParticipantDataSeeds,
|
||||
MessageParticipantDataSeed,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/message-participant-data-seeds.constant';
|
||||
import { NOTE_DATA_SEEDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/note-data-seeds.constant';
|
||||
import { NOTE_TARGET_DATA_SEEDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/note-target-data-seeds.constant';
|
||||
import { OPPORTUNITY_DATA_SEEDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/opportunity-data-seeds.constant';
|
||||
@@ -116,6 +122,10 @@ export class TimelineActivitySeederService {
|
||||
schemaName: string;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
// Get workspace-specific participant data
|
||||
const calendarEventParticipants =
|
||||
getCalendarEventParticipantDataSeeds(workspaceId);
|
||||
const messageParticipants = getMessageParticipantDataSeeds(workspaceId);
|
||||
const timelineActivities: TimelineActivitySeedData[] = [];
|
||||
const metadataIds = await this.getObjectMetadataIds(workspaceId);
|
||||
let activityIndex = 0;
|
||||
@@ -159,6 +169,8 @@ export class TimelineActivitySeederService {
|
||||
index,
|
||||
activityIndex,
|
||||
linkedObjectMetadataId,
|
||||
calendarEventParticipants,
|
||||
messageParticipants,
|
||||
});
|
||||
|
||||
timelineActivities.push(...linkedActivities);
|
||||
@@ -179,6 +191,8 @@ export class TimelineActivitySeederService {
|
||||
index,
|
||||
activityIndex,
|
||||
linkedObjectMetadataId,
|
||||
calendarEventParticipants,
|
||||
messageParticipants,
|
||||
});
|
||||
|
||||
timelineActivities.push(...linkedActivities);
|
||||
@@ -367,14 +381,23 @@ export class TimelineActivitySeederService {
|
||||
index,
|
||||
activityIndex,
|
||||
linkedObjectMetadataId,
|
||||
calendarEventParticipants,
|
||||
messageParticipants,
|
||||
}: {
|
||||
activityType: 'note' | 'task' | 'calendarEvent' | 'message';
|
||||
recordSeed: Record<string, unknown>;
|
||||
index: number;
|
||||
activityIndex: number;
|
||||
linkedObjectMetadataId: string;
|
||||
calendarEventParticipants: CalendarEventParticipantDataSeed[];
|
||||
messageParticipants: MessageParticipantDataSeed[];
|
||||
}): TimelineActivitySeedData[] {
|
||||
const targetInfos = this.getActivityTargetInfos(activityType, recordSeed);
|
||||
const targetInfos = this.getActivityTargetInfos(
|
||||
activityType,
|
||||
recordSeed,
|
||||
calendarEventParticipants,
|
||||
messageParticipants,
|
||||
);
|
||||
|
||||
if (targetInfos.length === 0) {
|
||||
return [];
|
||||
@@ -395,12 +418,16 @@ export class TimelineActivitySeederService {
|
||||
private getActivityTargetInfos(
|
||||
activityType: 'note' | 'task' | 'calendarEvent' | 'message',
|
||||
recordSeed: Record<string, unknown>,
|
||||
calendarEventParticipants: CalendarEventParticipantDataSeed[],
|
||||
messageParticipants: MessageParticipantDataSeed[],
|
||||
): ActivityTargetInfo[] {
|
||||
const targetGetters = {
|
||||
note: () => this.getNoteTargetInfos(recordSeed),
|
||||
task: () => this.getTaskTargetInfos(recordSeed),
|
||||
calendarEvent: () => this.getCalendarEventTargetInfos(recordSeed),
|
||||
message: () => this.getMessageTargetInfos(recordSeed),
|
||||
calendarEvent: () =>
|
||||
this.getCalendarEventTargetInfos(recordSeed, calendarEventParticipants),
|
||||
message: () =>
|
||||
this.getMessageTargetInfos(recordSeed, messageParticipants),
|
||||
};
|
||||
|
||||
const getter = targetGetters[activityType];
|
||||
@@ -462,8 +489,9 @@ export class TimelineActivitySeederService {
|
||||
|
||||
private getCalendarEventTargetInfos(
|
||||
recordSeed: Record<string, unknown>,
|
||||
calendarEventParticipants: CalendarEventParticipantDataSeed[],
|
||||
): ActivityTargetInfo[] {
|
||||
const eventParticipants = CALENDAR_EVENT_PARTICIPANT_DATA_SEEDS.filter(
|
||||
const eventParticipants = calendarEventParticipants.filter(
|
||||
(participant) => participant.calendarEventId === recordSeed.id,
|
||||
);
|
||||
|
||||
@@ -473,7 +501,7 @@ export class TimelineActivitySeederService {
|
||||
if (participant.personId) {
|
||||
targetInfos.push({
|
||||
targetType: 'person',
|
||||
targetId: participant.personId as string,
|
||||
targetId: participant.personId,
|
||||
});
|
||||
|
||||
const person = PERSON_DATA_SEEDS.find(
|
||||
@@ -494,14 +522,15 @@ export class TimelineActivitySeederService {
|
||||
|
||||
private getMessageTargetInfos(
|
||||
recordSeed: Record<string, unknown>,
|
||||
messageParticipants: MessageParticipantDataSeed[],
|
||||
): ActivityTargetInfo[] {
|
||||
const messageParticipants = MESSAGE_PARTICIPANT_DATA_SEEDS.filter(
|
||||
const filteredMessageParticipants = messageParticipants.filter(
|
||||
(participant) => participant.messageId === recordSeed.id,
|
||||
);
|
||||
|
||||
const targetInfos: ActivityTargetInfo[] = [];
|
||||
|
||||
messageParticipants.forEach((participant) => {
|
||||
filteredMessageParticipants.forEach((participant) => {
|
||||
if (participant.personId) {
|
||||
targetInfos.push({
|
||||
targetType: 'person',
|
||||
@@ -515,7 +544,7 @@ export class TimelineActivitySeederService {
|
||||
if (person?.companyId) {
|
||||
targetInfos.push({
|
||||
targetType: 'company',
|
||||
targetId: person.companyId as string,
|
||||
targetId: person.companyId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user