From c38979cc191e26909e0c6e128d3bd16ea39829f3 Mon Sep 17 00:00:00 2001 From: alexeh Date: Thu, 19 Dec 2024 06:56:43 +0100 Subject: [PATCH] sourcing-data events and view --- api/src/modules/api-events/api-event.entity.ts | 6 +++--- api/src/modules/api-events/api-events.module.ts | 2 ++ .../sourcing-data-import-view.entity.ts | 11 +++++++++++ .../import-data.event-handler.ts | 17 +++++++++-------- .../import-data/workers/import-data.consumer.ts | 6 +++++- 5 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 api/src/modules/api-events/sourcing-data-import-view.entity.ts diff --git a/api/src/modules/api-events/api-event.entity.ts b/api/src/modules/api-events/api-event.entity.ts index 09da386e4..3d9ae9d2f 100644 --- a/api/src/modules/api-events/api-event.entity.ts +++ b/api/src/modules/api-events/api-event.entity.ts @@ -24,9 +24,9 @@ export enum API_EVENT_KINDS { user__passwordResetTokenGenerated__v1alpha1 = 'user.passwordResetTokenGenerated/v1alpha1', user__passwordResetSucceeded__v1alpha1 = 'user.passwordResetSucceeded/v1alpha1', user__passwordResetFailed__v1alpha1 = 'user.passwordResetFailed/v1alpha1', - data__importStarted__v1alpha1 = 'data.importStarted/v1alpha1', - data__importFailed__v1alpha1 = 'data.importFailed/v1alpha1', - data__importSucceeded__v1alpha1 = 'data.importSucceeded/v1alpha1', + sourcing_data__importStarted__v1alpha1 = 'sourcing-data.importStarted/v1alpha1', + sourcing_data__importFailed__v1alpha1 = 'sourcing-data.importFailed/v1alpha1', + sourcing_data__importSucceeded__v1alpha1 = 'sourcing-data.importSucceeded/v1alpha1', } /** diff --git a/api/src/modules/api-events/api-events.module.ts b/api/src/modules/api-events/api-events.module.ts index 95222b92c..f2402d2b9 100644 --- a/api/src/modules/api-events/api-events.module.ts +++ b/api/src/modules/api-events/api-events.module.ts @@ -8,6 +8,7 @@ import { } from 'modules/api-events/api-event.topic+kind.entity'; import { ApiEventsController } from 'modules/api-events/api-events.controller'; import { ApiEventsService } from 'modules/api-events/api-events.service'; +import { SourcingDataImportViewEntity } from './sourcing-data-import-view.entity'; export const logger: Logger = new Logger('ApiEvents'); @@ -18,6 +19,7 @@ export const logger: Logger = new Logger('ApiEvents'); ApiEvent, LatestApiEventByTopicAndKind, FirstApiEventByTopicAndKind, + SourcingDataImportViewEntity, ]), ], providers: [ApiEventsService], diff --git a/api/src/modules/api-events/sourcing-data-import-view.entity.ts b/api/src/modules/api-events/sourcing-data-import-view.entity.ts new file mode 100644 index 000000000..944cb2f87 --- /dev/null +++ b/api/src/modules/api-events/sourcing-data-import-view.entity.ts @@ -0,0 +1,11 @@ +import { ViewEntity } from 'typeorm'; +import { ApiEventByTopicAndKind } from './api-event.topic+kind.entity'; + +@ViewEntity({ + name: 'sourcing_data_import_view', + expression: `SELECT topic, timestamp, kind, data + FROM api_events + WHERE kind::TEXT LIKE '%sourcing-data%' + ORDER BY topic, kind, timestamp DESC;`, +}) +export class SourcingDataImportViewEntity extends ApiEventByTopicAndKind {} diff --git a/api/src/modules/events/import-data-events/import-data.event-handler.ts b/api/src/modules/events/import-data-events/import-data.event-handler.ts index 7781140e5..55bbb18e2 100644 --- a/api/src/modules/events/import-data-events/import-data.event-handler.ts +++ b/api/src/modules/events/import-data-events/import-data.event-handler.ts @@ -1,19 +1,19 @@ import { EventsHandler, IEvent, IEventHandler } from '@nestjs/cqrs'; -import { API_EVENT_KINDS } from 'modules/api-events/api-event.entity'; +import { API_EVENT_KINDS, ApiEvent } from 'modules/api-events/api-event.entity'; import { ApiEventsService } from 'modules/api-events/api-events.service'; import { Task } from 'modules/tasks/task.entity'; export enum IMPORT_DATA_EVENTS { - STARTED = API_EVENT_KINDS.data__importStarted__v1alpha1, - FAILED = API_EVENT_KINDS.data__importFailed__v1alpha1, - SUCCEED = API_EVENT_KINDS.data__importSucceeded__v1alpha1, + STARTED = API_EVENT_KINDS.sourcing_data__importStarted__v1alpha1, + FAILED = API_EVENT_KINDS.sourcing_data__importFailed__v1alpha1, + SUCCEED = API_EVENT_KINDS.sourcing_data__importSucceeded__v1alpha1, } export class ImportDataEvent implements IEvent { constructor( public readonly taskId: Task['id'], public readonly kind: IMPORT_DATA_EVENTS, - public readonly payload: any, + public readonly data: any, ) {} } @@ -22,10 +22,11 @@ export class ImportDataEventHandler implements IEventHandler { constructor(private readonly apiEvents: ApiEventsService) {} async handle(event: ImportDataEvent): Promise { + const { taskId, kind, data } = event; await this.apiEvents.create({ - topic: event.taskId, - kind: event.kind as unknown as API_EVENT_KINDS, - data: event.payload, + topic: taskId, + kind: kind as unknown as API_EVENT_KINDS, + data: data, }); } } diff --git a/api/src/modules/import-data/workers/import-data.consumer.ts b/api/src/modules/import-data/workers/import-data.consumer.ts index 8df217105..313e4e386 100644 --- a/api/src/modules/import-data/workers/import-data.consumer.ts +++ b/api/src/modules/import-data/workers/import-data.consumer.ts @@ -54,7 +54,9 @@ export class ImportDataConsumer { }); this.importSocket.emitImportFailureToSocket({ error: err }); this.eventBus.publish( - new ImportDataEvent(task.id, IMPORT_DATA_EVENTS.FAILED, err), + new ImportDataEvent(task.id, IMPORT_DATA_EVENTS.FAILED, { + error: { message: err.message, stack: err.stack }, + }), ); this.logger.error( @@ -62,6 +64,8 @@ export class ImportDataConsumer { ); // TODO: If the error is not related to the file, we should not send an error report (as it will be empty), we should send a generic error message + // Since we are registering api events for the import now, it might be useful to include the id of the event so that the client + // can share it with the support team const errorReport: string = await this.tasksService.getTaskErrorReport( task.id,