Update workspace entities to make all TEXT nullable (#16144)
Follow up on #15926 --------- Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com> Co-authored-by: guillim <guigloo@msn.com>
This commit is contained in:
+6
-2
@@ -7,10 +7,10 @@ import { msg } from '@lingui/core/macro';
|
||||
import { render } from '@react-email/render';
|
||||
import { SendApprovedAccessDomainValidation } from 'twenty-emails';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { getSettingsPath } from 'twenty-shared/utils';
|
||||
import { getSettingsPath, isDefined } from 'twenty-shared/utils';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ApprovedAccessDomainEntity as ApprovedAccessDomainEntity } from 'src/engine/core-modules/approved-access-domain/approved-access-domain.entity';
|
||||
import { ApprovedAccessDomainEntity } from 'src/engine/core-modules/approved-access-domain/approved-access-domain.entity';
|
||||
import {
|
||||
ApprovedAccessDomainException,
|
||||
ApprovedAccessDomainExceptionCode,
|
||||
@@ -70,6 +70,10 @@ export class ApprovedAccessDomainService {
|
||||
},
|
||||
});
|
||||
|
||||
if (!isDefined(sender.userEmail)) {
|
||||
throw new Error(`Sender ${sender.id} has an empty userEmail`);
|
||||
}
|
||||
|
||||
const emailTemplate = SendApprovedAccessDomainValidation({
|
||||
link: link.toString(),
|
||||
workspace: {
|
||||
|
||||
+5
-3
@@ -112,7 +112,7 @@ export class TimelineCalendarEventService {
|
||||
participant.person?.avatarUrl ||
|
||||
participant.workspaceMember?.avatarUrl ||
|
||||
'',
|
||||
handle: participant.handle,
|
||||
handle: participant.handle ?? '',
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -139,15 +139,17 @@ export class TimelineCalendarEventService {
|
||||
title:
|
||||
visibility === CalendarChannelVisibility.METADATA
|
||||
? FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED
|
||||
: event.title,
|
||||
: (event.title ?? ''),
|
||||
description:
|
||||
visibility === CalendarChannelVisibility.METADATA
|
||||
? FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED
|
||||
: event.description,
|
||||
: (event.description ?? ''),
|
||||
startsAt: event.startsAt as unknown as Date,
|
||||
endsAt: event.endsAt as unknown as Date,
|
||||
participants,
|
||||
visibility,
|
||||
location: event.location ?? '',
|
||||
conferenceSolution: event.conferenceSolution ?? '',
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ export class FileAttachmentListener {
|
||||
FileDeletionJob.name,
|
||||
{
|
||||
workspaceId: payload.workspaceId,
|
||||
fullPath: event.properties.before.fullPath,
|
||||
fullPath: event.properties.before.fullPath ?? '',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ export class FileWorkspaceMemberListener {
|
||||
|
||||
this.messageQueueService.add<FileDeletionJobData>(FileDeletionJob.name, {
|
||||
workspaceId: payload.workspaceId,
|
||||
fullPath: event.properties.before.avatarUrl,
|
||||
fullPath: event.properties.before.avatarUrl ?? '',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ import {
|
||||
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
|
||||
|
||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter';
|
||||
@@ -59,7 +60,7 @@ export class ImapSmtpCaldavResolver {
|
||||
where: { id, provider: ConnectedAccountProvider.IMAP_SMTP_CALDAV },
|
||||
});
|
||||
|
||||
if (!connectedAccount) {
|
||||
if (!isDefined(connectedAccount) || !isDefined(connectedAccount?.handle)) {
|
||||
throw new UserInputError(
|
||||
`Connected mail account with ID ${id} not found`,
|
||||
);
|
||||
|
||||
+2
-2
@@ -75,8 +75,8 @@ export class TimelineMessagingService {
|
||||
|
||||
return {
|
||||
id: messageThread.id,
|
||||
subject: firstMessage.subject,
|
||||
lastMessageBody: lastMessage.text,
|
||||
subject: firstMessage.subject ?? '',
|
||||
lastMessageBody: lastMessage.text ?? '',
|
||||
lastMessageReceivedAt: lastMessage.receivedAt ?? new Date(),
|
||||
numberOfMessagesInThread: messageThread.messages.length,
|
||||
};
|
||||
|
||||
+35
-25
@@ -1,30 +1,40 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type TimelineThreadParticipantDTO } from 'src/engine/core-modules/messaging/dtos/timeline-thread-participant.dto';
|
||||
import { type MessageParticipantWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-participant.workspace-entity';
|
||||
|
||||
export const formatThreadParticipant = (
|
||||
threadParticipant: MessageParticipantWorkspaceEntity,
|
||||
): TimelineThreadParticipantDTO => ({
|
||||
personId: threadParticipant.personId,
|
||||
workspaceMemberId: threadParticipant.workspaceMemberId,
|
||||
firstName:
|
||||
threadParticipant.person?.name?.firstName ||
|
||||
threadParticipant.workspaceMember?.name.firstName ||
|
||||
'',
|
||||
lastName:
|
||||
threadParticipant.person?.name?.lastName ||
|
||||
threadParticipant.workspaceMember?.name.lastName ||
|
||||
'',
|
||||
displayName:
|
||||
threadParticipant.person?.name?.firstName ||
|
||||
threadParticipant.person?.name?.lastName ||
|
||||
threadParticipant.workspaceMember?.name.firstName ||
|
||||
threadParticipant.workspaceMember?.name.lastName ||
|
||||
threadParticipant.displayName ||
|
||||
threadParticipant.handle ||
|
||||
'',
|
||||
avatarUrl:
|
||||
threadParticipant.person?.avatarUrl ||
|
||||
threadParticipant.workspaceMember?.avatarUrl ||
|
||||
'',
|
||||
handle: threadParticipant.handle,
|
||||
});
|
||||
): TimelineThreadParticipantDTO => {
|
||||
if (!isDefined(threadParticipant.handle)) {
|
||||
throw new Error(
|
||||
`Thread participant ${threadParticipant.id} has an empty handle`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
personId: threadParticipant.personId,
|
||||
workspaceMemberId: threadParticipant.workspaceMemberId,
|
||||
firstName:
|
||||
threadParticipant.person?.name?.firstName ||
|
||||
threadParticipant.workspaceMember?.name.firstName ||
|
||||
'',
|
||||
lastName:
|
||||
threadParticipant.person?.name?.lastName ||
|
||||
threadParticipant.workspaceMember?.name.lastName ||
|
||||
'',
|
||||
displayName:
|
||||
threadParticipant.person?.name?.firstName ||
|
||||
threadParticipant.person?.name?.lastName ||
|
||||
threadParticipant.workspaceMember?.name.firstName ||
|
||||
threadParticipant.workspaceMember?.name.lastName ||
|
||||
threadParticipant.displayName ||
|
||||
threadParticipant.handle ||
|
||||
'',
|
||||
avatarUrl:
|
||||
threadParticipant.person?.avatarUrl ||
|
||||
threadParticipant.workspaceMember?.avatarUrl ||
|
||||
'',
|
||||
handle: threadParticipant.handle,
|
||||
};
|
||||
};
|
||||
|
||||
+8
@@ -75,6 +75,10 @@ export class WorkspaceMemberTranspiler {
|
||||
|
||||
const roles = fromRoleEntitiesToRoleDtos(userWorkspaceRoles);
|
||||
|
||||
if (!isDefined(userEmail)) {
|
||||
throw new Error(`Workspace member ${id} has no userEmail`);
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
@@ -111,6 +115,10 @@ export class WorkspaceMemberTranspiler {
|
||||
userEmail,
|
||||
} = workspaceMember;
|
||||
|
||||
if (!isDefined(userEmail)) {
|
||||
throw new Error(`Workspace member ${id} has no userEmail`);
|
||||
}
|
||||
|
||||
const avatarUrl = userWorkspaceId
|
||||
? this.generateSignedAvatarUrl({
|
||||
workspaceId: userWorkspaceId,
|
||||
|
||||
+1
-1
@@ -4,6 +4,7 @@ import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
||||
import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter';
|
||||
import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe';
|
||||
import { CreateDraftFromWorkflowVersionInput } from 'src/engine/core-modules/workflow/dtos/create-draft-from-workflow-version-input.dto';
|
||||
import { DuplicateWorkflowInput } from 'src/engine/core-modules/workflow/dtos/duplicate-workflow-input.dto';
|
||||
import { UpdateWorkflowVersionPositionsInput } from 'src/engine/core-modules/workflow/dtos/update-workflow-version-positions-input.dto';
|
||||
import { WorkflowVersionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-version.dto';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
@@ -14,7 +15,6 @@ import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants';
|
||||
import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter';
|
||||
import { WorkflowVersionWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.workspace-service';
|
||||
import { DuplicateWorkflowInput } from 'src/engine/core-modules/workflow/dtos/duplicate-workflow-input.dto';
|
||||
|
||||
@Resolver()
|
||||
@UsePipes(ResolverValidationPipe)
|
||||
|
||||
+7
@@ -306,6 +306,13 @@ export class WorkspaceInvitationService {
|
||||
: {},
|
||||
});
|
||||
|
||||
if (!isDefined(sender.userEmail)) {
|
||||
throw new WorkspaceInvitationException(
|
||||
'Sender email is missing',
|
||||
WorkspaceInvitationExceptionCode.EMAIL_MISSING,
|
||||
);
|
||||
}
|
||||
|
||||
const emailData = {
|
||||
link: link.toString(),
|
||||
workspace: {
|
||||
|
||||
+5
-2
@@ -7,8 +7,11 @@ export const transformStandardAgentDefinitionToFlatAgent = (
|
||||
standardAgentDefinition: StandardAgentDefinition,
|
||||
workspaceId: string,
|
||||
): FlatAgent => {
|
||||
const { standardRoleId: _standardRoleId, ...agentData } =
|
||||
standardAgentDefinition;
|
||||
const {
|
||||
standardRoleId: _standardRoleId,
|
||||
outputStrategy: _outputStrategy,
|
||||
...agentData
|
||||
} = standardAgentDefinition;
|
||||
|
||||
return {
|
||||
...agentData,
|
||||
|
||||
@@ -7,9 +7,9 @@ import {
|
||||
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
|
||||
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/search-field-metadata/constants/search-vector-field.constants';
|
||||
import { IndexType } from 'src/engine/metadata-modules/index-metadata/types/indexType.types';
|
||||
import { DEFAULT_LABEL_IDENTIFIER_FIELD_NAME } from 'src/engine/metadata-modules/object-metadata/constants/object-metadata.constants';
|
||||
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/search-field-metadata/constants/search-vector-field.constants';
|
||||
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
|
||||
import { WorkspaceCustomEntity } from 'src/engine/twenty-orm/decorators/workspace-custom-entity.decorator';
|
||||
import { WorkspaceFieldIndex } from 'src/engine/twenty-orm/decorators/workspace-field-index.decorator';
|
||||
@@ -44,7 +44,8 @@ export class CustomWorkspaceEntity extends BaseWorkspaceEntity {
|
||||
type: FieldMetadataType.TEXT,
|
||||
icon: 'IconAbc',
|
||||
})
|
||||
name: string;
|
||||
@WorkspaceIsNullable()
|
||||
name: string | null;
|
||||
|
||||
@WorkspaceField({
|
||||
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.position,
|
||||
|
||||
+8
@@ -133,6 +133,10 @@ export class CleanerWorkspaceService {
|
||||
const i18n = this.i18nService.getI18nInstance(workspaceMember.locale);
|
||||
const subject = i18n._(workspaceDeletionMsg);
|
||||
|
||||
if (!isDefined(workspaceMember.userEmail)) {
|
||||
throw new Error('Workspace member email is missing');
|
||||
}
|
||||
|
||||
this.emailService.send({
|
||||
to: workspaceMember.userEmail,
|
||||
from: `${this.twentyConfigService.get(
|
||||
@@ -207,6 +211,10 @@ export class CleanerWorkspaceService {
|
||||
const html = await render(emailTemplate, { pretty: true });
|
||||
const text = await render(emailTemplate, { plainText: true });
|
||||
|
||||
if (!isDefined(workspaceMember.userEmail)) {
|
||||
throw new Error('Workspace member email is missing');
|
||||
}
|
||||
|
||||
this.emailService.send({
|
||||
to: workspaceMember.userEmail,
|
||||
from: `${this.twentyConfigService.get(
|
||||
|
||||
+2
-3
@@ -2,7 +2,6 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { type WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface';
|
||||
|
||||
import { type FlatRole } from 'src/engine/metadata-modules/flat-role/types/flat-role.type';
|
||||
import { fromStandardRoleDefinitionToFlatRole } from 'src/engine/metadata-modules/flat-role/utils/from-standard-role-definition-to-flat-role.util';
|
||||
import { type RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { type StandardRoleDefinition } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-roles/types/standard-role-definition.interface';
|
||||
@@ -13,8 +12,8 @@ export class StandardRoleFactory {
|
||||
roleDefinitions: StandardRoleDefinition[],
|
||||
context: WorkspaceSyncContext,
|
||||
existingRoles: RoleEntity[],
|
||||
): FlatRole[] {
|
||||
const computedRoles: FlatRole[] = [];
|
||||
): Partial<RoleEntity>[] {
|
||||
const computedRoles: Partial<RoleEntity>[] = [];
|
||||
|
||||
for (const roleDefinition of roleDefinitions) {
|
||||
const existingRole = existingRoles.find(
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ export class WorkspaceSyncRoleService {
|
||||
|
||||
const roleComparatorResults = this.workspaceRoleComparator.compare({
|
||||
fromFlatRoles: existingStandardRoleEntities.map(fromRoleEntityToFlatRole),
|
||||
toFlatRoles: targetStandardRoles,
|
||||
toFlatRoles: targetStandardRoles.map(fromRoleEntityToFlatRole),
|
||||
});
|
||||
|
||||
for (const roleComparatorResult of roleComparatorResults) {
|
||||
|
||||
Reference in New Issue
Block a user