feat(history): add ProfileHistory creation with job execution results

TriggeringProfileJobCommand:
- Add RecActionResult property to store ReC action execution results
- Convert handler to primary constructor with ISender injection
- Create ProfileHistory after successful job execution
- Include detailed execution metrics in history (TotalActionCount, ActionExceptionCount, BatchId)
- Add required using statements for ProfileHistories and ValueObjects

ProfileWorkerOptionsValidator:
- Fix XML documentation reference to ValidateOptionsResult.Fail(string)
This commit is contained in:
2026-08-04 16:34:30 +02:00
parent 5b67035a07
commit dd9e6a710b
2 changed files with 22 additions and 5 deletions

View File

@@ -1,5 +1,9 @@
using ECMJobRunner.Domain.Entities; using ECMJobRunner.Application.ProfileHistories.Commands;
using ECMJobRunner.Domain.Entities;
using ECMJobRunner.Domain.Interfaces;
using ECMJobRunner.Domain.ValueObjects;
using MediatR; using MediatR;
using ReC.Client.Api;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -23,6 +27,8 @@ namespace ECMJobRunner.Application.Profiles.Commands
/// Unique batch identifier for this execution /// Unique batch identifier for this execution
/// </summary> /// </summary>
public string BatchId { get; set; } = null!; public string BatchId { get; set; } = null!;
internal BatchRecActionViewResponse? RecActionResult { get; set; }
} }
/// <summary> /// <summary>
@@ -30,7 +36,7 @@ namespace ECMJobRunner.Application.Profiles.Commands
/// All execution logic is delegated to pipeline behaviors /// All execution logic is delegated to pipeline behaviors
/// This handler simply returns completion after behaviors execute /// This handler simply returns completion after behaviors execute
/// </summary> /// </summary>
public class TriggeringDEXJobCommandHandler : IRequestHandler<TriggeringProfileJobCommand, Unit> public class TriggeringDEXJobCommandHandler(ISender Sender) : IRequestHandler<TriggeringProfileJobCommand, Unit>
{ {
/// <summary> /// <summary>
/// Handles the TriggeringDEXJobCommand /// Handles the TriggeringDEXJobCommand
@@ -39,13 +45,24 @@ namespace ECMJobRunner.Application.Profiles.Commands
/// <param name="request">The command containing job and batch ID</param> /// <param name="request">The command containing job and batch ID</param>
/// <param name="cancellationToken">Cancellation token</param> /// <param name="cancellationToken">Cancellation token</param>
/// <returns>Unit value indicating completion</returns> /// <returns>Unit value indicating completion</returns>
public Task<Unit> Handle(TriggeringProfileJobCommand request, CancellationToken cancellationToken) public async Task<Unit> Handle(TriggeringProfileJobCommand request, CancellationToken cancellationToken)
{ {
// All execution logic is handled by pipeline behaviors: // All execution logic is handled by pipeline behaviors:
// - MainQueryExecutionBehavior // - MainQueryExecutionBehavior
// - CheckQueryExecutionBehavior // - CheckQueryExecutionBehavior
// - ReCRequestExecutionBehavior // - ReCRequestExecutionBehavior
return Task.FromResult(Unit.Value);
var cmd = new CreateProfileHistoryCommand
{
Result = ResultType.Ok,
ResultText = $"Job '{request.Job.Name}' erfolgreich abgeschlossen. | Batch-ID: {request.BatchId} | Verarbeitete Aktionen: {request.RecActionResult?.TotalActionCount ?? 0} | Fehlgeschlagene Aktionen: {request.RecActionResult?.ActionExceptionCount ?? 0}",
ProfileId = request.Job.ProfileId,
AddedWho = "ECMJobRunner"
};
await Sender.Send(cmd, cancellationToken);
return Unit.Value;
} }
} }
} }

View File

@@ -55,7 +55,7 @@ internal class ProfileWorkerOptionsValidator : IValidateOptions<ProfileWorkerOpt
/// <param name="options">The options to validate.</param> /// <param name="options">The options to validate.</param>
/// <returns> /// <returns>
/// <see cref="ValidateOptionsResult.Success"/> if valid, /// <see cref="ValidateOptionsResult.Success"/> if valid,
/// or <see cref="ValidateOptionsResult.Fail"/> with error message if invalid. /// or <see cref="ValidateOptionsResult.Fail(string)"/> with error message if invalid.
/// </returns> /// </returns>
/// <remarks> /// <remarks>
/// Validation rules: /// Validation rules: