Refactor DEXJob to ProfileJob across the codebase

Renamed namespaces, classes, and commands from `DEXJob` to `ProfileJob` to align with the new "Profiles" context. Updated pipeline behaviors (`CheckQueryExecutionBehavior`, `MainQueryExecutionBehavior`, `ReCRequestExecutionBehavior`) to handle `TriggeringProfileJobCommand`.

Refactored unit tests to reflect the new naming convention, including mock setups and assertions. Updated `DtoExtensions` to return `TriggeringProfileJobBatchCommand`. Adjusted queries and dependency injection to use the new `Profiles` namespace.

Performed general refactoring to replace all references to "DEXJob" with "ProfileJob" in method names, variables, and documentation for consistency and clarity.
This commit is contained in:
2026-08-03 11:36:45 +02:00
parent a698f8daae
commit 1110728741
12 changed files with 56 additions and 56 deletions

View File

@@ -1,4 +1,4 @@
using ECMJobRunner.Application.DEXJob.Commands.Behaviors;
using ECMJobRunner.Application.Profiles.Commands.Behaviors;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ReC.Client;

View File

@@ -3,7 +3,7 @@ using ECMJobRunner.Application.Common.Dtos;
using ECMJobRunner.Application.Common.Exceptions;
using ECMJobRunner.Application.Common.Interfaces;
using ECMJobRunner.Application.Common.Options;
using ECMJobRunner.Application.DEXJob.Commands;
using ECMJobRunner.Application.Profiles.Commands;
using MediatR;
using Microsoft.Extensions.Options;
using System;
@@ -11,7 +11,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace ECMJobRunner.Application.DEXJob.Commands.Behaviors
namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
{
/// <summary>
/// Pipeline behavior that executes the check SQL query for DEX jobs
@@ -46,7 +46,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands.Behaviors
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
#endif
{
if (request is TriggeringDEXJobCommand command)
if (request is TriggeringProfileJobCommand command)
{
await ExecuteCheckQueryAsync(command, cancellationToken);
}
@@ -54,7 +54,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands.Behaviors
return await next();
}
private async Task ExecuteCheckQueryAsync(TriggeringDEXJobCommand command, CancellationToken cancel)
private async Task ExecuteCheckQueryAsync(TriggeringProfileJobCommand command, CancellationToken cancel)
{
if (!string.IsNullOrWhiteSpace(command.Job.SqlCheckQuery))
{

View File

@@ -3,7 +3,7 @@ using ECMJobRunner.Application.Common.Dtos;
using ECMJobRunner.Application.Common.Exceptions;
using ECMJobRunner.Application.Common.Interfaces;
using ECMJobRunner.Application.Common.Options;
using ECMJobRunner.Application.DEXJob.Commands;
using ECMJobRunner.Application.Profiles.Commands;
using MediatR;
using Microsoft.Extensions.Options;
using System;
@@ -11,7 +11,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace ECMJobRunner.Application.DEXJob.Commands.Behaviors
namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
{
/// <summary>
/// Pipeline behavior that executes the main SQL query for DEX jobs
@@ -46,7 +46,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands.Behaviors
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
#endif
{
if (request is TriggeringDEXJobCommand command)
if (request is TriggeringProfileJobCommand command)
{
await ExecuteMainQueryAsync(command, cancellationToken);
}
@@ -54,7 +54,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands.Behaviors
return await next();
}
private async Task ExecuteMainQueryAsync(TriggeringDEXJobCommand command, CancellationToken cancel)
private async Task ExecuteMainQueryAsync(TriggeringProfileJobCommand command, CancellationToken cancel)
{
if (!string.IsNullOrWhiteSpace(command.Job.SqlMainQuery))
{

View File

@@ -1,7 +1,7 @@
using ECMJobRunner.Application.Common.Constants;
using ECMJobRunner.Application.Common.Exceptions;
using ECMJobRunner.Application.Common.Options;
using ECMJobRunner.Application.DEXJob.Commands;
using ECMJobRunner.Application.Profiles.Commands;
using MediatR;
using Microsoft.Extensions.Options;
using ReC.Client;
@@ -10,7 +10,7 @@ using System;
using System.Threading;
using System.Threading.Tasks;
namespace ECMJobRunner.Application.DEXJob.Commands.Behaviors
namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
{
/// <summary>
/// Pipeline behavior that sends ReC HTTP request for DEX jobs
@@ -45,7 +45,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands.Behaviors
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
#endif
{
if (request is TriggeringDEXJobCommand command)
if (request is TriggeringProfileJobCommand command)
{
await SendReCRequestAsync(command, cancellationToken);
}
@@ -53,7 +53,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands.Behaviors
return await next();
}
private async Task SendReCRequestAsync(TriggeringDEXJobCommand command, CancellationToken cancel)
private async Task SendReCRequestAsync(TriggeringProfileJobCommand command, CancellationToken cancel)
{
try
{

View File

@@ -6,13 +6,13 @@ using System;
using System.Threading;
using System.Threading.Tasks;
namespace ECMJobRunner.Application.DEXJob.Commands
namespace ECMJobRunner.Application.Profiles.Commands
{
/// <summary>
/// Command to trigger DEX job batch for a profile
/// Executes all SQL jobs associated with a profile ID
/// </summary>
public class TriggeringDEXJobBatchCommand : IRequest<Unit>
public class TriggeringProfileJobBatchCommand : IRequest<Unit>
{
/// <summary>
/// Profile ID to trigger all associated SQL jobs
@@ -26,7 +26,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands
/// Validates that the profile is active before execution
/// </summary>
public class TriggeringDEXJobBatchCommandHandler(ICfgProfileRepository profileRepo, IProfileSqlJobRepository jobRepo, ISender sender)
: IRequestHandler<TriggeringDEXJobBatchCommand, Unit>
: IRequestHandler<TriggeringProfileJobBatchCommand, Unit>
{
/// <summary>
/// Handles the TriggeringDEXJobBatchCommand
@@ -36,7 +36,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Unit value indicating completion</returns>
/// <exception cref="InactiveProfileException">Thrown when the profile is not active</exception>
public async Task<Unit> Handle(TriggeringDEXJobBatchCommand request, CancellationToken cancellationToken)
public async Task<Unit> Handle(TriggeringProfileJobBatchCommand request, CancellationToken cancellationToken)
{
var batchId = CreateBatchId();
@@ -59,7 +59,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands
foreach (var job in jobs)
{
await sender.Send(new TriggeringDEXJobCommand
await sender.Send(new TriggeringProfileJobCommand
{
Job = job,
BatchId = batchId

View File

@@ -3,7 +3,7 @@ using MediatR;
using System.Threading;
using System.Threading.Tasks;
namespace ECMJobRunner.Application.DEXJob.Commands
namespace ECMJobRunner.Application.Profiles.Commands
{
/// <summary>
/// Command to trigger a single DEX job execution
@@ -12,7 +12,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands
/// 2. CheckQueryExecutionBehavior - validates with check SQL query
/// 3. ReCRequestExecutionBehavior - invokes ReC HTTP request
/// </summary>
public class TriggeringDEXJobCommand : IRequest<Unit>
public class TriggeringProfileJobCommand : IRequest<Unit>
{
/// <summary>
/// The SQL job to execute
@@ -30,7 +30,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands
/// All execution logic is delegated to pipeline behaviors
/// This handler simply returns completion after behaviors execute
/// </summary>
public class TriggeringDEXJobCommandHandler : IRequestHandler<TriggeringDEXJobCommand, Unit>
public class TriggeringDEXJobCommandHandler : IRequestHandler<TriggeringProfileJobCommand, Unit>
{
/// <summary>
/// Handles the TriggeringDEXJobCommand
@@ -39,7 +39,7 @@ namespace ECMJobRunner.Application.DEXJob.Commands
/// <param name="request">The command containing job and batch ID</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Unit value indicating completion</returns>
public Task<Unit> Handle(TriggeringDEXJobCommand request, CancellationToken cancellationToken)
public Task<Unit> Handle(TriggeringProfileJobCommand request, CancellationToken cancellationToken)
{
// All execution logic is handled by pipeline behaviors:
// - MainQueryExecutionBehavior

View File

@@ -7,7 +7,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ECMJobRunner.Application.DEXJob.Queries
namespace ECMJobRunner.Application.Profiles.Queries
{
/// <summary>
/// Query to retrieve profiles with flexible filtering options

View File

@@ -21,7 +21,7 @@ namespace ECMJobRunner.Tests.Application
{
private readonly Mock<ISQLExecutor> _mockExecutor;
private readonly Mock<IOptions<DexJobOptions>> _mockOptions;
private readonly CheckQueryExecutionBehavior<TriggeringDEXJobCommand, Unit> _behavior;
private readonly CheckQueryExecutionBehavior<TriggeringProfileJobCommand, Unit> _behavior;
private readonly Mock<RequestHandlerDelegate<Unit>> _mockNext;
public CheckQueryExecutionBehaviorTests()
@@ -29,7 +29,7 @@ namespace ECMJobRunner.Tests.Application
_mockExecutor = new Mock<ISQLExecutor>();
_mockOptions = new Mock<IOptions<DexJobOptions>>();
_mockOptions.Setup(o => o.Value).Returns(new DexJobOptions());
_behavior = new CheckQueryExecutionBehavior<TriggeringDEXJobCommand, Unit>(_mockExecutor.Object, _mockOptions.Object);
_behavior = new CheckQueryExecutionBehavior<TriggeringProfileJobCommand, Unit>(_mockExecutor.Object, _mockOptions.Object);
_mockNext = new Mock<RequestHandlerDelegate<Unit>>();
_mockNext.Setup(n => n()).ReturnsAsync(Unit.Value);
}
@@ -38,7 +38,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithValidCheckQuery_ExecutesSuccessfully()
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlCheckQuery = "SELECT COUNT(*) AS [Return Value] FROM Table" },
BatchId = "20260711143025123456"
@@ -68,7 +68,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithPositiveReturnValue_DoesNotThrow(int returnValue)
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlCheckQuery = "SELECT COUNT(*) AS [Return Value] FROM Table" },
BatchId = "20260711143025123456"
@@ -96,7 +96,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithZeroOrNegativeReturnValue_ThrowsDEXJobException(int returnValue)
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlCheckQuery = "SELECT COUNT(*) AS [Return Value] FROM Table" },
BatchId = "20260711143025123456"
@@ -122,7 +122,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithNullCheckQuery_IgnoresByDefault()
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlCheckQuery = null },
BatchId = "20260711143025123456"
@@ -157,8 +157,8 @@ namespace ECMJobRunner.Tests.Application
};
_mockOptions.Setup(o => o.Value).Returns(options);
var behavior = new CheckQueryExecutionBehavior<TriggeringDEXJobCommand, Unit>(_mockExecutor.Object, _mockOptions.Object);
var command = new TriggeringDEXJobCommand
var behavior = new CheckQueryExecutionBehavior<TriggeringProfileJobCommand, Unit>(_mockExecutor.Object, _mockOptions.Object);
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlCheckQuery = null },
BatchId = "20260711143025123456"
@@ -181,7 +181,7 @@ namespace ECMJobRunner.Tests.Application
{
// Arrange
var batchId = "20260711143025123456";
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlCheckQuery = "SELECT COUNT(*) AS [Return Value] FROM Table WHERE BatchId = '#INT#BATCH_ID'" },
BatchId = batchId
@@ -209,7 +209,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithNullResult_ThrowsDEXJobException()
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlCheckQuery = "SELECT COUNT(*) AS [Return Value] FROM Table" },
BatchId = "20260711143025123456"

View File

@@ -21,7 +21,7 @@ namespace ECMJobRunner.Tests.Application
{
private readonly Mock<ISQLExecutor> _mockExecutor;
private readonly Mock<IOptions<DexJobOptions>> _mockOptions;
private readonly MainQueryExecutionBehavior<TriggeringDEXJobCommand, Unit> _behavior;
private readonly MainQueryExecutionBehavior<TriggeringProfileJobCommand, Unit> _behavior;
private readonly Mock<RequestHandlerDelegate<Unit>> _mockNext;
public MainQueryExecutionBehaviorTests()
@@ -29,7 +29,7 @@ namespace ECMJobRunner.Tests.Application
_mockExecutor = new Mock<ISQLExecutor>();
_mockOptions = new Mock<IOptions<DexJobOptions>>();
_mockOptions.Setup(o => o.Value).Returns(new DexJobOptions());
_behavior = new MainQueryExecutionBehavior<TriggeringDEXJobCommand, Unit>(_mockExecutor.Object, _mockOptions.Object);
_behavior = new MainQueryExecutionBehavior<TriggeringProfileJobCommand, Unit>(_mockExecutor.Object, _mockOptions.Object);
_mockNext = new Mock<RequestHandlerDelegate<Unit>>();
_mockNext.Setup(n => n()).ReturnsAsync(Unit.Value);
}
@@ -38,7 +38,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithValidMainQuery_ExecutesSuccessfully()
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlMainQuery = "INSERT INTO Table VALUES (1)" },
BatchId = "20260711143025123456"
@@ -65,7 +65,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithNullReturnValue_DoesNotThrow()
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlMainQuery = "INSERT INTO Table VALUES (1)" },
BatchId = "20260711143025123456"
@@ -90,7 +90,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithNonNullReturnValue_ThrowsDEXJobException()
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlMainQuery = "INSERT INTO Table VALUES (1)" },
BatchId = "20260711143025123456"
@@ -116,7 +116,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithNullMainQuery_IgnoresByDefault()
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlMainQuery = null },
BatchId = "20260711143025123456"
@@ -151,8 +151,8 @@ namespace ECMJobRunner.Tests.Application
};
_mockOptions.Setup(o => o.Value).Returns(options);
var behavior = new MainQueryExecutionBehavior<TriggeringDEXJobCommand, Unit>(_mockExecutor.Object, _mockOptions.Object);
var command = new TriggeringDEXJobCommand
var behavior = new MainQueryExecutionBehavior<TriggeringProfileJobCommand, Unit>(_mockExecutor.Object, _mockOptions.Object);
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlMainQuery = null },
BatchId = "20260711143025123456"
@@ -175,7 +175,7 @@ namespace ECMJobRunner.Tests.Application
{
// Arrange
var batchId = "20260711143025123456";
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlMainQuery = "INSERT INTO Table (BatchId) VALUES ('#INT#BATCH_ID')" },
BatchId = batchId
@@ -203,7 +203,7 @@ namespace ECMJobRunner.Tests.Application
public async Task Handle_WithExecutionError_ThrowsDEXJobException()
{
// Arrange
var command = new TriggeringDEXJobCommand
var command = new TriggeringProfileJobCommand
{
Job = new ProfileSqlJob { SqlMainQuery = "INVALID SQL" },
BatchId = "20260711143025123456"

View File

@@ -46,7 +46,7 @@ namespace ECMJobRunner.Tests.Application
.Setup(r => r.FindAsync(It.IsAny<Expression<Func<ProfileSqlJob, bool>>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(jobs);
var command = new TriggeringDEXJobBatchCommand { ProfileId = profileId };
var command = new TriggeringProfileJobBatchCommand { ProfileId = profileId };
// Act
var result = await _handler.Handle(command, CancellationToken.None);
@@ -54,7 +54,7 @@ namespace ECMJobRunner.Tests.Application
// Assert
result.Should().Be(Unit.Value);
_mockSender.Verify(
s => s.Send(It.IsAny<TriggeringDEXJobCommand>(), It.IsAny<CancellationToken>()),
s => s.Send(It.IsAny<TriggeringProfileJobCommand>(), It.IsAny<CancellationToken>()),
Times.Exactly(2),
"Should send command for each job");
}
@@ -68,7 +68,7 @@ namespace ECMJobRunner.Tests.Application
.Setup(r => r.FindAsync(It.IsAny<Expression<Func<ProfileSqlJob, bool>>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(Array.Empty<ProfileSqlJob>());
var command = new TriggeringDEXJobBatchCommand { ProfileId = profileId };
var command = new TriggeringProfileJobBatchCommand { ProfileId = profileId };
// Act
var result = await _handler.Handle(command, CancellationToken.None);
@@ -76,7 +76,7 @@ namespace ECMJobRunner.Tests.Application
// Assert
result.Should().Be(Unit.Value);
_mockSender.Verify(
s => s.Send(It.IsAny<TriggeringDEXJobCommand>(), It.IsAny<CancellationToken>()),
s => s.Send(It.IsAny<TriggeringProfileJobCommand>(), It.IsAny<CancellationToken>()),
Times.Never,
"Should not send any commands when no jobs found");
}
@@ -115,13 +115,13 @@ namespace ECMJobRunner.Tests.Application
.Setup(r => r.FindAsync(It.IsAny<Expression<Func<ProfileSqlJob, bool>>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new[] { job });
TriggeringDEXJobCommand? capturedCommand = null;
TriggeringProfileJobCommand? capturedCommand = null;
_mockSender
.Setup(s => s.Send(It.IsAny<TriggeringDEXJobCommand>(), It.IsAny<CancellationToken>()))
.Callback<IRequest<Unit>, CancellationToken>((cmd, _) => capturedCommand = cmd as TriggeringDEXJobCommand)
.Setup(s => s.Send(It.IsAny<TriggeringProfileJobCommand>(), It.IsAny<CancellationToken>()))
.Callback<IRequest<Unit>, CancellationToken>((cmd, _) => capturedCommand = cmd as TriggeringProfileJobCommand)
.ReturnsAsync(Unit.Value);
var command = new TriggeringDEXJobBatchCommand { ProfileId = profileId };
var command = new TriggeringProfileJobBatchCommand { ProfileId = profileId };
// Act
await _handler.Handle(command, CancellationToken.None);

View File

@@ -1,5 +1,5 @@
using ECMJobRunner.Application.Common.Dtos;
using ECMJobRunner.Application.DEXJob.Commands;
using ECMJobRunner.Application.Profiles.Commands;
using MediatR;
namespace ECMJobRunner.WebCron.Extensions;
@@ -27,10 +27,10 @@ public static class DtoExtensions
/// Converts a profile DTO to a DEX job batch command.
/// </summary>
/// <param name="profile">The profile configuration DTO.</param>
/// <returns>A <see cref="TriggeringDEXJobBatchCommand"/> ready to execute the profile job.</returns>
public static TriggeringDEXJobBatchCommand ToJob(this CfgProfileDto profile)
/// <returns>A <see cref="TriggeringProfileJobBatchCommand"/> ready to execute the profile job.</returns>
public static TriggeringProfileJobBatchCommand ToJob(this CfgProfileDto profile)
{
return new TriggeringDEXJobBatchCommand
return new TriggeringProfileJobBatchCommand
{
ProfileId = profile.Id,
};

View File

@@ -1,4 +1,4 @@
using ECMJobRunner.Application.DEXJob.Queries;
using ECMJobRunner.Application.Profiles.Queries;
using ECMJobRunner.WebCron.Extensions;
using Hangfire;
using MediatR;