43 Commits

Author SHA1 Message Date
302fee4908 Refactor tests to send commands directly to mediator
Refactored test code to remove ToObjectProcedure usage and send command objects directly to the mediator. Updated update procedure tests to use Data and Id properties. Replaced custom Execute*Procedure methods with sender.Send. Cleaned up unused usings. These changes improve consistency and reflect updates to command structures.
2026-03-24 11:29:15 +01:00
3e10176d98 Add PreprocessingBehavior for action command pipeline
Introduced PreprocessingBehavior implementing MediatR's IPipelineBehavior for InvokeRecActionViewCommand. This behavior executes a preprocessing SQL query if specified, and halts processing if an error occurs and ErrorAction is set to Stop. Added necessary using directives for dependencies.
2026-03-24 11:14:11 +01:00
4f0f99e0f8 Refactor InsertResultProcedure execution method
Replaced sender.ExecuteInsertProcedure with sender.Send for executing InsertResultProcedure. Removed the _options.AddedWho parameter, passing only the procedure object and cancellation token. The construction of InsertResultProcedure remains unchanged.
2026-03-24 11:11:36 +01:00
8fb4b4005c Refactor UpdateObjectProcedure to use DTO properties
Replaced *Procedure properties in UpdateObjectProcedure with corresponding DTO types (e.g., UpdateActionDto, UpdateEndpointDto, etc.) and added the necessary DTO namespace import. This decouples the record from procedure logic, improving separation of concerns and data transfer handling.
2026-03-24 11:11:12 +01:00
b3bb7144ef Refactor IUpdateProcedure to generic with Id and Data props
Changed IUpdateProcedure to a generic interface IUpdateProcedure<T>, adding Id (long) and Data (T) properties for improved type safety and flexibility in update procedures. The interface continues to inherit from IRequest<int>.
2026-03-24 11:10:47 +01:00
eff6350d77 Refactor update procedures to use DTO-based pattern
Refactored Update*Procedure records to encapsulate update data in dedicated DTOs (e.g., UpdateActionDto, UpdateEndpointDto) via a generic Data property. Updated interfaces to be generic and modified handlers to pass only the DTO to UpdateObjectProcedure. This improves maintainability, reduces duplication, and standardizes update logic across entities.
2026-03-24 11:09:46 +01:00
114b5de71d Add Update DTOs for partial entity updates in Procedures
Introduced six new DTO record classes under ReC.Application.Common.Procedures.UpdateProcedure.Dto to support partial (nullable) updates for Action, Endpoint, EndpointAuth, EndpointParams, Profile, and Result entities. These DTOs enable PATCH-like update operations by allowing selective property updates. No existing code was modified.
2026-03-24 11:08:37 +01:00
f786192786 Refactor ResultController to use mediator.Send for commands
Standardize command handling by replacing custom mediator methods
with mediator.Send in ResultController. Update PUT endpoint to
remove id route parameter and rely on payload for identification.
2026-03-24 11:07:42 +01:00
50741bfdd3 Refactor RecActionController to use MediatR Send only
Simplified controller by removing IConfiguration dependency and unused usings. Refactored all endpoints to use MediatR's Send method with command objects, eliminating custom mediator extension methods and route parameters like id. This streamlines command handling and reduces dependencies.
2026-03-24 11:06:20 +01:00
561eafe48c Refactor ProfileController to use MediatR Send method
Replaces custom Execute*Procedure methods with MediatR's Send for insert, update, and delete operations. Removes obsolete using directives. Updates the PUT endpoint to accept the profile ID in the request body instead of the route.
2026-03-24 11:04:41 +01:00
84358ced96 Refactor EndpointsController to use standard MediatR pattern
Removed IConfiguration dependency and replaced custom mediator
extension methods with standard mediator.Send calls for endpoint
commands. Simplified method signatures and removed unused usings.
Updated PUT endpoint to accept UpdateEndpointProcedure directly.
2026-03-24 11:03:28 +01:00
d2e97a2fef Refactor EndpointParamsController to use MediatR.Send
Removed IConfiguration dependency and custom MediatR extension methods from EndpointParamsController. All command handling now uses mediator.Send directly, and route/config parameters have been eliminated from endpoints. Cleaned up unused usings and streamlined controller logic.
2026-03-24 11:02:58 +01:00
d505c8415e Refactor EndpointAuthController to use MediatR Send
Replaced custom procedure execution methods with MediatR's Send method in EndpointAuthController. Removed obsolete using directives and updated the PUT endpoint to no longer require an id route parameter, expecting the id in the payload instead. This streamlines the controller and aligns it with standard MediatR practices.
2026-03-24 10:58:43 +01:00
a590ffd2dc Refactor InsertProfileProcedure to use MediatR handler
Refactored InsertProfileProcedure by removing the ToObjectProcedure method and introducing InsertProfileProcedureHandler, which implements IRequestHandler and delegates insert logic via MediatR's ISender. Updated using directives to include MediatR. This aligns profile insertion with the MediatR request/response pattern.
2026-03-24 10:14:58 +01:00
94da75ce37 Add MediatR handler for DeleteProfileProcedure command
Introduce DeleteProfileProcedureHandler using MediatR's IRequestHandler to process DeleteProfileProcedure requests. The handler sends a DeleteObjectProcedure via ISender, replacing the previous ToObjectProcedure method. Also, add necessary using directives and refactor logic to centralize command handling.
2026-03-24 10:14:10 +01:00
9c1ffd7df8 Refactor UpdateEndpointProcedure and add handler
Refactored UpdateEndpointProcedure to implement IUpdateProcedure directly and removed the ToObjectProcedure method. Introduced UpdateEndpointProcedureHandler using MediatR's ISender for command handling, aligning with MediatR patterns and enabling dependency injection.
2026-03-24 10:13:35 +01:00
e31d034266 Refactor InsertEndpointProcedure; add MediatR handler
Refactored InsertEndpointProcedure to remove the ToObjectProcedure method, making it a simple data record. Introduced InsertEndpointProcedureHandler using MediatR's IRequestHandler to handle insert commands asynchronously. Added necessary MediatR using directives.
2026-03-24 10:13:12 +01:00
649d7eff8c Refactor DeleteEndpointProcedure to use MediatR handler
Replaces the ToObjectProcedure method with a dedicated
DeleteEndpointProcedureHandler implementing IRequestHandler.
The handler uses MediatR's ISender to send DeleteObjectProcedure,
improving separation of concerns and aligning with MediatR
request/response patterns.
2026-03-24 10:12:35 +01:00
401d67de4c Refactor UpdateEndpointParamsProcedure to MediatR pattern
Refactored UpdateEndpointParamsProcedure to include all relevant properties and removed the ToObjectProcedure method. Introduced UpdateEndpointParamsProcedureHandler using MediatR's IRequestHandler, delegating update logic via ISender. This improves code structure and maintainability.
2026-03-24 10:11:55 +01:00
ed94415a33 Refactor InsertEndpointParamsProcedure with MediatR handler
Remove ToObjectProcedure method from InsertEndpointParamsProcedure and introduce InsertEndpointParamsProcedureHandler using MediatR's IRequestHandler. This decouples conversion and command logic, aligning with MediatR patterns and improving separation of concerns.
2026-03-24 10:10:14 +01:00
04513a3d08 Refactor endpoint params delete to use MediatR handler
Replaces ToObjectProcedure with DeleteEndpointParamsProcedureHandler using MediatR's request/handler pattern. Improves separation of concerns by delegating deletion logic to the handler and updates imports and namespace accordingly.
2026-03-24 10:09:37 +01:00
d390c3f7b6 Remove DeleteObjectProcedureExtensions and its methods
Deleted the DeleteObjectProcedureExtensions static class and its ExecuteDeleteProcedure extension methods from DeleteObjectProcedure.cs. These methods previously provided convenience for executing delete procedures via ISender. The core DeleteObjectProcedure record and its handler remain unchanged.
2026-03-24 10:08:45 +01:00
a40f20f6d9 Refactor UpdateEndpointAuthProcedure and add handler
Expanded UpdateEndpointAuthProcedure with new properties and removed the ToObjectProcedure method. Introduced UpdateEndpointAuthProcedureHandler using MediatR's ISender for command handling, improving separation of concerns and enabling dependency injection.
2026-03-24 09:59:21 +01:00
ee1f6a8753 Refactor InsertEndpointAuthProcedure handling
Move insert logic from InsertEndpointAuthProcedure to a new InsertEndpointAuthProcedureHandler using MediatR. Remove ToObjectProcedure method and update usings. The record now serves as a pure data structure.
2026-03-24 09:51:59 +01:00
1e35b6e263 Refactor DeleteEndpointAuthProcedure to use MediatR handler
Refactored DeleteEndpointAuthProcedure by removing the ToObjectProcedure method and introducing DeleteEndpointAuthProcedureHandler, which implements IRequestHandler and delegates deletion via MediatR's ISender. Consolidated using directives and namespace declarations.
2026-03-24 09:51:21 +01:00
e152e9a37a Refactor ChangedWho handling in UpdateObjectProcedure
ChangedWho is now initialized directly and no longer settable via a public method. Removed the ChangedBy method and related extension methods. Added a TODO to move ChangedWho assignment to authentication middleware in the future.
2026-03-24 09:48:37 +01:00
554aaa8b6c Refactor InsertObjectProcedure AddedWho handling
Removed AddedBy method and related extension; AddedWho is now set to a default value internally. Added a TODO to move AddedWho assignment to authentication middleware in the future.
2026-03-24 09:47:24 +01:00
329d156d08 Update IUpdateProcedure to use MediatR IRequest<int>
Refactored IUpdateProcedure to inherit from MediatR's IRequest<int> for integration with the MediatR pipeline. Removed the ToObjectProcedure method and added the necessary using directive for MediatR. This simplifies the interface and standardizes request handling.
2026-03-24 09:44:41 +01:00
246362812a Refactor IInsertProcedure for MediatR compatibility
IInsertProcedure now inherits from IRequest<long> to integrate with MediatR's request/response pattern. Removed the ToObjectProcedure method and added the necessary MediatR using directive.
2026-03-24 09:43:57 +01:00
71430918ac Refactor IDeleteProcedure to use MediatR IRequest<int>
IDeleteProcedure now inherits from MediatR's IRequest<int>, aligning it with MediatR request/response patterns. Removed the ToObjectProcedure method from the interface. Added the MediatR using directive. Note: The namespace and using directive are now on the same line, which may need formatting correction.
2026-03-24 09:43:36 +01:00
7a1705365b Add dynamic SQL execution to IRecDbContext interface
Added Database property to IRecDbContext for database operations. Introduced ExecuteDynamicSqlAsync extension method to run arbitrary SQL and return results as JSON. This enables flexible querying and result serialization.
2026-03-24 09:42:59 +01:00
acf136e689 Refactor UpdateProfileProcedure and add MediatR handler
Refactored UpdateProfileProcedure to implement IUpdateProcedure and expanded its properties. Removed ToObjectProcedure method. Introduced UpdateProfileProcedureHandler using MediatR's ISender for command dispatch. Modernized structure to use record types and handler classes.
2026-03-24 09:41:17 +01:00
6b4897702a Refactor DeleteActionProcedure to use MediatR handler
Refactored DeleteActionProcedure to implement IDeleteProcedure directly and removed the ToObjectProcedure method. Introduced DeleteActionProcedureHandler using MediatR's IRequestHandler to delegate deletion logic via ISender. Updated using directives for MediatR integration.
2026-03-19 23:19:07 +01:00
7d4e082958 Refactor InsertActionProcedure to use MediatR handler
Replaces the ToObjectProcedure method with an InsertActionProcedureHandler that implements IRequestHandler using MediatR. The handler maps InsertActionProcedure to InsertObjectProcedure and sends it via ISender. Also updates using statements to include MediatR.
2026-03-19 23:18:57 +01:00
d1dd021952 Refactor UpdateActionProcedure and add handler class
Expanded UpdateActionProcedure with new properties and removed the ToObjectProcedure method. Introduced UpdateActionProcedureHandler using MediatR to handle update logic and delegate to UpdateObjectProcedure. Centralized update logic in the handler for better maintainability.
2026-03-19 23:18:47 +01:00
5afc1791b0 Refactor DeleteResultProcedure to use MediatR handler
Remove ToObjectProcedure method and add DeleteResultProcedureHandler implementing IRequestHandler. The handler sends DeleteObjectProcedure via MediatR, mapping relevant properties. Also update using directives and namespace.
2026-03-19 23:18:38 +01:00
2ec07d7e96 Refactor InsertResultProcedure to use MediatR handler
Refactored InsertResultProcedure by removing its ToObjectProcedure method and introducing InsertResultProcedureHandler, which implements IRequestHandler and delegates object insertion via MediatR's ISender. This shifts conversion logic from the record to the handler and improves separation of concerns.
2026-03-19 23:18:29 +01:00
cbe4f1ba3c Refactor UpdateResultProcedure to use MediatR handler
Refactored UpdateResultProcedure to implement IUpdateProcedure directly and removed the ToObjectProcedure method. Introduced UpdateResultProcedureHandler using MediatR's IRequestHandler pattern, delegating update logic via ISender. This improves code structure and maintainability.
2026-03-19 23:18:17 +01:00
16155da033 Add Info and Error properties to OutResDto
Added two new nullable string properties, Info and Error, to the OutResDto record to support additional informational and error messages in responses.
2026-03-19 18:51:33 +01:00
0aa1414ea6 Add @pRESULT_INFO and @pRESULT_ERROR SQL parameters
Added two new SQL parameters, @pRESULT_INFO and @pRESULT_ERROR, to InsertObjectProcedure.cs. These are set from request.Result.Info and request.Result.Error, or to DBNull.Value if null, to support additional result data in the procedure.
2026-03-19 18:50:47 +01:00
181a9a83fd Add Info and Error properties to InsertResultProcedure
Added nullable string properties Info and Error to the InsertResultProcedure record to allow storing additional information and error messages related to insert operations.
2026-03-19 18:50:34 +01:00
5e3e12bad8 Add Info and Error properties to entity mapping
Added Info and Error properties to the entity configuration, mapping them to the RESULT_INFO and RESULT_ERROR columns in the database using HasColumnName. This allows the entity to store and retrieve additional result information and error details.
2026-03-19 18:49:28 +01:00
6dcc128ad5 Add Info, Error, AddedWho, and ChangedWho to ResultView
Extended ResultView with four new nullable string properties:
Info and Error for additional details and error messages,
and AddedWho and ChangedWho for tracking user metadata.
2026-03-19 18:49:08 +01:00
49 changed files with 456 additions and 334 deletions

