Delete unused objects (#7823)

Fixes #7113

---------

Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
Félix Malfait
2024-10-30 13:35:43 +01:00
committed by GitHub
parent 57d9b8e8b4
commit 50c912d57f
45 changed files with 422 additions and 1094 deletions

View File

@@ -5,7 +5,6 @@ export type Attachment = {
type: AttachmentType;
companyId: string;
personId: string;
activityId: string;
authorId: string;
createdAt: string;
__typename: string;

View File

@@ -18,7 +18,6 @@ const mockActivityTarget = {
updatedAt: '2021-08-03T19:20:06.000Z',
createdAt: '2021-08-03T19:20:06.000Z',
personId: '1',
activityId: '234',
companyId: '1',
id: '123',
};

View File

@@ -37,7 +37,6 @@ const mocks: MockedResponse[] = [
edges {
node {
__typename
activityId
authorId
companyId
createdAt

View File

@@ -51,7 +51,6 @@ const mocks: MockedResponse[] = [
edges {
node {
__typename
activityId
authorId
companyId
createdAt
@@ -138,6 +137,9 @@ const mocks: MockedResponse[] = [
rocketId
taskId
updatedAt
workflowId
workflowRunId
workflowVersionId
workspaceMemberId
}
}

View File

@@ -316,6 +316,219 @@ export const mocks = [
}
workspaceMemberId
}
}
companyId
createdAt
deletedAt
id
note {
__typename
body
createdAt
createdBy {
source
workspaceMemberId
name
}
deletedAt
id
position
title
updatedAt
}
noteId
opportunity {
__typename
amount {
amountMicros
currencyCode
}
closeDate
companyId
createdAt
createdBy {
source
workspaceMemberId
name
}
deletedAt
id
name
pointOfContactId
position
stage
updatedAt
}
opportunityId
person {
__typename
avatarUrl
city
companyId
createdAt
createdBy {
source
workspaceMemberId
name
}
deletedAt
emails {
primaryEmail
additionalEmails
}
id
intro
jobTitle
linkedinLink {
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
name {
firstName
lastName
}
performanceRating
phones {
primaryPhoneNumber
primaryPhoneCountryCode
additionalPhones
}
position
updatedAt
whatsapp {
primaryPhoneNumber
primaryPhoneCountryCode
additionalPhones
}
workPreference
xLink {
primaryLinkUrl
primaryLinkLabel
secondaryLinks
}
}
personId
position
rocket {
__typename
createdAt
createdBy {
source
workspaceMemberId
name
}
deletedAt
id
name
position
updatedAt
}
rocketId
task {
__typename
assigneeId
body
createdAt
createdBy {
source
workspaceMemberId
name
}
deletedAt
dueAt
id
position
status
title
updatedAt
}
taskId
updatedAt
view {
__typename
createdAt
deletedAt
icon
id
isCompact
kanbanFieldMetadataId
key
name
objectMetadataId
position
type
updatedAt
}
viewId
workflow {
__typename
createdAt
deletedAt
id
lastPublishedVersionId
name
position
statuses
updatedAt
}
workflowId
workflowRun {
__typename
createdAt
createdBy {
source
workspaceMemberId
name
}
deletedAt
endedAt
id
name
output
position
startedAt
status
updatedAt
workflowId
workflowVersionId
}
workflowRunId
workflowVersion {
__typename
createdAt
deletedAt
id
name
position
status
steps
trigger
updatedAt
workflowId
}
workflowVersionId
workspaceMember {
__typename
avatarUrl
colorScheme
createdAt
dateFormat
deletedAt
id
locale
name {
firstName
lastName
}
timeFormat
timeZone
updatedAt
userEmail
userId
}
workspaceMemberId
}
}
`,
variables: {
@@ -575,6 +788,41 @@ export const mocks = [
updatedAt
}
workflowId
workflowRun {
__typename
createdAt
createdBy {
source
workspaceMemberId
name
}
deletedAt
endedAt
id
name
output
position
startedAt
status
updatedAt
workflowId
workflowVersionId
}
workflowRunId
workflowVersion {
__typename
createdAt
deletedAt
id
name
position
status
steps
trigger
updatedAt
workflowId
}
workflowVersionId
workspaceMember {
__typename
avatarUrl

View File

@@ -3,7 +3,7 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
export const mapSoftDeleteFieldsToGraphQLQuery = (
objectMetadataItem: Pick<ObjectMetadataItem, 'fields'>,
): string => {
const softDeleteFields = ['id', 'deletedAt'];
const softDeleteFields = ['deletedAt', 'id'];
const fieldsThatShouldBeQueried = objectMetadataItem.fields.filter(
(field) => field.isActive && softDeleteFields.includes(field.name),

View File

@@ -49,27 +49,10 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ZERO_RELATIONS = `
export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
__typename
activityTargets {
edges {
node {
__typename
activityId
companyId
createdAt
deletedAt
id
opportunityId
personId
rocketId
updatedAt
}
}
}
attachments {
edges {
node {
__typename
activityId
authorId
companyId
createdAt
@@ -190,6 +173,8 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
updatedAt
viewId
workflowId
workflowRunId
workflowVersionId
workspaceMemberId
}
}
@@ -308,6 +293,9 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
rocketId
taskId
updatedAt
workflowId
workflowRunId
workflowVersionId
workspaceMemberId
}
}

View File

@@ -15,5 +15,7 @@ export const variables = {
};
export const responseData = {
__typename: 'Person',
deletedAt: '2024-02-14T09:45:00Z',
id: 'a7286b9a-c039-4a89-9567-2dfa7953cda9',
};

View File

@@ -99,20 +99,6 @@ export const query = gql`
}
city
email
activityTargets {
edges {
node {
__typename
id
updatedAt
createdAt
personId
activityId
companyId
id
}
}
}
jobTitle
favorites {
edges {
@@ -137,7 +123,6 @@ export const query = gql`
createdAt
name
personId
activityId
companyId
id
authorId

View File

@@ -8,8 +8,8 @@ const expectedQueryTemplate = `
mutation DeleteOnePerson($idToDelete: ID!) {
deletePerson(id: $idToDelete) {
__typename
deletedAt
id
deletedAt
}
}
`.replace(/\s/g, '');

View File

@@ -47,22 +47,6 @@ const mocks: MockedResponse[] = [
userId
}
accountOwnerId
activityTargets {
edges {
node {
__typename
activityId
companyId
createdAt
deletedAt
id
opportunityId
personId
rocketId
updatedAt
}
}
}
address {
addressStreet1
addressStreet2
@@ -81,7 +65,6 @@ const mocks: MockedResponse[] = [
edges {
node {
__typename
activityId
authorId
companyId
createdAt
@@ -129,6 +112,8 @@ const mocks: MockedResponse[] = [
updatedAt
viewId
workflowId
workflowRunId
workflowVersionId
workspaceMemberId
}
}
@@ -278,6 +263,9 @@ const mocks: MockedResponse[] = [
rocketId
taskId
updatedAt
workflowId
workflowRunId
workflowVersionId
workspaceMemberId
}
}

View File

@@ -46,22 +46,6 @@ const companyMocks = [
userId
}
accountOwnerId
activityTargets {
edges {
node {
__typename
activityId
companyId
createdAt
deletedAt
id
opportunityId
personId
rocketId
updatedAt
}
}
}
address {
addressStreet1
addressStreet2
@@ -80,7 +64,6 @@ const companyMocks = [
edges {
node {
__typename
activityId
authorId
companyId
createdAt

View File

@@ -88,19 +88,6 @@ export const query = gql`
}
city
email
activityTargets {
edges {
node {
id
updatedAt
createdAt
personId
activityId
companyId
id
}
}
}
jobTitle
favorites {
edges {
@@ -124,7 +111,6 @@ export const query = gql`
createdAt
name
personId
activityId
companyId
id
authorId

View File

@@ -88,35 +88,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: null,
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [
{
__typename: 'ActivityTargetEdge',
node: {
__typename: 'ActivityTarget',
id: '97114d7e-2a80-4401-af58-36c88e13e852',
activityId: '737a6c31-610a-457b-b087-791ac700fa46',
createdAt: '2023-11-24T13:15:03.523Z',
updatedAt: '2023-11-24T13:15:03.523Z',
companyId: '04b2e9f5-0713-40a5-8216-82802401d33e',
personId: null,
},
},
{
__typename: 'ActivityTargetEdge',
node: {
__typename: 'ActivityTarget',
id: 'cb29d37a-3d5e-4efb-afa3-38f4bff69912',
activityId: '3c6ea4a3-f71d-4c31-9dfa-f868a5de4091',
createdAt: '2023-11-24T13:14:57.628Z',
updatedAt: '2023-11-24T13:14:57.628Z',
companyId: '04b2e9f5-0713-40a5-8216-82802401d33e',
personId: null,
},
},
],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -339,10 +310,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -489,10 +456,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -554,10 +517,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -755,10 +714,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -820,10 +775,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -885,10 +836,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -950,10 +897,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -1048,10 +991,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -1146,10 +1085,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -1211,10 +1146,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -1276,10 +1207,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,
@@ -1426,10 +1353,6 @@ export const SIGN_IN_BACKGROUND_MOCK_COMPANIES = [
secondaryLinks: [],
__typename: 'Links',
},
activityTargets: {
__typename: 'ActivityTargetConnection',
edges: [],
},
annualRecurringRevenue: {
__typename: 'Currency',
amountMicros: null,

View File

@@ -40,21 +40,6 @@ const meta: Meta<PageDecoratorArgs> = {
},
});
}),
graphql.query('FindManyActivityTargets', () => {
return HttpResponse.json({
data: {
activityTargets: {
edges: [],
pageInfo: {
hasNextPage: false,
startCursor: '',
endCursor: '',
},
totalCount: 0,
},
},
});
}),
graphql.query('FindOneworkspaceMember', () => {
return HttpResponse.json({
data: {

View File

@@ -259,9 +259,13 @@ export const graphqlMocks = {
edges: [],
__typename: 'OpportunityConnection',
},
activityTargets: {
taskTargets: {
edges: [],
__typename: 'ActivityTargetConnection',
__typename: 'TaskTargetConnection',
},
noteTargets: {
edges: [],
__typename: 'NoteTargetConnection',
},
},
cursor: null,
@@ -301,9 +305,13 @@ export const graphqlMocks = {
edges: [],
__typename: 'OpportunityConnection',
},
activityTargets: {
taskTargets: {
edges: [],
__typename: 'ActivityTargetConnection',
__typename: 'TaskTargetConnection',
},
noteTargets: {
edges: [],
__typename: 'NoteTargetConnection',
},
},
cursor: null,

View File

@@ -9,11 +9,11 @@ import { EnvironmentService } from 'src/engine/core-modules/environment/environm
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { KeyValuePair } from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
import { PostgresCredentials } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.entity';
import { WorkspaceSSOIdentityProvider } from 'src/engine/core-modules/sso/workspace-sso-identity-provider.entity';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
import { WorkspaceSSOIdentityProvider } from 'src/engine/core-modules/sso/workspace-sso-identity-provider.entity';
@Injectable()
export class TypeORMService implements OnModuleInit, OnModuleDestroy {

View File

@@ -386,7 +386,6 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
) {
const relatedObjectTypes = [
'timelineActivity',
'activityTarget',
'favorite',
'attachment',
'noteTarget',

View File

@@ -1,28 +1,27 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository } from 'typeorm';
import { FieldMetadataSettings } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
import {
FieldMetadataEntity,
FieldMetadataType,
} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { createForeignKeyDeterministicUuid } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { createRelationForeignKeyFieldMetadataName } from 'src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util';
import { buildMigrationsToCreateRemoteTableRelations } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-relations/utils/build-migrations-to-create-remote-table-relations.util';
import { buildMigrationsToRemoveRemoteTableRelations } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-relations/utils/build-migrations-to-remove-remote-table-relations.util';
import { mapUdtNameToFieldType } from 'src/engine/metadata-modules/remote-server/remote-table/utils/udt-name-mapper.util';
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
import {
ACTIVITY_TARGET_STANDARD_FIELD_IDS,
ATTACHMENT_STANDARD_FIELD_IDS,
FAVORITE_STANDARD_FIELD_IDS,
TIMELINE_ACTIVITY_STANDARD_FIELD_IDS,
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { buildMigrationsToCreateRemoteTableRelations } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-relations/utils/build-migrations-to-create-remote-table-relations.util';
import { buildMigrationsToRemoveRemoteTableRelations } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-relations/utils/build-migrations-to-remove-remote-table-relations.util';
import { mapUdtNameToFieldType } from 'src/engine/metadata-modules/remote-server/remote-table/utils/udt-name-mapper.util';
import { createRelationForeignKeyFieldMetadataName } from 'src/engine/metadata-modules/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util';
import { createForeignKeyDeterministicUuid } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util';
@Injectable()
export class RemoteTableRelationsService {
@@ -54,14 +53,6 @@ export class RemoteTableRelationsService {
objectPrimaryKeyFieldSettings,
);
const activityTargetObjectMetadata =
await this.createActivityTargetRelation(
workspaceId,
remoteObjectMetadata,
objectPrimaryKeyFieldType,
objectPrimaryKeyFieldSettings,
);
const attachmentObjectMetadata = await this.createAttachmentRelation(
workspaceId,
remoteObjectMetadata,
@@ -87,7 +78,6 @@ export class RemoteTableRelationsService {
remoteObjectMetadata.nameSingular,
[
favoriteObjectMetadata,
activityTargetObjectMetadata,
attachmentObjectMetadata,
timelineActivityObjectMetadata,
],
@@ -107,12 +97,6 @@ export class RemoteTableRelationsService {
workspaceId: workspaceId,
});
const activityTargetObjectMetadata =
await this.objectMetadataRepository.findOneByOrFail({
nameSingular: 'activityTarget',
workspaceId: workspaceId,
});
const attachmentObjectMetadata =
await this.objectMetadataRepository.findOneByOrFail({
nameSingular: 'attachment',
@@ -136,7 +120,6 @@ export class RemoteTableRelationsService {
name: targetColumnName,
objectMetadataId: In([
favoriteObjectMetadata.id,
activityTargetObjectMetadata.id,
attachmentObjectMetadata.id,
timelineActivityObjectMetadata.id,
]),
@@ -158,53 +141,12 @@ export class RemoteTableRelationsService {
workspaceId,
buildMigrationsToRemoveRemoteTableRelations(targetColumnName, [
favoriteObjectMetadata,
activityTargetObjectMetadata,
attachmentObjectMetadata,
timelineActivityObjectMetadata,
]),
);
}
private async createActivityTargetRelation(
workspaceId: string,
createdObjectMetadata: ObjectMetadataEntity,
objectPrimaryKeyType: FieldMetadataType,
objectPrimaryKeyFieldSettings:
| FieldMetadataSettings<FieldMetadataType | 'default'>
| undefined,
) {
const activityTargetObjectMetadata =
await this.objectMetadataRepository.findOneByOrFail({
nameSingular: 'activityTarget',
workspaceId: workspaceId,
});
await this.fieldMetadataRepository.save(
// Foreign key
{
standardId: createForeignKeyDeterministicUuid({
objectId: createdObjectMetadata.id,
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.custom,
}),
objectMetadataId: activityTargetObjectMetadata.id,
workspaceId: workspaceId,
isCustom: false,
isActive: true,
type: objectPrimaryKeyType,
name: `${createdObjectMetadata.nameSingular}Id`,
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
description: `ActivityTarget ${createdObjectMetadata.labelSingular} id foreign key`,
icon: undefined,
isNullable: true,
isSystem: true,
defaultValue: undefined,
settings: { ...objectPrimaryKeyFieldSettings, isForeignKey: true },
},
);
return activityTargetObjectMetadata;
}
private async createAttachmentRelation(
workspaceId: string,
createdObjectMetadata: ObjectMetadataEntity,

View File

@@ -1,9 +1,9 @@
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import {
WorkspaceMigrationTableAction,
WorkspaceMigrationTableActionType,
WorkspaceMigrationColumnActionType,
WorkspaceMigrationColumnDrop,
WorkspaceMigrationTableAction,
WorkspaceMigrationTableActionType,
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
import { computeTableName } from 'src/engine/utils/compute-table-name.util';

View File

@@ -22,7 +22,6 @@ import {
FieldTypeAndNameMetadata,
getTsVectorColumnExpressionFromFields,
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-objects/activity-target.workspace-entity';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity';
import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/note-target.workspace-entity';
@@ -71,19 +70,6 @@ export class CustomWorkspaceEntity extends BaseWorkspaceEntity {
})
createdBy: ActorMetadata;
@WorkspaceRelation({
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.activityTargets,
label: 'Activities',
type: RelationMetadataType.ONE_TO_MANY,
description: (objectMetadata) =>
`Activities tied to the ${objectMetadata.labelSingular}`,
icon: 'IconCheckbox',
inverseSideTarget: () => ActivityTargetWorkspaceEntity,
onDelete: RelationOnDeleteAction.CASCADE,
})
@WorkspaceIsNullable()
activityTargets: ActivityTargetWorkspaceEntity[];
@WorkspaceRelation({
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.noteTargets,
label: 'Notes',

View File

@@ -67,7 +67,7 @@ export const notesAllView = (
TODO: Add later, since we don't have real-time it probably doesn't work well?
{
fieldMetadataId:
objectMetadataMap[STANDARD_OBJECT_IDS.activity].fields[
objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[
BASE_OBJECT_STANDARD_FIELD_IDS.updatedAt
],
position: 0,

View File

@@ -4,15 +4,16 @@ import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/wo
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
import {
WorkspaceMigrationColumnActionType,
WorkspaceMigrationEntity,
WorkspaceMigrationTableAction,
WorkspaceMigrationTableActionType,
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory';
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
export interface ObjectMetadataUpdate {
current: ObjectMetadataEntity;
@@ -27,9 +28,7 @@ export class WorkspaceMigrationObjectFactory {
async create(
objectMetadataCollection: ObjectMetadataEntity[],
action:
| WorkspaceMigrationBuilderAction.CREATE
| WorkspaceMigrationBuilderAction.DELETE,
action: WorkspaceMigrationBuilderAction.CREATE,
): Promise<Partial<WorkspaceMigrationEntity>[]>;
async create(
@@ -37,11 +36,24 @@ export class WorkspaceMigrationObjectFactory {
action: WorkspaceMigrationBuilderAction.UPDATE,
): Promise<Partial<WorkspaceMigrationEntity>[]>;
async create(
objectMetadataCollection: ObjectMetadataEntity[],
action: WorkspaceMigrationBuilderAction.DELETE,
relationMetadataByFromObjectMetadataId: Record<
string,
RelationMetadataEntity[]
>,
): Promise<Partial<WorkspaceMigrationEntity>[]>;
async create(
objectMetadataCollectionOrObjectMetadataUpdateCollection:
| ObjectMetadataEntity[]
| ObjectMetadataUpdate[],
action: WorkspaceMigrationBuilderAction,
relationMetadataByFromObjectMetadataId?: Record<
string,
RelationMetadataEntity[]
>,
): Promise<Partial<WorkspaceMigrationEntity>[]> {
switch (action) {
case WorkspaceMigrationBuilderAction.CREATE:
@@ -55,6 +67,10 @@ export class WorkspaceMigrationObjectFactory {
case WorkspaceMigrationBuilderAction.DELETE:
return this.deleteObjectMigration(
objectMetadataCollectionOrObjectMetadataUpdateCollection as ObjectMetadataEntity[],
relationMetadataByFromObjectMetadataId as Record<
string,
RelationMetadataEntity[]
>,
);
default:
return [];
@@ -136,22 +152,43 @@ export class WorkspaceMigrationObjectFactory {
private async deleteObjectMigration(
objectMetadataCollection: ObjectMetadataEntity[],
relationMetadataByFromObjectMetadataId: Record<
string,
RelationMetadataEntity[]
>,
): Promise<Partial<WorkspaceMigrationEntity>[]> {
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
for (const objectMetadata of objectMetadataCollection) {
const migrations: WorkspaceMigrationTableAction[] = [
{
name: computeObjectTargetTable(objectMetadata),
action: WorkspaceMigrationTableActionType.DROP,
},
];
const relationMetadataCollection =
relationMetadataByFromObjectMetadataId[objectMetadata.id];
workspaceMigrations.push({
workspaceId: objectMetadata.workspaceId,
name: generateMigrationName(`delete-${objectMetadata.nameSingular}`),
isCustom: false,
migrations,
migrations: [
...(relationMetadataCollection ?? []).map(
(relationMetadata) =>
({
name: computeObjectTargetTable(
relationMetadata.toObjectMetadata,
),
action: WorkspaceMigrationTableActionType.ALTER,
columns: [
{
action: WorkspaceMigrationColumnActionType.DROP_FOREIGN_KEY,
columnName: `${relationMetadata.toFieldMetadata.name}Id`,
},
],
}) satisfies WorkspaceMigrationTableAction,
),
{
name: computeObjectTargetTable(objectMetadata),
action: WorkspaceMigrationTableActionType.DROP,
columns: [],
} satisfies WorkspaceMigrationTableAction,
],
});
}

View File

@@ -5,6 +5,7 @@
* For readability keys can be edited but the values should not be changed.
*/
// TODO: check if this can be deleted
export const ACTIVITY_TARGET_STANDARD_FIELD_IDS = {
activity: '20202020-ca58-478c-a4f5-ae825671c30e',
person: '20202020-4afd-4ae7-99c2-de57d795a93f',
@@ -13,6 +14,7 @@ export const ACTIVITY_TARGET_STANDARD_FIELD_IDS = {
custom: '20202020-7f21-442f-94be-32462281b1ca',
};
// TODO: check if this can be deleted
export const ACTIVITY_STANDARD_FIELD_IDS = {
title: '20202020-24a1-4d94-a071-617f3eeed7b0',
body: '20202020-209b-440a-b2a8-043fa36a7d37',
@@ -109,6 +111,7 @@ export const CALENDAR_EVENT_STANDARD_FIELD_IDS = {
calendarEventParticipants: '20202020-e07e-4ccb-88f5-6f3d00458eec',
};
// TODO: check if this can be deleted
export const COMMENT_STANDARD_FIELD_IDS = {
body: '20202020-d5eb-49d2-b3e0-1ed04145ebb7',
author: '20202020-2ab1-427e-a981-cf089de3a9bd',
@@ -129,6 +132,7 @@ export const COMPANY_STANDARD_FIELD_IDS = {
createdBy: '20202020-fabc-451d-ab7d-412170916baa',
people: '20202020-3213-4ddf-9494-6422bcff8d7c',
accountOwner: '20202020-95b8-4e10-9881-edb5d4765f9d',
// TODO: check if activityTargets field can be deleted
activityTargets: '20202020-c2a5-4c9b-9d9a-582bcd57fbc8',
taskTargets: '20202020-cb17-4a61-8f8f-3be6730480de',
noteTargets: '20202020-bae0-4556-a74a-a9c686f77a88',
@@ -304,6 +308,7 @@ export const OPPORTUNITY_STANDARD_FIELD_IDS = {
pointOfContact: '20202020-8dfb-42fc-92b6-01afb759ed16',
company: '20202020-cbac-457e-b565-adece5fc815f',
favorites: '20202020-a1c2-4500-aaae-83ba8a0e827a',
// TODO: check if activityTargets field can be deleted
activityTargets: '20202020-220a-42d6-8261-b2102d6eab35',
taskTargets: '20202020-59c0-4179-a208-4a255f04a5be',
noteTargets: '20202020-dd3f-42d5-a382-db58aabf43d3',
@@ -327,6 +332,7 @@ export const PERSON_STANDARD_FIELD_IDS = {
createdBy: '20202020-f6ab-4d98-af24-a3d5b664148a',
company: '20202020-e2f3-448e-b34c-2d625f0025fd',
pointOfContactForOpportunities: '20202020-911b-4a7d-b67b-918aa9a5b33a',
// TODO: check if activityTargets field can be deleted
activityTargets: '20202020-dee7-4b7f-b50a-1f50bd3be452',
taskTargets: '20202020-584b-4d3e-88b6-53ab1fa03c3a',
noteTargets: '20202020-c8fc-4258-8250-15905d3fcfec',
@@ -498,6 +504,7 @@ export const CUSTOM_OBJECT_STANDARD_FIELD_IDS = {
name: '20202020-ba07-4ffd-ba63-009491f5749c',
position: '20202020-c2bd-4e16-bb9a-c8b0411bf49d',
createdBy: '20202020-be0e-4971-865b-32ca87cbb315',
// TODO: check if activityTargets field can be deleted
activityTargets: '20202020-7f42-40ae-b96c-c8a61acc83bf',
noteTargets: '20202020-01fd-4f37-99dc-9427a444018a',
taskTargets: '20202020-0860-4566-b865-bff3c626c303',

View File

@@ -6,6 +6,7 @@
*/
export const STANDARD_OBJECT_IDS = {
// TODO: check if activity, activityTarget and comment can be deleted
activityTarget: '20202020-2945-440e-8d1a-f84672d33d5e',
activity: '20202020-39aa-4a89-843b-eb5f2a8b677f',
apiKey: '20202020-4c00-401d-8cda-ec6a4c41cd7d',

View File

@@ -6,6 +6,7 @@ import {
FindOptionsWhere,
In,
ObjectLiteral,
Repository,
} from 'typeorm';
import { DeepPartial } from 'typeorm/common/DeepPartial';
import { v4 as uuidV4 } from 'uuid';
@@ -127,6 +128,11 @@ export class WorkspaceMetadataUpdaterService {
updatedFieldMetadataCollection: FieldMetadataUpdate[];
}> {
const fieldMetadataRepository = manager.getRepository(FieldMetadataEntity);
const indexFieldMetadataRepository = manager.getRepository(
IndexFieldMetadataEntity,
);
const indexMetadataRepository = manager.getRepository(IndexMetadataEntity);
/**
* Update field metadata
*/
@@ -157,6 +163,12 @@ export class WorkspaceMetadataUpdaterService {
);
if (fieldMetadataDeleteCollectionWithoutRelationType.length > 0) {
await this.deleteIndexFieldMetadata(
fieldMetadataDeleteCollectionWithoutRelationType,
indexFieldMetadataRepository,
indexMetadataRepository,
);
await fieldMetadataRepository.delete(
fieldMetadataDeleteCollectionWithoutRelationType.map(
(field) => field.id,
@@ -171,6 +183,33 @@ export class WorkspaceMetadataUpdaterService {
};
}
async deleteIndexFieldMetadata(
fieldMetadataDeleteCollectionWithoutRelationType: Partial<FieldMetadataEntity>[],
indexFieldMetadataRepository: Repository<IndexFieldMetadataEntity>,
indexMetadataRepository: Repository<IndexMetadataEntity>,
) {
const indexFieldMetadatas = await indexFieldMetadataRepository.find({
where: {
fieldMetadataId: In(
fieldMetadataDeleteCollectionWithoutRelationType.map(
(field) => field.id,
),
),
},
relations: {
indexMetadata: true,
},
});
const uniqueIndexMetadataIds = [
...new Set(indexFieldMetadatas.map((field) => field.indexMetadataId)),
];
if (uniqueIndexMetadataIds.length > 0) {
await indexMetadataRepository.delete(uniqueIndexMetadataIds);
}
}
async updateRelationMetadata(
manager: EntityManager,
storage: WorkspaceSyncStorage,

View File

@@ -8,6 +8,7 @@ import { ComparatorAction } from 'src/engine/workspace-manager/workspace-sync-me
import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
import { WorkspaceMigrationObjectFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-object.factory';
import { WorkspaceObjectComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-object.comparator';
@@ -37,6 +38,10 @@ export class WorkspaceSyncObjectMetadataService {
const objectMetadataRepository =
manager.getRepository(ObjectMetadataEntity);
const relationMetadataRepository = manager.getRepository(
RelationMetadataEntity,
);
// Retrieve object metadata collection from DB
const originalObjectMetadataCollection =
await objectMetadataRepository.find({
@@ -47,6 +52,33 @@ export class WorkspaceSyncObjectMetadataService {
relations: ['dataSource', 'fields'],
});
// Retrieve relation metadata collection from DB
const originalRelationMetadataCollection =
await relationMetadataRepository.find({
where: {
workspaceId: context.workspaceId,
},
relations: ['toObjectMetadata', 'toFieldMetadata'],
});
const relationMetadataByFromObjectMetadataId: Record<
string,
RelationMetadataEntity[]
> = originalRelationMetadataCollection.reduce(
(acc, relationMetadata) => {
const fromObjectMetadataId = relationMetadata.fromObjectMetadataId;
if (!acc[fromObjectMetadataId]) {
acc[fromObjectMetadataId] = [];
}
acc[fromObjectMetadataId].push(relationMetadata);
return acc;
},
{} as Record<string, RelationMetadataEntity[]>,
);
// Create standard object metadata collection
const standardObjectMetadataCollection = this.standardObjectFactory.create(
standardObjectMetadataDefinitions,
@@ -129,6 +161,7 @@ export class WorkspaceSyncObjectMetadataService {
await this.workspaceMigrationObjectFactory.create(
storage.objectMetadataDeleteCollection,
WorkspaceMigrationBuilderAction.DELETE,
relationMetadataByFromObjectMetadataId,
);
this.logger.log('Saving migrations');

View File

@@ -1,6 +1,3 @@
import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-objects/activity-target.workspace-entity';
import { ActivityWorkspaceEntity } from 'src/modules/activity/standard-objects/activity.workspace-entity';
import { CommentWorkspaceEntity } from 'src/modules/activity/standard-objects/comment.workspace-entity';
import { ApiKeyWorkspaceEntity } from 'src/modules/api-key/standard-objects/api-key.workspace-entity';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
import { BlocklistWorkspaceEntity } from 'src/modules/blocklist/standard-objects/blocklist.workspace-entity';
@@ -41,8 +38,6 @@ import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/sta
// TODO: Maybe we should automate this with the DiscoverService of Nest.JS
export const standardObjectMetadataDefinitions = [
ActivityTargetWorkspaceEntity,
ActivityWorkspaceEntity,
ApiKeyWorkspaceEntity,
AuditLogWorkspaceEntity,
AttachmentWorkspaceEntity,
@@ -52,7 +47,6 @@ export const standardObjectMetadataDefinitions = [
CalendarChannelWorkspaceEntity,
CalendarChannelEventAssociationWorkspaceEntity,
CalendarEventParticipantWorkspaceEntity,
CommentWorkspaceEntity,
CompanyWorkspaceEntity,
ConnectedAccountWorkspaceEntity,
FavoriteWorkspaceEntity,

View File

@@ -1,104 +0,0 @@
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity';
import { WorkspaceDynamicRelation } from 'src/engine/twenty-orm/decorators/workspace-dynamic-relation.decorator';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator';
import { ACTIVITY_TARGET_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ActivityWorkspaceEntity } from 'src/modules/activity/standard-objects/activity.workspace-entity';
import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity';
import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity';
import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity';
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.activityTarget,
namePlural: 'activityTargets',
labelSingular: 'Activity Target',
labelPlural: 'Activity Targets',
description: 'An activity target',
icon: STANDARD_OBJECT_ICONS.activityTarget,
})
@WorkspaceIsSystem()
export class ActivityTargetWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceRelation({
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.activity,
type: RelationMetadataType.MANY_TO_ONE,
label: 'Activity',
description: 'ActivityTarget activity',
icon: 'IconNotes',
inverseSideTarget: () => ActivityWorkspaceEntity,
inverseSideFieldKey: 'activityTargets',
})
@WorkspaceIsNullable()
activity: Relation<ActivityWorkspaceEntity> | null;
@WorkspaceJoinColumn('activity')
activityId: string | null;
@WorkspaceRelation({
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.person,
type: RelationMetadataType.MANY_TO_ONE,
label: 'Person',
description: 'ActivityTarget person',
icon: 'IconUser',
inverseSideTarget: () => PersonWorkspaceEntity,
inverseSideFieldKey: 'activityTargets',
})
@WorkspaceIsNullable()
person: Relation<PersonWorkspaceEntity> | null;
@WorkspaceJoinColumn('person')
personId: string | null;
@WorkspaceRelation({
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.company,
type: RelationMetadataType.MANY_TO_ONE,
label: 'Company',
description: 'ActivityTarget company',
icon: 'IconBuildingSkyscraper',
inverseSideTarget: () => CompanyWorkspaceEntity,
inverseSideFieldKey: 'activityTargets',
})
@WorkspaceIsNullable()
company: Relation<CompanyWorkspaceEntity> | null;
@WorkspaceJoinColumn('company')
companyId: string | null;
@WorkspaceRelation({
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.opportunity,
type: RelationMetadataType.MANY_TO_ONE,
label: 'Opportunity',
description: 'ActivityTarget opportunity',
icon: 'IconTargetArrow',
inverseSideTarget: () => OpportunityWorkspaceEntity,
inverseSideFieldKey: 'activityTargets',
})
@WorkspaceIsNullable()
opportunity: Relation<OpportunityWorkspaceEntity> | null;
@WorkspaceJoinColumn('opportunity')
opportunityId: string | null;
@WorkspaceDynamicRelation({
type: RelationMetadataType.MANY_TO_ONE,
argsFactory: (oppositeObjectMetadata) => ({
standardId: ACTIVITY_TARGET_STANDARD_FIELD_IDS.custom,
name: oppositeObjectMetadata.nameSingular,
label: oppositeObjectMetadata.labelSingular,
description: `ActivityTarget ${oppositeObjectMetadata.labelSingular}`,
joinColumn: `${oppositeObjectMetadata.nameSingular}Id`,
icon: 'IconBuildingSkyscraper',
}),
inverseSideTarget: () => CustomWorkspaceEntity,
inverseSideFieldKey: 'activityTargets',
})
custom: Relation<CustomWorkspaceEntity>;
}

View File

@@ -1,159 +0,0 @@
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import {
RelationMetadataType,
RelationOnDeleteAction,
} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator';
import { ACTIVITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-objects/activity-target.workspace-entity';
import { CommentWorkspaceEntity } from 'src/modules/activity/standard-objects/comment.workspace-entity';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.activity,
namePlural: 'activities',
labelSingular: 'Activity',
labelPlural: 'Activities',
description: 'An activity',
icon: STANDARD_OBJECT_ICONS.activity,
labelIdentifierStandardId: ACTIVITY_STANDARD_FIELD_IDS.title,
})
@WorkspaceIsSystem()
export class ActivityWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
standardId: ACTIVITY_STANDARD_FIELD_IDS.title,
type: FieldMetadataType.TEXT,
label: 'Title',
description: 'Activity title',
icon: 'IconNotes',
})
title: string;
@WorkspaceField({
standardId: ACTIVITY_STANDARD_FIELD_IDS.body,
type: FieldMetadataType.TEXT,
label: 'Body',
description: 'Activity body',
icon: 'IconList',
})
body: string;
@WorkspaceField({
standardId: ACTIVITY_STANDARD_FIELD_IDS.type,
type: FieldMetadataType.TEXT,
label: 'Type',
description: 'Activity type',
icon: 'IconCheckbox',
defaultValue: "'Note'",
})
type: string;
@WorkspaceField({
standardId: ACTIVITY_STANDARD_FIELD_IDS.reminderAt,
type: FieldMetadataType.DATE_TIME,
label: 'Reminder Date',
description: 'Activity reminder date',
icon: 'IconCalendarEvent',
})
@WorkspaceIsNullable()
reminderAt: Date | null;
@WorkspaceField({
standardId: ACTIVITY_STANDARD_FIELD_IDS.dueAt,
type: FieldMetadataType.DATE_TIME,
label: 'Due Date',
description: 'Activity due date',
icon: 'IconCalendarEvent',
})
@WorkspaceIsNullable()
dueAt: Date | null;
@WorkspaceField({
standardId: ACTIVITY_STANDARD_FIELD_IDS.completedAt,
type: FieldMetadataType.DATE_TIME,
label: 'Completion Date',
description: 'Activity completion date',
icon: 'IconCheck',
})
@WorkspaceIsNullable()
completedAt: Date | null;
@WorkspaceRelation({
standardId: ACTIVITY_STANDARD_FIELD_IDS.activityTargets,
label: 'Targets',
description: 'Activity targets',
icon: 'IconCheckbox',
type: RelationMetadataType.ONE_TO_MANY,
inverseSideTarget: () => ActivityTargetWorkspaceEntity,
onDelete: RelationOnDeleteAction.SET_NULL,
})
@WorkspaceIsNullable()
activityTargets: Relation<ActivityTargetWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: ACTIVITY_STANDARD_FIELD_IDS.attachments,
label: 'Attachments',
description: 'Activity attachments',
icon: 'IconFileImport',
type: RelationMetadataType.ONE_TO_MANY,
inverseSideTarget: () => AttachmentWorkspaceEntity,
onDelete: RelationOnDeleteAction.SET_NULL,
})
@WorkspaceIsNullable()
attachments: Relation<AttachmentWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: ACTIVITY_STANDARD_FIELD_IDS.comments,
label: 'Comments',
description: 'Activity comments',
icon: 'IconComment',
type: RelationMetadataType.ONE_TO_MANY,
inverseSideTarget: () => CommentWorkspaceEntity,
onDelete: RelationOnDeleteAction.CASCADE,
})
@WorkspaceIsNullable()
comments: Relation<CommentWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: ACTIVITY_STANDARD_FIELD_IDS.author,
label: 'Author',
description: 'Activity author',
icon: 'IconUserCircle',
type: RelationMetadataType.MANY_TO_ONE,
inverseSideTarget: () => WorkspaceMemberWorkspaceEntity,
inverseSideFieldKey: 'authoredActivities',
onDelete: RelationOnDeleteAction.SET_NULL,
})
@WorkspaceIsNullable()
author: Relation<WorkspaceMemberWorkspaceEntity> | null;
@WorkspaceJoinColumn('author')
authorId: string | null;
@WorkspaceRelation({
standardId: ACTIVITY_STANDARD_FIELD_IDS.assignee,
label: 'Assignee',
description: 'Activity assignee',
icon: 'IconUserCircle',
type: RelationMetadataType.MANY_TO_ONE,
inverseSideTarget: () => WorkspaceMemberWorkspaceEntity,
inverseSideFieldKey: 'assignedActivities',
onDelete: RelationOnDeleteAction.SET_NULL,
})
@WorkspaceIsNullable()
assignee: Relation<WorkspaceMemberWorkspaceEntity> | null;
@WorkspaceJoinColumn('assignee')
assigneeId: string | null;
}

View File

@@ -1,63 +0,0 @@
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator';
import { COMMENT_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ActivityWorkspaceEntity } from 'src/modules/activity/standard-objects/activity.workspace-entity';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.comment,
namePlural: 'comments',
labelSingular: 'Comment',
labelPlural: 'Comments',
description: 'A comment',
icon: STANDARD_OBJECT_ICONS.comment,
})
@WorkspaceIsSystem()
export class CommentWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
standardId: COMMENT_STANDARD_FIELD_IDS.body,
type: FieldMetadataType.TEXT,
label: 'Body',
description: 'Comment body',
icon: 'IconLink',
})
body: string;
@WorkspaceRelation({
standardId: COMMENT_STANDARD_FIELD_IDS.author,
type: RelationMetadataType.MANY_TO_ONE,
label: 'Author',
description: 'Comment author',
icon: 'IconCircleUser',
inverseSideTarget: () => WorkspaceMemberWorkspaceEntity,
inverseSideFieldKey: 'authoredComments',
})
author: Relation<WorkspaceMemberWorkspaceEntity>;
@WorkspaceJoinColumn('author')
authorId: string;
@WorkspaceRelation({
standardId: COMMENT_STANDARD_FIELD_IDS.activity,
type: RelationMetadataType.MANY_TO_ONE,
label: 'Activity',
description: 'Comment activity',
icon: 'IconNotes',
inverseSideTarget: () => ActivityWorkspaceEntity,
inverseSideFieldKey: 'comments',
})
activity: Relation<ActivityWorkspaceEntity>;
@WorkspaceJoinColumn('activity')
activityId: string;
}

View File

@@ -15,7 +15,6 @@ import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-re
import { ATTACHMENT_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ActivityWorkspaceEntity } from 'src/modules/activity/standard-objects/activity.workspace-entity';
import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity';
import { NoteWorkspaceEntity } from 'src/modules/note/standard-objects/note.workspace-entity';
import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity';
@@ -76,21 +75,6 @@ export class AttachmentWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceJoinColumn('author')
authorId: string;
@WorkspaceRelation({
standardId: ATTACHMENT_STANDARD_FIELD_IDS.activity,
type: RelationMetadataType.MANY_TO_ONE,
label: 'Activity',
description: 'Attachment activity',
icon: 'IconNotes',
inverseSideTarget: () => ActivityWorkspaceEntity,
inverseSideFieldKey: 'attachments',
})
@WorkspaceIsNullable()
activity: Relation<ActivityWorkspaceEntity> | null;
@WorkspaceJoinColumn('activity')
activityId: string | null;
@WorkspaceRelation({
standardId: ATTACHMENT_STANDARD_FIELD_IDS.task,
type: RelationMetadataType.MANY_TO_ONE,

View File

@@ -30,7 +30,6 @@ import {
FieldTypeAndNameMetadata,
getTsVectorColumnExpressionFromFields,
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-objects/activity-target.workspace-entity';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity';
import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/note-target.workspace-entity';
@@ -198,19 +197,6 @@ export class CompanyWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceJoinColumn('accountOwner')
accountOwnerId: string | null;
@WorkspaceRelation({
standardId: COMPANY_STANDARD_FIELD_IDS.activityTargets,
type: RelationMetadataType.ONE_TO_MANY,
label: 'Activities',
description: 'Activities tied to the company',
icon: 'IconCheckbox',
inverseSideTarget: () => ActivityTargetWorkspaceEntity,
onDelete: RelationOnDeleteAction.CASCADE,
})
@WorkspaceIsNullable()
@WorkspaceIsSystem()
activityTargets: Relation<ActivityTargetWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: COMPANY_STANDARD_FIELD_IDS.taskTargets,
type: RelationMetadataType.ONE_TO_MANY,

View File

@@ -29,7 +29,6 @@ import {
FieldTypeAndNameMetadata,
getTsVectorColumnExpressionFromFields,
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-objects/activity-target.workspace-entity';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity';
import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity';
@@ -177,19 +176,6 @@ export class OpportunityWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceIsSystem()
favorites: Relation<FavoriteWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: OPPORTUNITY_STANDARD_FIELD_IDS.activityTargets,
type: RelationMetadataType.ONE_TO_MANY,
label: 'Activities',
description: 'Activities tied to the opportunity',
icon: 'IconCheckbox',
inverseSideTarget: () => ActivityTargetWorkspaceEntity,
onDelete: RelationOnDeleteAction.CASCADE,
})
@WorkspaceIsNullable()
@WorkspaceIsSystem()
activityTargets: Relation<ActivityTargetWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: OPPORTUNITY_STANDARD_FIELD_IDS.taskTargets,
type: RelationMetadataType.ONE_TO_MANY,

View File

@@ -32,7 +32,6 @@ import {
FieldTypeAndNameMetadata,
getTsVectorColumnExpressionFromFields,
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-objects/activity-target.workspace-entity';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity';
import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity';
@@ -205,18 +204,6 @@ export class PersonWorkspaceEntity extends BaseWorkspaceEntity {
})
pointOfContactForOpportunities: Relation<OpportunityWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: PERSON_STANDARD_FIELD_IDS.activityTargets,
type: RelationMetadataType.ONE_TO_MANY,
label: 'Activities',
description: 'Activities tied to the contact',
icon: 'IconCheckbox',
inverseSideTarget: () => ActivityTargetWorkspaceEntity,
onDelete: RelationOnDeleteAction.CASCADE,
})
@WorkspaceIsSystem()
activityTargets: Relation<ActivityTargetWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: PERSON_STANDARD_FIELD_IDS.taskTargets,
type: RelationMetadataType.ONE_TO_MANY,

View File

@@ -2,10 +2,9 @@ import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-que
import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { CommentWorkspaceEntity } from 'src/modules/activity/standard-objects/comment.workspace-entity';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
@WorkspaceQueryHook(`workspaceMember.deleteOne`)
export class WorkspaceMemberDeleteOnePreQueryHook
@@ -24,21 +23,12 @@ export class WorkspaceMemberDeleteOnePreQueryHook
'attachment',
);
const commentRepository =
await this.twentyORMManager.getRepository<CommentWorkspaceEntity>(
'comment',
);
const authorId = payload.id;
await attachmentRepository.delete({
authorId,
});
await commentRepository.delete({
authorId,
});
return payload;
}
}

View File

@@ -27,8 +27,6 @@ import {
FieldTypeAndNameMetadata,
getTsVectorColumnExpressionFromFields,
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
import { ActivityWorkspaceEntity } from 'src/modules/activity/standard-objects/activity.workspace-entity';
import { CommentWorkspaceEntity } from 'src/modules/activity/standard-objects/comment.workspace-entity';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
import { BlocklistWorkspaceEntity } from 'src/modules/blocklist/standard-objects/blocklist.workspace-entity';
import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity';
@@ -142,30 +140,6 @@ export class WorkspaceMemberWorkspaceEntity extends BaseWorkspaceEntity {
userId: string;
// Relations
@WorkspaceRelation({
standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.authoredActivities,
type: RelationMetadataType.ONE_TO_MANY,
label: 'Authored activities',
description: 'Activities created by the workspace member',
icon: 'IconCheckbox',
inverseSideTarget: () => ActivityWorkspaceEntity,
inverseSideFieldKey: 'author',
onDelete: RelationOnDeleteAction.SET_NULL,
})
authoredActivities: Relation<ActivityWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.assignedActivities,
type: RelationMetadataType.ONE_TO_MANY,
label: 'Assigned activities',
description: 'Activities assigned to the workspace member',
icon: 'IconCheckbox',
inverseSideTarget: () => ActivityWorkspaceEntity,
inverseSideFieldKey: 'assignee',
onDelete: RelationOnDeleteAction.SET_NULL,
})
assignedActivities: Relation<ActivityWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.assignedTasks,
type: RelationMetadataType.ONE_TO_MANY,
@@ -227,18 +201,6 @@ export class WorkspaceMemberWorkspaceEntity extends BaseWorkspaceEntity {
})
authoredAttachments: Relation<AttachmentWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.authoredComments,
type: RelationMetadataType.ONE_TO_MANY,
label: 'Authored comments',
description: 'Authored comments',
icon: 'IconComment',
inverseSideTarget: () => CommentWorkspaceEntity,
inverseSideFieldKey: 'author',
onDelete: RelationOnDeleteAction.SET_NULL,
})
authoredComments: Relation<CommentWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.connectedAccounts,
type: RelationMetadataType.ONE_TO_MANY,

View File

@@ -1,67 +0,0 @@
import request from 'supertest';
const client = request(`http://localhost:${APP_PORT}`);
describe('activitiesResolver (e2e)', () => {
it('should find many activities', () => {
const queryData = {
query: `
query activities {
activities {
edges {
node {
title
body
type
reminderAt
dueAt
completedAt
id
createdAt
updatedAt
deletedAt
authorId
assigneeId
}
}
}
}
`,
};
return client
.post('/graphql')
.set('Authorization', `Bearer ${ACCESS_TOKEN}`)
.send(queryData)
.expect(200)
.expect((res) => {
expect(res.body.data).toBeDefined();
expect(res.body.errors).toBeUndefined();
})
.expect((res) => {
const data = res.body.data.activities;
expect(data).toBeDefined();
expect(Array.isArray(data.edges)).toBe(true);
const edges = data.edges;
if (edges.length > 0) {
const activities = edges[0].node;
expect(activities).toHaveProperty('title');
expect(activities).toHaveProperty('body');
expect(activities).toHaveProperty('type');
expect(activities).toHaveProperty('reminderAt');
expect(activities).toHaveProperty('dueAt');
expect(activities).toHaveProperty('completedAt');
expect(activities).toHaveProperty('id');
expect(activities).toHaveProperty('createdAt');
expect(activities).toHaveProperty('updatedAt');
expect(activities).toHaveProperty('deletedAt');
expect(activities).toHaveProperty('authorId');
expect(activities).toHaveProperty('assigneeId');
}
});
});
});

View File

@@ -1,61 +0,0 @@
import request from 'supertest';
const client = request(`http://localhost:${APP_PORT}`);
describe('activityTargetsResolver (e2e)', () => {
it('should find many activityTargets', () => {
const queryData = {
query: `
query activityTargets {
activityTargets {
edges {
node {
id
createdAt
updatedAt
deletedAt
activityId
personId
companyId
opportunityId
rocketId
}
}
}
}
`,
};
return client
.post('/graphql')
.set('Authorization', `Bearer ${ACCESS_TOKEN}`)
.send(queryData)
.expect(200)
.expect((res) => {
expect(res.body.data).toBeDefined();
expect(res.body.errors).toBeUndefined();
})
.expect((res) => {
const data = res.body.data.activityTargets;
expect(data).toBeDefined();
expect(Array.isArray(data.edges)).toBe(true);
const edges = data.edges;
if (edges.length > 0) {
const activityTargets = edges[0].node;
expect(activityTargets).toHaveProperty('id');
expect(activityTargets).toHaveProperty('createdAt');
expect(activityTargets).toHaveProperty('updatedAt');
expect(activityTargets).toHaveProperty('deletedAt');
expect(activityTargets).toHaveProperty('activityId');
expect(activityTargets).toHaveProperty('personId');
expect(activityTargets).toHaveProperty('companyId');
expect(activityTargets).toHaveProperty('opportunityId');
expect(activityTargets).toHaveProperty('rocketId');
}
});
});
});

View File

@@ -18,7 +18,6 @@ describe('attachmentsResolver (e2e)', () => {
updatedAt
deletedAt
authorId
activityId
taskId
noteId
personId
@@ -60,7 +59,6 @@ describe('attachmentsResolver (e2e)', () => {
expect(attachments).toHaveProperty('updatedAt');
expect(attachments).toHaveProperty('deletedAt');
expect(attachments).toHaveProperty('authorId');
expect(attachments).toHaveProperty('activityId');
expect(attachments).toHaveProperty('taskId');
expect(attachments).toHaveProperty('noteId');
expect(attachments).toHaveProperty('personId');

View File

@@ -1,57 +0,0 @@
import request from 'supertest';
const client = request(`http://localhost:${APP_PORT}`);
describe('commentsResolver (e2e)', () => {
it('should find many comments', () => {
const queryData = {
query: `
query comments {
comments {
edges {
node {
body
id
createdAt
updatedAt
deletedAt
authorId
activityId
}
}
}
}
`,
};
return client
.post('/graphql')
.set('Authorization', `Bearer ${ACCESS_TOKEN}`)
.send(queryData)
.expect(200)
.expect((res) => {
expect(res.body.data).toBeDefined();
expect(res.body.errors).toBeUndefined();
})
.expect((res) => {
const data = res.body.data.comments;
expect(data).toBeDefined();
expect(Array.isArray(data.edges)).toBe(true);
const edges = data.edges;
if (edges.length > 0) {
const comments = edges[0].node;
expect(comments).toHaveProperty('body');
expect(comments).toHaveProperty('id');
expect(comments).toHaveProperty('createdAt');
expect(comments).toHaveProperty('updatedAt');
expect(comments).toHaveProperty('deletedAt');
expect(comments).toHaveProperty('authorId');
expect(comments).toHaveProperty('activityId');
}
});
});
});

View File

@@ -1,67 +0,0 @@
import request from 'supertest';
const client = request(`http://localhost:${APP_PORT}`);
describe('searchActivitiesResolver (e2e)', () => {
it('should find many searchActivities', () => {
const queryData = {
query: `
query searchActivities {
searchActivities {
edges {
node {
title
body
type
reminderAt
dueAt
completedAt
id
createdAt
updatedAt
deletedAt
authorId
assigneeId
}
}
}
}
`,
};
return client
.post('/graphql')
.set('Authorization', `Bearer ${ACCESS_TOKEN}`)
.send(queryData)
.expect(200)
.expect((res) => {
expect(res.body.data).toBeDefined();
expect(res.body.errors).toBeUndefined();
})
.expect((res) => {
const data = res.body.data.searchActivities;
expect(data).toBeDefined();
expect(Array.isArray(data.edges)).toBe(true);
const edges = data.edges;
if (edges.length > 0) {
const searchActivities = edges[0].node;
expect(searchActivities).toHaveProperty('title');
expect(searchActivities).toHaveProperty('body');
expect(searchActivities).toHaveProperty('type');
expect(searchActivities).toHaveProperty('reminderAt');
expect(searchActivities).toHaveProperty('dueAt');
expect(searchActivities).toHaveProperty('completedAt');
expect(searchActivities).toHaveProperty('id');
expect(searchActivities).toHaveProperty('createdAt');
expect(searchActivities).toHaveProperty('updatedAt');
expect(searchActivities).toHaveProperty('deletedAt');
expect(searchActivities).toHaveProperty('authorId');
expect(searchActivities).toHaveProperty('assigneeId');
}
});
});
});

View File

@@ -1,61 +0,0 @@
import request from 'supertest';
const client = request(`http://localhost:${APP_PORT}`);
describe('searchActivityTargetsResolver (e2e)', () => {
it('should find many searchActivityTargets', () => {
const queryData = {
query: `
query searchActivityTargets {
searchActivityTargets {
edges {
node {
id
createdAt
updatedAt
deletedAt
activityId
personId
companyId
opportunityId
rocketId
}
}
}
}
`,
};
return client
.post('/graphql')
.set('Authorization', `Bearer ${ACCESS_TOKEN}`)
.send(queryData)
.expect(200)
.expect((res) => {
expect(res.body.data).toBeDefined();
expect(res.body.errors).toBeUndefined();
})
.expect((res) => {
const data = res.body.data.searchActivityTargets;
expect(data).toBeDefined();
expect(Array.isArray(data.edges)).toBe(true);
const edges = data.edges;
if (edges.length > 0) {
const searchActivityTargets = edges[0].node;
expect(searchActivityTargets).toHaveProperty('id');
expect(searchActivityTargets).toHaveProperty('createdAt');
expect(searchActivityTargets).toHaveProperty('updatedAt');
expect(searchActivityTargets).toHaveProperty('deletedAt');
expect(searchActivityTargets).toHaveProperty('activityId');
expect(searchActivityTargets).toHaveProperty('personId');
expect(searchActivityTargets).toHaveProperty('companyId');
expect(searchActivityTargets).toHaveProperty('opportunityId');
expect(searchActivityTargets).toHaveProperty('rocketId');
}
});
});
});

View File

@@ -18,7 +18,6 @@ describe('searchAttachmentsResolver (e2e)', () => {
updatedAt
deletedAt
authorId
activityId
taskId
noteId
personId
@@ -60,7 +59,6 @@ describe('searchAttachmentsResolver (e2e)', () => {
expect(searchAttachments).toHaveProperty('updatedAt');
expect(searchAttachments).toHaveProperty('deletedAt');
expect(searchAttachments).toHaveProperty('authorId');
expect(searchAttachments).toHaveProperty('activityId');
expect(searchAttachments).toHaveProperty('taskId');
expect(searchAttachments).toHaveProperty('noteId');
expect(searchAttachments).toHaveProperty('personId');

View File

@@ -1,57 +0,0 @@
import request from 'supertest';
const client = request(`http://localhost:${APP_PORT}`);
describe('searchCommentsResolver (e2e)', () => {
it('should find many searchComments', () => {
const queryData = {
query: `
query searchComments {
searchComments {
edges {
node {
body
id
createdAt
updatedAt
deletedAt
authorId
activityId
}
}
}
}
`,
};
return client
.post('/graphql')
.set('Authorization', `Bearer ${ACCESS_TOKEN}`)
.send(queryData)
.expect(200)
.expect((res) => {
expect(res.body.data).toBeDefined();
expect(res.body.errors).toBeUndefined();
})
.expect((res) => {
const data = res.body.data.searchComments;
expect(data).toBeDefined();
expect(Array.isArray(data.edges)).toBe(true);
const edges = data.edges;
if (edges.length > 0) {
const searchComments = edges[0].node;
expect(searchComments).toHaveProperty('body');
expect(searchComments).toHaveProperty('id');
expect(searchComments).toHaveProperty('createdAt');
expect(searchComments).toHaveProperty('updatedAt');
expect(searchComments).toHaveProperty('deletedAt');
expect(searchComments).toHaveProperty('authorId');
expect(searchComments).toHaveProperty('activityId');
}
});
});
});