7154 deleted event is not emitted when calling destroyone (#7159)
Closes #7154
This commit is contained in:
@ -35,6 +35,7 @@ import {
|
||||
} from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception';
|
||||
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { ObjectRecordCreateEvent } from 'src/engine/core-modules/event-emitter/types/object-record-create.event';
|
||||
import { ObjectRecordDeleteEvent } from 'src/engine/core-modules/event-emitter/types/object-record-delete.event';
|
||||
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
|
||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
|
||||
@ -284,10 +285,94 @@ export class GraphqlQueryRunnerService {
|
||||
async destroyOne<ObjectRecord extends IRecord = IRecord>(
|
||||
args: DestroyOneResolverArgs,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<ObjectRecord> {
|
||||
): Promise<ObjectRecord | undefined> {
|
||||
const graphqlQueryDestroyOneResolverService =
|
||||
new GraphqlQueryDestroyOneResolverService(this.twentyORMGlobalManager);
|
||||
|
||||
return graphqlQueryDestroyOneResolverService.destroyOne(args, options);
|
||||
const { authContext, objectMetadataItem } = options;
|
||||
|
||||
assertMutationNotOnRemoteObject(objectMetadataItem);
|
||||
assertIsValidUuid(args.id);
|
||||
|
||||
const hookedArgs =
|
||||
await this.workspaceQueryHookService.executePreQueryHooks(
|
||||
authContext,
|
||||
objectMetadataItem.nameSingular,
|
||||
'destroyOne',
|
||||
args,
|
||||
);
|
||||
|
||||
const computedArgs = (await this.queryRunnerArgsFactory.create(
|
||||
hookedArgs,
|
||||
options,
|
||||
ResolverArgsType.DestroyOne,
|
||||
)) as DestroyOneResolverArgs;
|
||||
|
||||
const result = (await graphqlQueryDestroyOneResolverService.destroyOne(
|
||||
computedArgs,
|
||||
options,
|
||||
)) as ObjectRecord;
|
||||
|
||||
await this.workspaceQueryHookService.executePostQueryHooks(
|
||||
authContext,
|
||||
objectMetadataItem.nameSingular,
|
||||
'destroyOne',
|
||||
[result],
|
||||
);
|
||||
|
||||
await this.triggerWebhooks<IRecord>(
|
||||
[result],
|
||||
CallWebhookJobsJobOperation.destroy,
|
||||
options,
|
||||
);
|
||||
|
||||
this.emitDestroyEvents<IRecord>([result], authContext, objectMetadataItem);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private emitDestroyEvents<BaseRecord extends IRecord = IRecord>(
|
||||
records: BaseRecord[],
|
||||
authContext: AuthContext,
|
||||
objectMetadataItem: ObjectMetadataInterface,
|
||||
) {
|
||||
this.workspaceEventEmitter.emit(
|
||||
`${objectMetadataItem.nameSingular}.destroyed`,
|
||||
records.map((record) => {
|
||||
return {
|
||||
userId: authContext.user?.id,
|
||||
recordId: record.id,
|
||||
objectMetadata: objectMetadataItem,
|
||||
properties: {
|
||||
before: this.removeNestedProperties(record),
|
||||
},
|
||||
} satisfies ObjectRecordDeleteEvent<any>;
|
||||
}),
|
||||
authContext.workspace.id,
|
||||
);
|
||||
}
|
||||
|
||||
private removeNestedProperties<Record extends IRecord = IRecord>(
|
||||
record: Record,
|
||||
) {
|
||||
if (!record) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sanitizedRecord = {};
|
||||
|
||||
for (const [key, value] of Object.entries(record)) {
|
||||
if (value && typeof value === 'object' && value['edges']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key === '__typename') {
|
||||
continue;
|
||||
}
|
||||
|
||||
sanitizedRecord[key] = value;
|
||||
}
|
||||
|
||||
return sanitizedRecord;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ export enum CallWebhookJobsJobOperation {
|
||||
create = 'create',
|
||||
update = 'update',
|
||||
delete = 'delete',
|
||||
destroy = 'destroy',
|
||||
}
|
||||
|
||||
export type CallWebhookJobsJobData = {
|
||||
|
||||
@ -49,6 +49,13 @@ export class EntityEventsToDbListener {
|
||||
return this.handle(payload);
|
||||
}
|
||||
|
||||
@OnEvent('*.destroyed')
|
||||
async handleDestroy(
|
||||
payload: WorkspaceEventBatch<ObjectRecordUpdateEvent<any>>,
|
||||
) {
|
||||
return this.handle(payload);
|
||||
}
|
||||
|
||||
private async handle(payload: WorkspaceEventBatch<ObjectRecordBaseEvent>) {
|
||||
const filteredEvents = payload.events.filter(
|
||||
(event) => event.objectMetadata?.isAuditLogged,
|
||||
|
||||
@ -4,6 +4,7 @@ import {
|
||||
DeleteManyResolverArgs,
|
||||
DeleteOneResolverArgs,
|
||||
DestroyManyResolverArgs,
|
||||
DestroyOneResolverArgs,
|
||||
FindDuplicatesResolverArgs,
|
||||
FindManyResolverArgs,
|
||||
FindOneResolverArgs,
|
||||
@ -39,4 +40,6 @@ export type WorkspacePreQueryHookPayload<T> = T extends 'createMany'
|
||||
? RestoreManyResolverArgs
|
||||
: T extends 'destroyMany'
|
||||
? DestroyManyResolverArgs
|
||||
: never;
|
||||
: T extends 'destroyOne'
|
||||
? DestroyOneResolverArgs
|
||||
: never;
|
||||
|
||||
@ -22,6 +22,7 @@ export enum ResolverArgsType {
|
||||
DeleteMany = 'DeleteMany',
|
||||
RestoreMany = 'RestoreMany',
|
||||
DestroyMany = 'DestroyMany',
|
||||
DestroyOne = 'DestroyOne',
|
||||
}
|
||||
|
||||
export interface FindManyResolverArgs<
|
||||
|
||||
Reference in New Issue
Block a user