View File

@@ -1,8 +1,5 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.EndpointAuth.Commands;
namespace ReC.API.Controllers;
@@ -21,22 +18,21 @@ public class EndpointAuthController(IMediator mediator, IConfiguration config) :
[ProducesResponseType(StatusCodes.Status201Created)]
public async Task<IActionResult> Post([FromBody] InsertEndpointAuthProcedure procedure, CancellationToken cancel)
{
var id = await mediator.ExecuteInsertProcedure(procedure, config["AddedWho"], cancel);
var id = await mediator.Send(procedure, cancel);
return StatusCode(StatusCodes.Status201Created, id);
}
/// <summary>
/// Updates an endpoint authentication record via the ENDPOINT_AUTH update procedure.
/// </summary>
/// <param name="id">ENDPOINT_AUTH identifier to update.</param>
/// <param name="procedure">UpdateEndpointAuthProcedure payload.</param>
/// <param name="cancel">A token to cancel the operation.</param>
/// <returns>No content on success.</returns>
[HttpPut("{id:long}")]
[HttpPut]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Put([FromRoute] long id, [FromBody] UpdateEndpointAuthProcedure procedure, CancellationToken cancel)
public async Task<IActionResult> Put([FromBody] UpdateEndpointAuthProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteUpdateProcedure(procedure, id, cancel: cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
@@ -50,7 +46,7 @@ public class EndpointAuthController(IMediator mediator, IConfiguration config) :
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Delete([FromBody] DeleteEndpointAuthProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteDeleteProcedure(procedure, cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
}

View File

@@ -1,15 +1,12 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.EndpointParams.Commands;
namespace ReC.API.Controllers;
[Route("api/[controller]")]
[ApiController]
public class EndpointParamsController(IMediator mediator, IConfiguration config) : ControllerBase
public class EndpointParamsController(IMediator mediator) : ControllerBase
{
/// <summary>
/// Inserts endpoint parameter records via the ENDPOINT_PARAMS insert procedure.
@@ -21,22 +18,21 @@ public class EndpointParamsController(IMediator mediator, IConfiguration config)
[ProducesResponseType(StatusCodes.Status201Created)]
public async Task<IActionResult> Post([FromBody] InsertEndpointParamsProcedure procedure, CancellationToken cancel)
{
var id = await mediator.ExecuteInsertProcedure(procedure, config["AddedWho"], cancel);
var id = await mediator.Send(procedure, cancel);
return StatusCode(StatusCodes.Status201Created, id);
}
/// <summary>
/// Updates endpoint parameter records via the ENDPOINT_PARAMS update procedure.
/// </summary>
/// <param name="id">ENDPOINT_PARAMS identifier to update.</param>
/// <param name="procedure">UpdateEndpointParamsProcedure payload.</param>
/// <param name="cancel">A token to cancel the operation.</param>
/// <returns>No content on success.</returns>
[HttpPut("{id:long}")]
[HttpPut]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Put([FromRoute] long id, [FromBody] UpdateEndpointParamsProcedure procedure, CancellationToken cancel)
public async Task<IActionResult> Put([FromBody] UpdateEndpointParamsProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteUpdateProcedure(procedure, id, cancel: cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
@@ -50,7 +46,7 @@ public class EndpointParamsController(IMediator mediator, IConfiguration config)
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Delete([FromBody] DeleteEndpointParamsProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteDeleteProcedure(procedure, cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
}

View File

@@ -1,15 +1,12 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Endpoints.Commands;
namespace ReC.API.Controllers;
[Route("api/[controller]")]
[ApiController]
public class EndpointsController(IMediator mediator, IConfiguration config) : ControllerBase
public class EndpointsController(IMediator mediator) : ControllerBase
{
/// <summary>
/// Inserts an endpoint via the ENDPOINT insert procedure.
@@ -21,22 +18,21 @@ public class EndpointsController(IMediator mediator, IConfiguration config) : Co
[ProducesResponseType(StatusCodes.Status201Created)]
public async Task<IActionResult> Post([FromBody] InsertEndpointProcedure procedure, CancellationToken cancel)
{
var id = await mediator.ExecuteInsertProcedure(procedure, config["AddedWho"], cancel);
var id = await mediator.Send(procedure, cancel);
return StatusCode(StatusCodes.Status201Created, id);
}
/// <summary>
/// Updates an endpoint via the ENDPOINT update procedure.
/// </summary>
/// <param name="id">ENDPOINT identifier to update.</param>
/// <param name="procedure">UpdateEndpointProcedure payload.</param>
/// <param name="cancel">A token to cancel the operation.</param>
/// <returns>No content on success.</returns>
[HttpPut("{id:long}")]
[HttpPut]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Put([FromRoute] long id, [FromBody] UpdateEndpointProcedure procedure, CancellationToken cancel)
public async Task<IActionResult> Put([FromBody] UpdateEndpointProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteUpdateProcedure(procedure, id, cancel: cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
@@ -50,7 +46,7 @@ public class EndpointsController(IMediator mediator, IConfiguration config) : Co
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Delete([FromBody] DeleteEndpointProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteDeleteProcedure(procedure, cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
}

View File

@@ -1,8 +1,5 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Profile.Commands;
using ReC.Application.Profile.Queries;
@@ -28,22 +25,21 @@ public class ProfileController(IMediator mediator) : ControllerBase
[ProducesResponseType(StatusCodes.Status201Created)]
public async Task<IActionResult> Post([FromBody] InsertProfileProcedure procedure, CancellationToken cancel)
{
var id = await mediator.ExecuteInsertProcedure(procedure, cancel: cancel);
var id = await mediator.Send(procedure, cancel);
return CreatedAtAction(nameof(Get), new { id }, id);
}
/// <summary>
/// Updates a profile via the PROFILE update procedure.
/// </summary>
/// <param name="id">Profile identifier to update.</param>
/// <param name="procedure">UpdateProfileProcedure payload.</param>
/// <param name="cancel">A token to cancel the operation.</param>
/// <returns>No content on success.</returns>
[HttpPut("{id:long}")]
[HttpPut]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Put([FromRoute] long id, [FromBody] UpdateProfileProcedure procedure, CancellationToken cancel)
public async Task<IActionResult> Put([FromBody] UpdateProfileProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteUpdateProcedure(procedure, id, cancel: cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
@@ -57,7 +53,7 @@ public class ProfileController(IMediator mediator) : ControllerBase
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Delete([FromBody] DeleteProfileProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteDeleteProcedure(procedure, cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
}

View File

@@ -1,8 +1,5 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.RecActions.Commands;
using ReC.Application.RecActions.Queries;
@@ -10,19 +7,19 @@ namespace ReC.API.Controllers;
[Route("api/[controller]")]
[ApiController]
public class RecActionController(IMediator mediator, IConfiguration config) : ControllerBase
public class RecActionController(IMediator mediator) : ControllerBase
{
/// <summary>
/// Invokes a batch of RecActions for a given profile.
/// </summary>
/// <param name="profileId">The ID of the profile.</param>
/// <param name="command">The command containing the profile ID.</param>
/// <param name="cancel">A token to cancel the operation.</param>
/// <returns>An HTTP 202 Accepted response indicating the process has been started.</returns>
[HttpPost("invoke/{profileId}")]
[HttpPost("invoke/{command}")]
[ProducesResponseType(StatusCodes.Status202Accepted)]
public async Task<IActionResult> Invoke([FromRoute] int profileId, CancellationToken cancel)
public async Task<IActionResult> Invoke([FromRoute] InvokeBatchRecActionViewsCommand command, CancellationToken cancel)
{
await mediator.InvokeBatchRecActionView(profileId, cancel);
await mediator.Send(command, cancel);
return Accepted();
}
@@ -47,7 +44,7 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
[ProducesResponseType(StatusCodes.Status201Created)]
public async Task<IActionResult> Create([FromBody] InsertActionProcedure command, CancellationToken cancel)
{
await mediator.ExecuteInsertProcedure(command, config["AddedWho"], cancel);
await mediator.Send(command, cancel);
return StatusCode(StatusCodes.Status201Created);
}
@@ -55,15 +52,14 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
/// <summary>
/// Updates a RecAction via the ACTION update procedure.
/// </summary>
/// <param name="id">RecAction identifier to update.</param>
/// <param name="procedure">UpdateActionProcedure payload.</param>
/// <param name="cancel">A token to cancel the operation.</param>
/// <returns>No content on success.</returns>
[HttpPut("{id:long}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Update([FromRoute] long id, [FromBody] UpdateActionProcedure procedure, CancellationToken cancel)
public async Task<IActionResult> Update([FromBody] UpdateActionProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteUpdateProcedure(procedure, id, cancel: cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
@@ -77,7 +73,7 @@ public class RecActionController(IMediator mediator, IConfiguration config) : Co
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Delete([FromBody] DeleteActionProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteDeleteProcedure(procedure, cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
#endregion CRUD

View File

@@ -32,22 +32,21 @@ public class ResultController(IMediator mediator) : ControllerBase
[ProducesResponseType(StatusCodes.Status201Created)]
public async Task<IActionResult> Post([FromBody] InsertResultProcedure procedure, CancellationToken cancel)
{
var id = await mediator.ExecuteInsertProcedure(procedure, cancel: cancel);
var id = await mediator.Send(procedure, cancel);
return CreatedAtAction(nameof(Get), new { actionId = procedure.ActionId }, new { id, procedure.ActionId });
}
/// <summary>
/// Updates a RESULT record via the update procedure.
/// </summary>
/// <param name="id">RESULT identifier to update.</param>
/// <param name="procedure">UpdateResultProcedure payload.</param>
/// <param name="cancel">A token to cancel the operation.</param>
/// <returns>No content on success.</returns>
[HttpPut("{id:long}")]
[HttpPut]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Put([FromRoute] long id, [FromBody] UpdateResultProcedure procedure, CancellationToken cancel)
public async Task<IActionResult> Put([FromBody] UpdateResultProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteUpdateProcedure(procedure, id, cancel: cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
@@ -61,7 +60,7 @@ public class ResultController(IMediator mediator) : ControllerBase
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Delete([FromBody] DeleteResultProcedure procedure, CancellationToken cancel)
{
await mediator.ExecuteDeleteProcedure(procedure, cancel);
await mediator.Send(procedure, cancel);
return NoContent();
}
}

View File

@@ -0,0 +1,29 @@
using DigitalData.Core.Abstraction.Application.Repository;
using MediatR;
using ReC.Application.Common.Interfaces;
using ReC.Application.RecActions.Commands;
using ReC.Domain.Constants;
namespace ReC.Application.Common.Behaviors.Action;
public class PreprocessingBehavior(IRecDbContext context, ISender sender) : IPipelineBehavior<InvokeRecActionViewCommand, bool>
{
public async Task<bool> Handle(InvokeRecActionViewCommand request, RequestHandlerDelegate<bool> next, CancellationToken cancel)
{
try
{
if (request.Action.PreprocessingQuery is string query)
await context.ExecuteDynamicSqlAsync(query);
}
catch (Exception ex)
{
if(request.Action.ErrorAction == ErrorAction.Stop)
{
// save output result
return false;
}
}
return await next(cancel);
}
}

View File

@@ -10,6 +10,10 @@ public record OutResDto
public string? Body { get; set; }
public string? Info { get; set; }
public string? Error { get; set; }
public string AddedWho { get; set; } = null!;
public DateTime AddedWhen { get; set; }

View File

@@ -1,6 +1,8 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using ReC.Domain.QueryOutput;
using ReC.Domain.Views;
using System.Text.Json;
namespace ReC.Application.Common.Interfaces;
@@ -21,4 +23,38 @@ public interface IRecDbContext
#endregion DbSets
public Task<int> SaveChangesAsync(CancellationToken cancel = default);
public DatabaseFacade Database { get; }
}
public static class RecDbContextSaveExtensions
{
public static async Task<string> ExecuteDynamicSqlAsync(this IRecDbContext context, string sql)
{
var result = new List<Dictionary<string, object?>>();
using var command = context.Database.GetDbConnection().CreateCommand();
command.CommandText = sql;
await context.Database.OpenConnectionAsync();
using var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
var row = new Dictionary<string, object?>();
for (int i = 0; i < reader.FieldCount; i++)
{
var columnName = reader.GetName(i);
var value = reader.IsDBNull(i) ? null : reader.GetValue(i);
row[columnName] = value;
}
result.Add(row);
}
return JsonSerializer.Serialize(result);
}
}

View File

@@ -31,25 +31,6 @@ public record DeleteObjectProcedure : IRequest<int>
public bool Force { get; set; }
}
public static class DeleteObjectProcedureExtensions
{
public static Task<int> ExecuteDeleteProcedure(this ISender sender, IDeleteProcedure procedure, CancellationToken cancel = default)
{
return sender.Send(procedure.ToObjectProcedure(), cancel);
}
public static Task<int> ExecuteDeleteProcedure(this ISender sender, string entity, long start, long end = 0, bool force = false, CancellationToken cancel = default)
{
return sender.Send(new DeleteObjectProcedure
{
Entity = entity,
Start = start,
End = end,
Force = force
}, cancel);
}
}
public class DeleteObjectProcedureHandler(IRepository repo, IOptionsMonitor<SqlExceptionOptions> sqlExOpt) : IRequestHandler<DeleteObjectProcedure, int>
{
public async Task<int> Handle(DeleteObjectProcedure request, CancellationToken cancel)

View File

@@ -1,6 +1,7 @@
using MediatR;
namespace ReC.Application.Common.Procedures.DeleteProcedure;
public interface IDeleteProcedure
public interface IDeleteProcedure : IRequest<int>
{
public DeleteObjectProcedure ToObjectProcedure();
}

View File

@@ -1,6 +1,7 @@
namespace ReC.Application.Common.Procedures.InsertProcedure;
using MediatR;
public interface IInsertProcedure
namespace ReC.Application.Common.Procedures.InsertProcedure;
public interface IInsertProcedure : IRequest<long>
{
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null);
}

View File

@@ -21,13 +21,8 @@ public record InsertObjectProcedure : IRequest<long>
/// </summary>
public string Entity { get; set; } = null!;
internal string? AddedWho { get; private set; }
public InsertObjectProcedure AddedBy(string? addedWho = null)
{
AddedWho = addedWho ?? "ReC.API";
return this;
}
//TODO: update to set in authentication middleware or similar, and remove from procedure properties
internal string? AddedWho { get; private set; } = "ReC.API";
public InsertActionProcedure Action { get; set; } = new();
public InsertEndpointProcedure Endpoint { get; set; } = new();
@@ -37,14 +32,6 @@ public record InsertObjectProcedure : IRequest<long>
public InsertEndpointParamsProcedure EndpointParams { get; set; } = new();
}
public static class InsertObjectProcedureExtensions
{
public static Task<long> ExecuteInsertProcedure(this ISender sender, IInsertProcedure procedure, string? addedWho = null, CancellationToken cancel = default)
{
return sender.Send(procedure.ToObjectProcedure(addedWho ?? "Rec.API"), cancel);
}
}
public class InsertObjectProcedureHandler(IRepository repo, IOptionsMonitor<SqlExceptionOptions> sqlExOpt) : IRequestHandler<InsertObjectProcedure, long>
{
public async Task<long> Handle(InsertObjectProcedure request, CancellationToken cancel)
@@ -98,6 +85,8 @@ public class InsertObjectProcedureHandler(IRepository repo, IOptionsMonitor<SqlE
new SqlParameter("@pRESULT_STATUS_ID", (object?)request.Result.StatusId ?? DBNull.Value),
new SqlParameter("@pRESULT_HEADER", (object?)request.Result.Header ?? DBNull.Value),
new SqlParameter("@pRESULT_BODY", (object?)request.Result.Body ?? DBNull.Value),
new SqlParameter("@pRESULT_INFO", (object?)request.Result.Info ?? DBNull.Value),
new SqlParameter("@pRESULT_ERROR", (object?)request.Result.Error ?? DBNull.Value),
new SqlParameter("@pENDPOINT_PARAMS_ACTIVE", (object?)request.EndpointParams.Active ?? DBNull.Value),
new SqlParameter("@pENDPOINT_PARAMS_DESCRIPTION", (object?)request.EndpointParams.Description ?? DBNull.Value),

View File

@@ -0,0 +1,18 @@
namespace ReC.Application.Common.Procedures.UpdateProcedure.Dto;
public record UpdateActionDto
{
public long? ProfileId { get; set; }
public bool? Active { get; set; }
public byte? Sequence { get; set; }
public long? EndpointId { get; set; }
public long? EndpointAuthId { get; set; }
public short? EndpointParamsId { get; set; }
public short? SqlConnectionId { get; set; }
public byte? TypeId { get; set; }
public string? PreSql { get; set; }
public string? HeaderSql { get; set; }
public string? BodySql { get; set; }
public string? PostSql { get; set; }
public byte? ErrorActionId { get; set; }
}

View File

@@ -0,0 +1,16 @@
namespace ReC.Application.Common.Procedures.UpdateProcedure.Dto;
public record UpdateEndpointAuthDto
{
public bool? Active { get; set; }
public string? Description { get; set; }
public byte? TypeId { get; set; }
public string? ApiKey { get; set; }
public string? ApiValue { get; set; }
public bool? ApiKeyAddToId { get; set; }
public string? Token { get; set; }
public string? Username { get; set; }
public string? Password { get; set; }
public string? Domain { get; set; }
public string? Workstation { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace ReC.Application.Common.Procedures.UpdateProcedure.Dto;
public record UpdateEndpointDto
{
public bool? Active { get; set; }
public string? Description { get; set; }
public string? Uri { get; set; }
}

View File

@@ -0,0 +1,11 @@
namespace ReC.Application.Common.Procedures.UpdateProcedure.Dto;
public record UpdateEndpointParamsDto
{
public bool? Active { get; set; }
public string? Description { get; set; }
public short? GroupId { get; set; }
public byte? Sequence { get; set; }
public string? Key { get; set; }
public string? Value { get; set; }
}

View File

@@ -0,0 +1,15 @@
namespace ReC.Application.Common.Procedures.UpdateProcedure.Dto;
public record UpdateProfileDto
{
public bool? Active { get; set; }
public byte? TypeId { get; set; }
public string? Mandantor { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public byte? LogLevelId { get; set; }
public short? LanguageId { get; set; }
public DateTime? FirstRun { get; set; }
public DateTime? LastRun { get; set; }
public string? LastResult { get; set; }
}

View File

@@ -0,0 +1,9 @@
namespace ReC.Application.Common.Procedures.UpdateProcedure.Dto;
public record UpdateResultDto
{
public long? ActionId { get; set; }
public short? StatusId { get; set; }
public string? Header { get; set; }
public string? Body { get; set; }
}

View File

@@ -1,6 +1,10 @@
using MediatR;
namespace ReC.Application.Common.Procedures.UpdateProcedure;
public interface IUpdateProcedure
public interface IUpdateProcedure<T> : IRequest<int>
{
public UpdateObjectProcedure ToObjectProcedure(long id, string? changedWho = null);
}
public long Id { get; set; }
public T Data { get; set; }
}

View File

@@ -5,6 +5,7 @@ using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
using ReC.Application.Common.Exceptions;
using ReC.Application.Common.Options;
using ReC.Application.Common.Procedures.UpdateProcedure.Dto;
using ReC.Application.EndpointAuth.Commands;
using ReC.Application.EndpointParams.Commands;
using ReC.Application.Endpoints.Commands;
@@ -26,28 +27,15 @@ public record UpdateObjectProcedure : IRequest<int>
/// </summary>
public long Id { get; set; }
internal string? ChangedWho { get; private set; }
//TODO: update to set in authentication middleware or similar, and remove from procedure properties
internal string? ChangedWho { get; private set; } = "ReC.API";
public UpdateObjectProcedure ChangedBy(string? changedWho = null)
{
ChangedWho = changedWho ?? "ReC.API";
return this;
}
public UpdateActionProcedure Action { get; set; } = new();
public UpdateEndpointProcedure Endpoint { get; set; } = new();
public UpdateEndpointAuthProcedure EndpointAuth { get; set; } = new();
public UpdateProfileProcedure Profile { get; set; } = new();
public UpdateResultProcedure Result { get; set; } = new();
public UpdateEndpointParamsProcedure EndpointParams { get; set; } = new();
}
public static class UpdateObjectProcedureExtensions
{
public static Task<int> ExecuteUpdateProcedure(this ISender sender, IUpdateProcedure procedure, long id, string? changedWho = null, CancellationToken cancel = default)
{
return sender.Send(procedure.ToObjectProcedure(id, changedWho ?? "ReC.API"), cancel);
}
public UpdateActionDto Action { get; set; } = new();
public UpdateEndpointDto Endpoint { get; set; } = new();
public UpdateEndpointAuthDto EndpointAuth { get; set; } = new();
public UpdateProfileDto Profile { get; set; } = new();
public UpdateResultDto Result { get; set; } = new();
public UpdateEndpointParamsDto EndpointParams { get; set; } = new();
}
public class UpdateObjectProcedureHandler(IRepository repo, IOptionsMonitor<SqlExceptionOptions> sqlExOpt) : IRequestHandler<UpdateObjectProcedure, int>

View File

@@ -1,3 +1,4 @@
using MediatR;
using ReC.Application.Common.Procedures.DeleteProcedure;
namespace ReC.Application.EndpointAuth.Commands;
@@ -18,15 +19,18 @@ public record DeleteEndpointAuthProcedure : IDeleteProcedure
/// If true, delete even if dependent ACTION data exists
/// </summary>
public bool Force { get; set; }
}
public DeleteObjectProcedure ToObjectProcedure()
public class DeleteEndpointAuthProcedureHandler(ISender sender) : IRequestHandler<DeleteEndpointAuthProcedure, int>
{
public async Task<int> Handle(DeleteEndpointAuthProcedure request, CancellationToken cancel)
{
return new DeleteObjectProcedure
return await sender.Send(new DeleteObjectProcedure
{
Entity = "ENDPOINT_AUTH",
Start = Start,
End = End,
Force = Force
};
Start = request.Start,
End = request.End,
Force = request.Force
}, cancel);
}
}
}

View File

@@ -1,4 +1,5 @@
using ReC.Application.Common.Procedures.InsertProcedure;
using MediatR;
using ReC.Application.Common.Procedures.InsertProcedure;
namespace ReC.Application.EndpointAuth.Commands;
@@ -15,13 +16,16 @@ public record InsertEndpointAuthProcedure : IInsertProcedure
public string? Password { get; set; }
public string? Domain { get; set; }
public string? Workstation { get; set; }
}
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
public class InsertEndpointAuthProcedureHandler(ISender sender) : IRequestHandler<InsertEndpointAuthProcedure, long>
{
public async Task<long> Handle(InsertEndpointAuthProcedure request, CancellationToken cancel)
{
return new InsertObjectProcedure
return await sender.Send(new InsertObjectProcedure
{
Entity = "ENDPOINT_AUTH",
EndpointAuth = this
}.AddedBy(addedWho);
EndpointAuth = request
}, cancel);
}
}

View File

@@ -1,28 +1,25 @@
using MediatR;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure.Dto;
namespace ReC.Application.EndpointAuth.Commands;
public record UpdateEndpointAuthProcedure : IUpdateProcedure
public record UpdateEndpointAuthProcedure : IUpdateProcedure<UpdateEndpointAuthDto>
{
public bool? Active { get; set; }
public string? Description { get; set; }
public byte? TypeId { get; set; }
public string? ApiKey { get; set; }
public string? ApiValue { get; set; }
public bool? ApiKeyAddToId { get; set; }
public string? Token { get; set; }
public string? Username { get; set; }
public string? Password { get; set; }
public string? Domain { get; set; }
public string? Workstation { get; set; }
public long Id { get; set; }
public UpdateObjectProcedure ToObjectProcedure(long id, string? changedWho = null)
public UpdateEndpointAuthDto Data { get; set; } = null!;
}
public class UpdateEndpointAuthProcedureHandler(ISender sender) : IRequestHandler<UpdateEndpointAuthProcedure, int>
{
public async Task<int> Handle(UpdateEndpointAuthProcedure request, CancellationToken cancel)
{
return new UpdateObjectProcedure
return await sender.Send(new UpdateObjectProcedure
{
Entity = "ENDPOINT_AUTH",
Id = id,
EndpointAuth = this
}.ChangedBy(changedWho);
Id = request.Id,
EndpointAuth = request.Data
}, cancel);
}
}
}

View File

@@ -1,3 +1,4 @@
using MediatR;
using ReC.Application.Common.Procedures.DeleteProcedure;
namespace ReC.Application.EndpointParams.Commands;
@@ -18,15 +19,18 @@ public record DeleteEndpointParamsProcedure : IDeleteProcedure
/// If true, delete even if dependent ACTION data exists
/// </summary>
public bool Force { get; set; }
}
public DeleteObjectProcedure ToObjectProcedure()
public class DeleteEndpointParamsProcedureHandler(ISender sender) : IRequestHandler<DeleteEndpointParamsProcedure, int>
{
public async Task<int> Handle(DeleteEndpointParamsProcedure request, CancellationToken cancel)
{
return new DeleteObjectProcedure
return await sender.Send(new DeleteObjectProcedure
{
Entity = "ENDPOINT_PARAMS",
Start = Start,
End = End,
Force = Force
};
Start = request.Start,
End = request.End,
Force = request.Force
}, cancel);
}
}
}

View File

@@ -1,4 +1,5 @@
using ReC.Application.Common.Procedures.InsertProcedure;
using MediatR;
using ReC.Application.Common.Procedures.InsertProcedure;
namespace ReC.Application.EndpointParams.Commands;
@@ -10,13 +11,16 @@ public record InsertEndpointParamsProcedure : IInsertProcedure
public byte? Sequence { get; set; }
public string? Key { get; set; }
public string? Value { get; set; }
}
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
public class InsertEndpointParamsProcedureHandler(ISender sender) : IRequestHandler<InsertEndpointParamsProcedure, long>
{
public async Task<long> Handle(InsertEndpointParamsProcedure request, CancellationToken cancel)
{
return new InsertObjectProcedure
return await sender.Send(new InsertObjectProcedure
{
Entity = "ENDPOINT_PARAMS",
EndpointParams = this
}.AddedBy(addedWho);
EndpointParams = request
}, cancel);
}
}

View File

@@ -1,23 +1,25 @@
using MediatR;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure.Dto;
namespace ReC.Application.EndpointParams.Commands;
public record UpdateEndpointParamsProcedure : IUpdateProcedure
public record UpdateEndpointParamsProcedure : IUpdateProcedure<UpdateEndpointParamsDto>
{
public bool? Active { get; set; }
public string? Description { get; set; }
public short? GroupId { get; set; }
public byte? Sequence { get; set; }
public string? Key { get; set; }
public string? Value { get; set; }
public long Id { get; set; }
public UpdateObjectProcedure ToObjectProcedure(long id, string? changedWho = null)
public UpdateEndpointParamsDto Data { get; set; } = null!;
}
public class UpdateEndpointParamsProcedureHandler(ISender sender) : IRequestHandler<UpdateEndpointParamsProcedure, int>
{
public async Task<int> Handle(UpdateEndpointParamsProcedure request, CancellationToken cancel)
{
return new UpdateObjectProcedure
return await sender.Send(new UpdateObjectProcedure
{
Entity = "ENDPOINT_PARAMS",
Id = id,
EndpointParams = this
}.ChangedBy(changedWho);
Id = request.Id,
EndpointParams = request.Data
}, cancel);
}
}
}

View File

@@ -1,3 +1,4 @@
using MediatR;
using ReC.Application.Common.Procedures.DeleteProcedure;
namespace ReC.Application.Endpoints.Commands;
@@ -18,15 +19,18 @@ public record DeleteEndpointProcedure : IDeleteProcedure
/// If true, delete even if dependent ACTION data exists
/// </summary>
public bool Force { get; set; }
}
public DeleteObjectProcedure ToObjectProcedure()
public class DeleteEndpointProcedureHandler(ISender sender) : IRequestHandler<DeleteEndpointProcedure, int>
{
public async Task<int> Handle(DeleteEndpointProcedure request, CancellationToken cancel)
{
return new DeleteObjectProcedure
return await sender.Send(new DeleteObjectProcedure
{
Entity = "ENDPOINT",
Start = Start,
End = End,
Force = Force
};
Start = request.Start,
End = request.End,
Force = request.Force
}, cancel);
}
}

View File

@@ -1,4 +1,5 @@
using ReC.Application.Common.Procedures.InsertProcedure;
using MediatR;
using ReC.Application.Common.Procedures.InsertProcedure;
namespace ReC.Application.Endpoints.Commands;
@@ -7,13 +8,16 @@ public record InsertEndpointProcedure : IInsertProcedure
public bool? Active { get; set; }
public string? Description { get; set; }
public string? Uri { get; set; }
}
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
public class InsertEndpointProcedureHandler(ISender sender) : IRequestHandler<InsertEndpointProcedure, long>
{
public async Task<long> Handle(InsertEndpointProcedure request, CancellationToken cancel)
{
return new InsertObjectProcedure
return await sender.Send(new InsertObjectProcedure
{
Entity = "ENDPOINT",
Endpoint = this
}.AddedBy(addedWho);
Endpoint = request
}, cancel);
}
}

View File

@@ -1,20 +1,25 @@
using MediatR;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure.Dto;
namespace ReC.Application.Endpoints.Commands;
public record UpdateEndpointProcedure : IUpdateProcedure
public record UpdateEndpointProcedure : IUpdateProcedure<UpdateEndpointDto>
{
public bool? Active { get; set; }
public string? Description { get; set; }
public string? Uri { get; set; }
public long Id { get; set; }
public UpdateObjectProcedure ToObjectProcedure(long id, string? changedWho = null)
public UpdateEndpointDto Data { get; set; } = null!;
}
public class UpdateEndpointProcedureHandler(ISender sender) : IRequestHandler<UpdateEndpointProcedure, int>
{
public async Task<int> Handle(UpdateEndpointProcedure request, CancellationToken cancel)
{
return new UpdateObjectProcedure
return await sender.Send(new UpdateObjectProcedure
{
Entity = "ENDPOINT",
Id = id,
Endpoint = this
}.ChangedBy(changedWho);
Id = request.Id,
Endpoint = request.Data
}, cancel);
}
}
}

View File

@@ -1,3 +1,4 @@
using MediatR;
using ReC.Application.Common.Procedures.DeleteProcedure;
namespace ReC.Application.Profile.Commands;
@@ -18,15 +19,18 @@ public record DeleteProfileProcedure : IDeleteProcedure
/// If true, delete even if dependent ACTION data exists
/// </summary>
public bool Force { get; set; }
}
public DeleteObjectProcedure ToObjectProcedure()
public class DeleteProfileProcedureHandler(ISender sender) : IRequestHandler<DeleteProfileProcedure, int>
{
public async Task<int> Handle(DeleteProfileProcedure request, CancellationToken cancel)
{
return new DeleteObjectProcedure
return await sender.Send(new DeleteObjectProcedure
{
Entity = "PROFILE",
Start = Start,
End = End,
Force = Force
};
Start = request.Start,
End = request.End,
Force = request.Force
}, cancel);
}
}
}

