diff --git a/server/models/Event.ts b/server/models/Event.ts index 6f1a37322..63a308534 100644 --- a/server/models/Event.ts +++ b/server/models/Event.ts @@ -91,8 +91,10 @@ class Event extends BaseModel { @Column(DataType.UUID) teamId: string; - // Schedule can be used to send events into the event system without recording - // them in the database or audit trail – consider using a task instead. + /* + * Schedule can be used to send events into the event system without recording + * them in the database or audit trail – consider using a task instead. + */ static schedule(event: Partial) { const now = new Date(); globalEventQueue.add( diff --git a/server/queues/tasks/ExportMarkdownZipTask.ts b/server/queues/tasks/ExportMarkdownZipTask.ts index bce34f3ed..288f5c2ef 100644 --- a/server/queues/tasks/ExportMarkdownZipTask.ts +++ b/server/queues/tasks/ExportMarkdownZipTask.ts @@ -6,6 +6,7 @@ import ExportSuccessEmail from "@server/emails/templates/ExportSuccessEmail"; import Logger from "@server/logging/logger"; import { Collection, Event, FileOperation, Team, User } from "@server/models"; import { FileOperationState } from "@server/models/FileOperation"; +import fileOperationPresenter from "@server/presenters/fileOperation"; import { uploadToS3FromBuffer } from "@server/utils/s3"; import { archiveCollections } from "@server/utils/zip"; import BaseTask, { TaskPriority } from "./BaseTask"; @@ -44,21 +45,20 @@ export default class ExportMarkdownZipTask extends BaseTask { try { Logger.info("task", `ExportTask processing data for ${fileOperationId}`); - await this.updateFileOperation( - fileOperation, - FileOperationState.Creating - ); + await this.updateFileOperation(fileOperation, { + state: FileOperationState.Creating, + }); const filePath = await archiveCollections(collections); Logger.info("task", `ExportTask uploading data for ${fileOperationId}`); - await this.updateFileOperation( - fileOperation, - FileOperationState.Uploading - ); + await this.updateFileOperation(fileOperation, { + state: FileOperationState.Uploading, + }); const fileBuffer = await fs.promises.readFile(filePath); + const stat = await fs.promises.stat(filePath); const url = await uploadToS3FromBuffer( fileBuffer, "application/zip", @@ -66,12 +66,11 @@ export default class ExportMarkdownZipTask extends BaseTask { "private" ); - await this.updateFileOperation( - fileOperation, - FileOperationState.Complete, - undefined, - url - ); + await this.updateFileOperation(fileOperation, { + size: stat.size, + state: FileOperationState.Complete, + url, + }); await ExportSuccessEmail.schedule({ to: user.email, @@ -79,11 +78,10 @@ export default class ExportMarkdownZipTask extends BaseTask { teamUrl: team.url, }); } catch (error) { - await this.updateFileOperation( - fileOperation, - FileOperationState.Error, - error - ); + await this.updateFileOperation(fileOperation, { + state: FileOperationState.Error, + error, + }); await ExportFailureEmail.schedule({ to: user.email, teamUrl: team.url, @@ -100,20 +98,21 @@ export default class ExportMarkdownZipTask extends BaseTask { */ private async updateFileOperation( fileOperation: FileOperation, - state: FileOperationState, - error?: Error, - url?: string + options: Partial & { error?: Error } ) { await fileOperation.update({ - state, - url, - error: error ? truncate(error.message, { length: 255 }) : undefined, + ...options, + error: options.error + ? truncate(options.error.message, { length: 255 }) + : undefined, }); + await Event.schedule({ name: "fileOperations.update", modelId: fileOperation.id, teamId: fileOperation.teamId, actorId: fileOperation.userId, + data: fileOperationPresenter(fileOperation), }); } diff --git a/server/types.ts b/server/types.ts index 47fb4f2a7..6f24268e5 100644 --- a/server/types.ts +++ b/server/types.ts @@ -1,5 +1,5 @@ import { Context } from "koa"; -import { User } from "./models"; +import { FileOperation, User } from "./models"; export type ContextWithState = Context & { state: { @@ -112,14 +112,7 @@ export type FileOperationEvent = { teamId: string; actorId: string; modelId: string; - data: { - type: string; - state: string; - id: string; - size: number; - createdAt: string; - collectionId: string; - }; + data: Partial; }; export type CollectionEvent =