Add indicators request endpoint
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Managing.Application.Abstractions;
|
||||
using Managing.Api.Models.Requests;
|
||||
using Managing.Application.Abstractions;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Application.Shared;
|
||||
using Managing.Application.Trading.Commands;
|
||||
@@ -29,6 +30,8 @@ public class TradingController : BaseController
|
||||
private readonly ILogger<TradingController> _logger;
|
||||
private readonly IAdminConfigurationService _adminService;
|
||||
private readonly IAccountService _accountService;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TradingController"/> class.
|
||||
@@ -40,6 +43,8 @@ public class TradingController : BaseController
|
||||
/// <param name="mediator">Mediator for handling commands and requests.</param>
|
||||
/// <param name="adminService">Service for checking admin privileges.</param>
|
||||
/// <param name="accountService">Service for account operations.</param>
|
||||
/// <param name="httpClientFactory">HTTP client factory for making web requests.</param>
|
||||
/// <param name="configuration">Application configuration.</param>
|
||||
public TradingController(
|
||||
ILogger<TradingController> logger,
|
||||
ICommandHandler<OpenPositionRequest, Position> openTradeCommandHandler,
|
||||
@@ -47,7 +52,9 @@ public class TradingController : BaseController
|
||||
ITradingService tradingService,
|
||||
IMediator mediator, IMoneyManagementService moneyManagementService,
|
||||
IUserService userService, IAdminConfigurationService adminService,
|
||||
IAccountService accountService) : base(userService)
|
||||
IAccountService accountService,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
IConfiguration configuration) : base(userService)
|
||||
{
|
||||
_logger = logger;
|
||||
_openTradeCommandHandler = openTradeCommandHandler;
|
||||
@@ -57,6 +64,8 @@ public class TradingController : BaseController
|
||||
_moneyManagementService = moneyManagementService;
|
||||
_adminService = adminService;
|
||||
_accountService = accountService;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
@@ -235,4 +244,107 @@ public class TradingController : BaseController
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Submits a request for a new indicator to be developed via N8n webhook.
|
||||
/// </summary>
|
||||
/// <param name="request">The indicator request details including name, strategy, documentation, and requester information.</param>
|
||||
/// <returns>A success response indicating the request was submitted.</returns>
|
||||
[HttpPost("RequestIndicator")]
|
||||
public async Task<ActionResult<object>> RequestIndicator([FromBody] IndicatorRequestDto request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
return BadRequest("Request cannot be null.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.IndicatorName))
|
||||
{
|
||||
return BadRequest("Indicator name is required.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.StrategyDescription))
|
||||
{
|
||||
return BadRequest("Strategy is required.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.DocumentationUrl))
|
||||
{
|
||||
return BadRequest("Documentation URL is required.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.RequesterName))
|
||||
{
|
||||
return BadRequest("Requester name is required.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var webhookUrl = _configuration["N8n:IndicatorRequestWebhookUrl"];
|
||||
|
||||
if (string.IsNullOrEmpty(webhookUrl))
|
||||
{
|
||||
_logger.LogError("N8n indicator request webhook URL is not configured");
|
||||
return StatusCode(500, new { Success = false, Error = "Webhook URL is not configured." });
|
||||
}
|
||||
|
||||
var httpClient = _httpClientFactory.CreateClient();
|
||||
|
||||
// Create multipart form data content
|
||||
using var content = new MultipartFormDataContent();
|
||||
content.Add(new StringContent(request.IndicatorName), "field-0");
|
||||
content.Add(new StringContent(request.StrategyDescription), "field-1");
|
||||
content.Add(new StringContent(request.DocumentationUrl), "field-2");
|
||||
content.Add(new StringContent(request.ImageUrl ?? string.Empty), "field-3");
|
||||
content.Add(new StringContent(request.RequesterName), "field-4");
|
||||
|
||||
_logger.LogInformation(
|
||||
"Submitting indicator request: {IndicatorName} - {Strategy} by {Requester}",
|
||||
request.IndicatorName,
|
||||
request.StrategyDescription,
|
||||
request.RequesterName);
|
||||
|
||||
var response = await httpClient.PostAsync(webhookUrl, content);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"Successfully submitted indicator request: {IndicatorName} by {Requester}",
|
||||
request.IndicatorName,
|
||||
request.RequesterName);
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
Success = true,
|
||||
Message = "Indicator request submitted successfully.",
|
||||
IndicatorName = request.IndicatorName,
|
||||
Strategy = request.StrategyDescription,
|
||||
Requester = request.RequesterName
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
_logger.LogError(
|
||||
"Failed to submit indicator request. Status: {StatusCode}, Response: {Response}",
|
||||
response.StatusCode,
|
||||
responseContent);
|
||||
|
||||
return StatusCode(500, new
|
||||
{
|
||||
Success = false,
|
||||
Error = $"Failed to submit indicator request. Status: {response.StatusCode}"
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error submitting indicator request: {IndicatorName}", request.IndicatorName);
|
||||
return StatusCode(500, new
|
||||
{
|
||||
Success = false,
|
||||
Error = "An error occurred while submitting the indicator request."
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/Managing.Api/Models/Requests/IndicatorRequestDto.cs
Normal file
35
src/Managing.Api/Models/Requests/IndicatorRequestDto.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
#nullable enable
|
||||
|
||||
namespace Managing.Api.Models.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Request model for submitting indicator requests to N8n webhook
|
||||
/// </summary>
|
||||
public class IndicatorRequestDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the indicator (e.g., "MACD", "RSI", "Bollinger Bands")
|
||||
/// </summary>
|
||||
public string IndicatorName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Strategy or description of how the indicator is used (e.g., "MACD Cross", "RSI Divergence")
|
||||
/// </summary>
|
||||
public string StrategyDescription { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Primary documentation URL for the indicator
|
||||
/// </summary>
|
||||
public string DocumentationUrl { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Image URL for the indicator (optional) - can be a chart, diagram, or visual representation
|
||||
/// </summary>
|
||||
public string? ImageUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the person requesting the indicator
|
||||
/// </summary>
|
||||
public string RequesterName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
"RefundEndpoint": "/api/credits/refund"
|
||||
},
|
||||
"N8n": {
|
||||
"WebhookUrl": "https://n8n.kai.managing.live/webhook/fa9308b6-983b-42ec-b085-71599d655951"
|
||||
"WebhookUrl": "https://n8n.kai.managing.live/webhook/fa9308b6-983b-42ec-b085-71599d655951",
|
||||
"IndicatorRequestWebhookUrl": "https://n8n.kai.managing.live/form-test/c7dd294c-004e-4c0f-b4ce-42cc19734e0e"
|
||||
},
|
||||
"Sentry": {
|
||||
"Dsn": "https://fe12add48c56419bbdfa86227c188e7a@glitch.kai.managing.live/1",
|
||||
|
||||
Reference in New Issue
Block a user