View File

@@ -1,4 +1,5 @@
using ReC.Application.Common.Procedures.InsertProcedure;
using MediatR;
using ReC.Application.Common.Procedures.InsertProcedure;
namespace ReC.Application.Profile.Commands;
@@ -11,13 +12,16 @@ public record InsertProfileProcedure : IInsertProcedure
public string? Description { get; set; }
public byte? LogLevelId { get; set; }
public short? LanguageId { get; set; }
}
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
public class InsertProfileProcedureHandler(ISender sender) : IRequestHandler<InsertProfileProcedure, long>
{
public async Task<long> Handle(InsertProfileProcedure request, CancellationToken cancel)
{
return new InsertObjectProcedure
return await sender.Send(new InsertObjectProcedure
{
Entity = "PROFILE",
Profile = this
}.AddedBy(addedWho);
Profile = request
}, cancel);
}
}

View File

@@ -1,27 +1,25 @@
using MediatR;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure.Dto;
namespace ReC.Application.Profile.Commands;
public record UpdateProfileProcedure : IUpdateProcedure
public record UpdateProfileProcedure : IUpdateProcedure<UpdateProfileDto>
{
public bool? Active { get; set; }
public byte? TypeId { get; set; }
public string? Mandantor { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public byte? LogLevelId { get; set; }
public short? LanguageId { get; set; }
public DateTime? FirstRun { get; set; }
public DateTime? LastRun { get; set; }
public string? LastResult { get; set; }
public long Id { get; set; }
public UpdateObjectProcedure ToObjectProcedure(long id, string? changedWho = null)
public UpdateProfileDto Data { get; set; } = null!;
}
public class UpdateProfileProcedureHandler(ISender sender) : IRequestHandler<UpdateProfileProcedure, int>
{
public async Task<int> Handle(UpdateProfileProcedure request, CancellationToken cancel)
{
return new UpdateObjectProcedure
return await sender.Send(new UpdateObjectProcedure
{
Entity = "PROFILE",
Id = id,
Profile = this
}.ChangedBy(changedWho);
Id = request.Id,
Profile = request.Data
}, cancel);
}
}
}

