using AutomationBLL.EventDispatch; using Dapr; using GB5Shared.DTO.Framework.Login; using Microsoft.AspNetCore.Mvc; namespace AutomationSL.Subscriptions; // Bidirectional flow, inbound side: business modules publish these events when the corresponding // GB5 action completes (order accepted, ASN created, invoice posted); AutomationHub reacts by // dispatching the mapped outbound-upload script (see EventDispatchBLL for sequencing/idempotency). // // Topic names below are placeholders (AutomationHub-side names), modeled on the friendly-string // topic convention proven by ComplianceSL/Subscriptions/InvoicePostedSubscriber.cs // ("compliance.invoice.posted") — NOT GB5's numeric "EVENTTYPEID:{id}" IOutBox convention, since // that requires MEVENTTYPE rows to be seeded first and no live DB was reachable in this session to // do that. Before wiring a real publisher, confirm with that module's owner whether it already // publishes on an existing topic (reuse that name here) or needs a new one added. [ApiController] public class AutomationBusinessEventSubscriber : ControllerBase { private readonly IEventDispatchBLL _dispatchBll; private readonly ILogger _logger; public AutomationBusinessEventSubscriber(IEventDispatchBLL dispatchBll, ILogger logger) { _dispatchBll = dispatchBll; _logger = logger; } public record BusinessEventDTO(string OrderId, int TenantId, int? CustomerId, string? PayloadJson); [Topic("pubsub", "automation.order.accepted")] [HttpPost("/Automation/Subscriptions/OrderAccepted")] public Task HandleOrderAccepted([FromBody] BusinessEventDTO evt, CancellationToken ct) => Handle("ORDER_ACCEPTED", evt, ct); [Topic("pubsub", "automation.asn.created")] [HttpPost("/Automation/Subscriptions/AsnCreated")] public Task HandleAsnCreated([FromBody] BusinessEventDTO evt, CancellationToken ct) => Handle("ASN_CREATED", evt, ct); [Topic("pubsub", "automation.invoice.posted")] [HttpPost("/Automation/Subscriptions/InvoicePosted")] public Task HandleInvoicePosted([FromBody] BusinessEventDTO evt, CancellationToken ct) => Handle("INVOICE_POSTED", evt, ct); private async Task Handle(string eventType, BusinessEventDTO evt, CancellationToken ct) { _logger.LogInformation("Business event received: {EventType} OrderId {OrderId} TenantId {TenantId}", eventType, evt.OrderId, evt.TenantId); try { var login = new LoginDTO { ClientId = evt.TenantId, UserId = 0 }; var result = await _dispatchBll.HandleInboundEvent(eventType, evt.OrderId, evt.CustomerId, evt.PayloadJson, login, ct) .ConfigureAwait(false); _logger.LogInformation("{EventType} for OrderId {OrderId} result: {Result}", eventType, evt.OrderId, result); return Ok(new { Result = result }); } catch (Exception ex) { _logger.LogError(ex, "Failed to process {EventType} for OrderId {OrderId}", eventType, evt.OrderId); return StatusCode(500, ex.Message); } } }