diff --git a/mobile/openapi/lib/model/workflow_log_entry_dto.dart b/mobile/openapi/lib/model/workflow_log_entry_dto.dart index 2f0d6a9a41..7b0a61aa05 100644 --- a/mobile/openapi/lib/model/workflow_log_entry_dto.dart +++ b/mobile/openapi/lib/model/workflow_log_entry_dto.dart @@ -14,6 +14,7 @@ class WorkflowLogEntryDto { /// Returns a new [WorkflowLogEntryDto] instance. WorkflowLogEntryDto({ required this.at, + required this.id, this.lastStep = const Optional.absent(), required this.result, this.triggerDataId = const Optional.absent(), @@ -22,6 +23,9 @@ class WorkflowLogEntryDto { /// Workflow run date/time String at; + /// Workflow log entry ID + String id; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -44,6 +48,7 @@ class WorkflowLogEntryDto { @override bool operator ==(Object other) => identical(this, other) || other is WorkflowLogEntryDto && other.at == at && + other.id == id && other.lastStep == lastStep && other.result == result && other.triggerDataId == triggerDataId; @@ -52,16 +57,18 @@ class WorkflowLogEntryDto { int get hashCode => // ignore: unnecessary_parenthesis (at.hashCode) + + (id.hashCode) + (lastStep == null ? 0 : lastStep!.hashCode) + (result.hashCode) + (triggerDataId == null ? 0 : triggerDataId!.hashCode); @override - String toString() => 'WorkflowLogEntryDto[at=$at, lastStep=$lastStep, result=$result, triggerDataId=$triggerDataId]'; + String toString() => 'WorkflowLogEntryDto[at=$at, id=$id, lastStep=$lastStep, result=$result, triggerDataId=$triggerDataId]'; Map toJson() { final json = {}; json[r'at'] = this.at; + json[r'id'] = this.id; if (this.lastStep.isPresent) { final value = this.lastStep.value; json[r'lastStep'] = value; @@ -84,6 +91,7 @@ class WorkflowLogEntryDto { return WorkflowLogEntryDto( at: mapValueOfType(json, r'at')!, + id: mapValueOfType(json, r'id')!, lastStep: json.containsKey(r'lastStep') ? Optional.present(WorkflowLogEntryDtoLastStep.fromJson(json[r'lastStep'])) : const Optional.absent(), result: WorkflowResult.fromJson(json[r'result'])!, triggerDataId: json.containsKey(r'triggerDataId') ? Optional.present(mapValueOfType(json, r'triggerDataId')) : const Optional.absent(), @@ -135,6 +143,7 @@ class WorkflowLogEntryDto { /// The list of required keys that must be present in a JSON. static const requiredKeys = { 'at', + 'id', 'result', }; } diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index c52e43e998..74c8b446de 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -27985,6 +27985,12 @@ "description": "Workflow run date/time", "type": "string" }, + "id": { + "description": "Workflow log entry ID", + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$", + "type": "string" + }, "lastStep": { "description": "Last step ran, if the workflow ended early", "properties": { @@ -28018,6 +28024,7 @@ }, "required": [ "at", + "id", "result" ], "type": "object" diff --git a/packages/sdk/src/fetch-client.ts b/packages/sdk/src/fetch-client.ts index afc2675723..b82abff685 100644 --- a/packages/sdk/src/fetch-client.ts +++ b/packages/sdk/src/fetch-client.ts @@ -2837,6 +2837,8 @@ export type WorkflowUpdateDto = { export type WorkflowLogEntryDto = { /** Workflow run date/time */ at: string; + /** Workflow log entry ID */ + id: string; /** Last step ran, if the workflow ended early */ lastStep?: { /** Index of the step in the workflow */ diff --git a/server/src/dtos/workflow.dto.ts b/server/src/dtos/workflow.dto.ts index 56c9818500..98edf71d11 100644 --- a/server/src/dtos/workflow.dto.ts +++ b/server/src/dtos/workflow.dto.ts @@ -85,6 +85,7 @@ const WorkflowShareResponseSchema = z const WorkflowLogEntrySchema = z .object({ + id: z.uuidv4().describe('Workflow log entry ID'), at: z.string().describe('Workflow run date/time'), result: WorkflowResultSchema.describe('Workflow run result'), triggerDataId: z.uuid().optional().describe('Workflow trigger data ID'), diff --git a/server/src/repositories/workflow.repository.ts b/server/src/repositories/workflow.repository.ts index 513209a320..031cf9fe13 100644 --- a/server/src/repositories/workflow.repository.ts +++ b/server/src/repositories/workflow.repository.ts @@ -115,6 +115,7 @@ export class WorkflowRepository { return this.db .selectFrom('workflow_log') .select([ + 'workflow_log.id', 'workflow_log.createdAt', 'workflow_log.halted', 'workflow_log.error', diff --git a/server/src/services/workflow.service.ts b/server/src/services/workflow.service.ts index 28c6d673ec..0e72e540e2 100644 --- a/server/src/services/workflow.service.ts +++ b/server/src/services/workflow.service.ts @@ -88,6 +88,7 @@ export class WorkflowService extends BaseService { await this.requireAccess({ auth, permission: Permission.WorkflowLogs, ids: [id] }); const logs = await this.workflowRepository.getLogs(id, dto); return logs.map((entry) => ({ + id: entry.id, at: entry.createdAt.toISOString(), result: entry.error ? WorkflowResult.Error : entry.halted ? WorkflowResult.Halted : WorkflowResult.Completed, triggerDataId: entry.triggerDataId ?? undefined, diff --git a/web/src/lib/modals/WorkflowLogsModal.svelte b/web/src/lib/modals/WorkflowLogsModal.svelte index 24428722a5..a01afefcbf 100644 --- a/web/src/lib/modals/WorkflowLogsModal.svelte +++ b/web/src/lib/modals/WorkflowLogsModal.svelte @@ -98,7 +98,7 @@ {$t('result')} - {#each entries as entry} + {#each entries as entry (entry.id)}