View File

@@ -1,3 +1,4 @@
using MediatR;
using ReC.Application.Common.Procedures.DeleteProcedure;
namespace ReC.Application.RecActions.Commands;
@@ -18,15 +19,18 @@ public record DeleteActionProcedure : IDeleteProcedure
/// If true, delete even if dependent RESULT data exists
/// </summary>
public bool Force { get; set; }
}
public DeleteObjectProcedure ToObjectProcedure()
public class DeleteActionProcedureHandler(ISender sender) : IRequestHandler<DeleteActionProcedure, int>
{
public async Task<int> Handle(DeleteActionProcedure request, CancellationToken cancel)
{
return new DeleteObjectProcedure
return await sender.Send(new DeleteObjectProcedure
{
Entity = "ACTION",
Start = Start,
End = End,
Force = Force
};
Start = request.Start,
End = request.End,
Force = request.Force
}, cancel);
}
}
}

View File

@@ -1,4 +1,5 @@
using ReC.Application.Common.Procedures.InsertProcedure;
using MediatR;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Domain.Constants;
namespace ReC.Application.RecActions.Commands;
@@ -18,13 +19,16 @@ public record InsertActionProcedure : IInsertProcedure
public string? BodySql { get; set; }
public string? PostSql { get; set; }
public byte? ErrorActionId { get; set; }
}
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
public class InsertActionProcedureHandler(ISender sender) : IRequestHandler<InsertActionProcedure, long>
{
public async Task<long> Handle(InsertActionProcedure request, CancellationToken cancel)
{
return new InsertObjectProcedure
return await sender.Send(new InsertObjectProcedure
{
Entity = "ACTION",
Action = this
}.AddedBy(addedWho);
Action = request
}, cancel);
}
}

