Add indicators request endpoint

This commit is contained in:
2025-10-28 17:37:07 +07:00
parent 5cef270d64
commit 9d586974e2
3 changed files with 151 additions and 3 deletions

View File

@@ -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."
});
}
}
}

View 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;
}

View File

@@ -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",