View File

@@ -148,13 +148,13 @@ public class InvokeRecActionViewCommandHandler(
var statusCode = (short)response.StatusCode;
await sender.ExecuteInsertProcedure(new InsertResultProcedure()
await sender.Send(new InsertResultProcedure()
{
StatusId = statusCode,
ActionId = action.Id,
Header = JsonSerializer.Serialize(resHeaders, options: new() { WriteIndented = false }),
Body = resBody
}, _options.AddedWho, cancel);
}, cancel);
return response.IsSuccessStatusCode;
}

View File

@@ -1,30 +1,25 @@
using MediatR;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure.Dto;
namespace ReC.Application.RecActions.Commands;
public record UpdateActionProcedure : IUpdateProcedure
public record UpdateActionProcedure : IUpdateProcedure<UpdateActionDto>
{
public long? ProfileId { get; set; }
public bool? Active { get; set; }
public byte? Sequence { get; set; }
public long? EndpointId { get; set; }
public long? EndpointAuthId { get; set; }
public short? EndpointParamsId { get; set; }
public short? SqlConnectionId { get; set; }
public byte? TypeId { get; set; }
public string? PreSql { get; set; }
public string? HeaderSql { get; set; }
public string? BodySql { get; set; }
public string? PostSql { get; set; }
public byte? ErrorActionId { get; set; }
public long Id { get; set; }
public UpdateObjectProcedure ToObjectProcedure(long id, string? changedWho = null)
public UpdateActionDto Data { get; set; } = null!;
}
public class UpdateActionProcedureHandler(ISender sender) : IRequestHandler<UpdateActionProcedure, int>
{
public async Task<int> Handle(UpdateActionProcedure request, CancellationToken cancel)
{
return new UpdateObjectProcedure
return await sender.Send(new UpdateObjectProcedure
{
Entity = "ACTION",
Id = id,
Action = this
}.ChangedBy(changedWho);
Id = request.Id,
Action = request.Data
}, cancel);
}
}
}

View File

@@ -1,3 +1,4 @@
using MediatR;
using ReC.Application.Common.Procedures.DeleteProcedure;
namespace ReC.Application.Results.Commands;
@@ -18,15 +19,18 @@ public record DeleteResultProcedure : IDeleteProcedure
/// Force parameter (not used for RESULT entity as it has no dependencies)
/// </summary>
public bool Force { get; set; }
}
public DeleteObjectProcedure ToObjectProcedure()
public class DeleteResultProcedureHandler(ISender sender) : IRequestHandler<DeleteResultProcedure, int>
{
public async Task<int> Handle(DeleteResultProcedure request, CancellationToken cancel)
{
return new DeleteObjectProcedure
return await sender.Send(new DeleteObjectProcedure
{
Entity = "RESULT",
Start = Start,
End = End,
Force = Force
};
Start = request.Start,
End = request.End,
Force = request.Force
}, cancel);
}
}
}

View File

@@ -1,4 +1,5 @@
using ReC.Application.Common.Procedures.InsertProcedure;
using MediatR;
using ReC.Application.Common.Procedures.InsertProcedure;
namespace ReC.Application.Results.Commands;
@@ -8,13 +9,18 @@ public record InsertResultProcedure : IInsertProcedure
public short? StatusId { get; set; }
public string? Header { get; set; }
public string? Body { get; set; }
public string? Info { get; set; }
public string? Error { get; set; }
}
public InsertObjectProcedure ToObjectProcedure(string? addedWho = null)
public class InsertResultProcedureHandler(ISender sender) : IRequestHandler<InsertResultProcedure, long>
{
public async Task<long> Handle(InsertResultProcedure request, CancellationToken cancel)
{
return new InsertObjectProcedure
return await sender.Send(new InsertObjectProcedure
{
Entity = "RESULT",
Result = this
}.AddedBy(addedWho ?? "Rec.API");
Result = request
}, cancel);
}
}

View File

@@ -1,21 +1,25 @@
using MediatR;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure.Dto;
namespace ReC.Application.Results.Commands;
public record UpdateResultProcedure : IUpdateProcedure
public record UpdateResultProcedure : IUpdateProcedure<UpdateResultDto>
{
public long? ActionId { get; set; }
public short? StatusId { get; set; }
public string? Header { get; set; }
public string? Body { get; set; }
public long Id { get; set; }
public UpdateObjectProcedure ToObjectProcedure(long id, string? changedWho = null)
public UpdateResultDto Data { get; set; } = null!;
}
public class UpdateResultProcedureHandler(ISender sender) : IRequestHandler<UpdateResultProcedure, int>
{
public async Task<int> Handle(UpdateResultProcedure request, CancellationToken cancel)
{
return new UpdateObjectProcedure
return await sender.Send(new UpdateObjectProcedure
{
Entity = "RESULT",
Id = id,
Result = this
}.ChangedBy(changedWho);
Id = request.Id,
Result = request.Data
}, cancel);
}
}
}

View File

@@ -25,6 +25,10 @@ public class ResultView
public string? Body { get; set; }
public string? Info { get; set; }
public string? Error { get; set; }
public string? AddedWho { get; set; }
public DateTime? AddedWhen { get; set; }

View File

@@ -107,6 +107,8 @@ public class RecDbContext(DbContextOptions<RecDbContext> options) : DbContext(op
b.Property(e => e.StatusName).HasColumnName("STATUS");
b.Property(e => e.Header).HasColumnName("RESULT_HEADER");
b.Property(e => e.Body).HasColumnName("RESULT_BODY");
b.Property(e => e.Info).HasColumnName("RESULT_INFO");
b.Property(e => e.Error).HasColumnName("RESULT_ERROR");
b.Property(e => e.AddedWho).HasColumnName("ADDED_WHO");
b.Property(e => e.AddedWhen).HasColumnName("ADDED_WHEN");
b.Property(e => e.ChangedWho).HasColumnName("CHANGED_WHO");

View File

@@ -24,11 +24,10 @@ public class EndpointAuthProcedureTests : RecApplicationTestBase
public async Task InsertEndpointAuthProcedure_runs_via_mediator()
{
var procedure = new InsertEndpointAuthProcedure { Active = true, Description = "auth", TypeId = 1, ApiKey = "key", ApiValue = "value" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.GreaterThan(0));
}
@@ -36,12 +35,11 @@ public class EndpointAuthProcedureTests : RecApplicationTestBase
[Test]
public async Task UpdateEndpointAuthProcedure_runs_via_mediator()
{
var procedure = new UpdateEndpointAuthProcedure { Active = false, Description = "auth-update", TypeId = 2 };
var objectProc = procedure.ToObjectProcedure(15, "ReC.Tests");
var procedure = new UpdateEndpointAuthProcedure { Data = { Active = false, Description = "auth-update", TypeId = 2 }, Id = 15 };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}
@@ -50,11 +48,10 @@ public class EndpointAuthProcedureTests : RecApplicationTestBase
public async Task DeleteEndpointAuthProcedure_runs_via_mediator()
{
var procedure = new DeleteEndpointAuthProcedure { Start = 3, End = 4, Force = false };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}

View File

@@ -1,12 +1,6 @@
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.EndpointParams.Commands;
using ReC.Tests.Application;
namespace ReC.Tests.Application.EndpointParams;
@@ -24,11 +18,10 @@ public class EndpointParamsProcedureTests : RecApplicationTestBase
public async Task InsertEndpointParamsProcedure_runs_via_mediator()
{
var procedure = new InsertEndpointParamsProcedure { Active = true, Description = "param", GroupId = 1, Sequence = 1, Key = "k", Value = "v" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.GreaterThan(0));
}
@@ -36,12 +29,11 @@ public class EndpointParamsProcedureTests : RecApplicationTestBase
[Test]
public async Task UpdateEndpointParamsProcedure_runs_via_mediator()
{
var procedure = new UpdateEndpointParamsProcedure { Active = false, Description = "param-update", GroupId = 2, Sequence = 2, Key = "k2", Value = "v2" };
var objectProc = procedure.ToObjectProcedure(25, "ReC.Tests");
var procedure = new UpdateEndpointParamsProcedure { Data = { Active = false, Description = "param-update", GroupId = 2, Sequence = 2, Key = "k2", Value = "v2" }, Id = 25 };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}
@@ -50,11 +42,10 @@ public class EndpointParamsProcedureTests : RecApplicationTestBase
public async Task DeleteEndpointParamsProcedure_runs_via_mediator()
{
var procedure = new DeleteEndpointParamsProcedure { Start = 5, End = 6, Force = true };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}

View File

@@ -24,11 +24,10 @@ public class EndpointProcedureTests : RecApplicationTestBase
public async Task InsertEndpointProcedure_runs_via_mediator()
{
var procedure = new InsertEndpointProcedure { Active = true, Description = "desc", Uri = "http://example" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.GreaterThan(0));
}
@@ -36,12 +35,11 @@ public class EndpointProcedureTests : RecApplicationTestBase
[Test]
public async Task UpdateEndpointProcedure_runs_via_mediator()
{
var procedure = new UpdateEndpointProcedure { Active = false, Description = "updated", Uri = "http://updated" };
var objectProc = procedure.ToObjectProcedure(12, "ReC.Tests");
var procedure = new UpdateEndpointProcedure { Data = { Active = false, Description = "updated", Uri = "http://updated" }, Id = 12 };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}
@@ -50,11 +48,10 @@ public class EndpointProcedureTests : RecApplicationTestBase
public async Task DeleteEndpointProcedure_runs_via_mediator()
{
var procedure = new DeleteEndpointProcedure { Start = 1, End = 2, Force = true };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}

View File

@@ -27,7 +27,7 @@ public class ProcedureExecutionTests : RecApplicationTestBase
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.ExecuteInsertProcedure(procedure, "ReC.Tests");
var result = await sender.Send(procedure);
Assert.That(result, Is.GreaterThan(0));
}
@@ -35,11 +35,11 @@ public class ProcedureExecutionTests : RecApplicationTestBase
[Test]
public async Task ExecuteUpdateProcedure_runs_with_changedWho()
{
var procedure = new UpdateProfileProcedure { Name = "updated" };
var procedure = new UpdateProfileProcedure { Data = { Name = "updated" }, Id = 123 };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.ExecuteUpdateProcedure(procedure, 123, "ReC.Tests");
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}
@@ -51,7 +51,7 @@ public class ProcedureExecutionTests : RecApplicationTestBase
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.ExecuteDeleteProcedure(procedure);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}

View File

@@ -24,11 +24,10 @@ public class ProfileProcedureTests : RecApplicationTestBase
public async Task InsertProfileProcedure_runs_via_mediator()
{
var procedure = new InsertProfileProcedure { Active = true, TypeId = 1, Name = "name", Mandantor = "man" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.GreaterThan(0));
}
@@ -36,12 +35,11 @@ public class ProfileProcedureTests : RecApplicationTestBase
[Test]
public async Task UpdateProfileProcedure_runs_via_mediator()
{
var procedure = new UpdateProfileProcedure { Active = false, TypeId = 2, Name = "updated", Mandantor = "man2" };
var objectProc = procedure.ToObjectProcedure(45, "ReC.Tests");
var procedure = new UpdateProfileProcedure { Data = { Active = false, TypeId = 2, Name = "updated", Mandantor = "man2" }, Id = 45 };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}
@@ -50,11 +48,10 @@ public class ProfileProcedureTests : RecApplicationTestBase
public async Task DeleteProfileProcedure_runs_via_mediator()
{
var procedure = new DeleteProfileProcedure { Start = 9, End = 10, Force = false };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}

View File

@@ -26,11 +26,10 @@ public class RecActionProcedureTests : RecApplicationTestBase
try
{
var procedure = new InsertActionProcedure { ProfileId = 1, Active = true, Sequence = 1, EndpointId = 1 };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.GreaterThan(0), "Expected a valid ID greater than 0 to be returned from the insert operation.");
}
@@ -54,12 +53,11 @@ public class RecActionProcedureTests : RecApplicationTestBase
[Test]
public async Task UpdateActionProcedure_runs_via_mediator()
{
var procedure = new UpdateActionProcedure { ProfileId = 2, Active = false, Sequence = 2 };
var objectProc = procedure.ToObjectProcedure(35, "ReC.Tests");
var procedure = new UpdateActionProcedure { Data = { ProfileId = 2, Active = false, Sequence = 2 }, Id = 35 };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}
@@ -68,11 +66,10 @@ public class RecActionProcedureTests : RecApplicationTestBase
public async Task DeleteActionProcedure_runs_via_mediator()
{
var procedure = new DeleteActionProcedure { Start = 7, End = 8, Force = true };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}

View File

@@ -24,11 +24,10 @@ public class ResultProcedureTests : RecApplicationTestBase
public async Task InsertResultProcedure_runs_via_mediator()
{
var procedure = new InsertResultProcedure { ActionId = 1, StatusId = 200, Header = "h", Body = "b" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.GreaterThan(0));
}
@@ -36,12 +35,11 @@ public class ResultProcedureTests : RecApplicationTestBase
[Test]
public async Task UpdateResultProcedure_runs_via_mediator()
{
var procedure = new UpdateResultProcedure { ActionId = 2, StatusId = 500, Header = "h2", Body = "b2" };
var objectProc = procedure.ToObjectProcedure(55, "ReC.Tests");
var procedure = new UpdateResultProcedure { Data = { ActionId = 2, StatusId = 500, Header = "h2", Body = "b2" }, Id = 55 };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}
@@ -50,11 +48,10 @@ public class ResultProcedureTests : RecApplicationTestBase
public async Task DeleteResultProcedure_runs_via_mediator()
{
var procedure = new DeleteResultProcedure { Start = 11, End = 12, Force = false };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
var result = await sender.Send(procedure);
Assert.That(result, Is.Not.EqualTo(default(int)));
}