using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.RateLimiting; namespace TaxBaik.Web.Controllers; [ApiController] [Route("api/client-logs")] [AllowAnonymous] [EnableRateLimiting("client-logs")] public class ClientLogsController(ILogger logger) : ControllerBase { [HttpPost] public IActionResult Post([FromBody] ClientLogEntry entry) { if (string.IsNullOrWhiteSpace(entry.Message)) { return BadRequest(); } logger.LogWarning( "ClientLog {Level} {Source} {Message} Url={Url} Route={Route} Screen={Screen} Feature={Feature} Action={Action} Step={Step} Entity={Entity} EntityId={EntityId} DataKey={DataKey} BuildVersion={BuildVersion} UserAgent={UserAgent} Stack={Stack}", entry.Level ?? "error", entry.Source ?? "unknown", entry.Message, entry.Url ?? string.Empty, entry.Route ?? string.Empty, entry.Screen ?? string.Empty, entry.Feature ?? string.Empty, entry.Action ?? string.Empty, entry.Step ?? string.Empty, entry.Entity ?? string.Empty, entry.EntityId ?? string.Empty, entry.DataKey ?? string.Empty, entry.BuildVersion ?? string.Empty, entry.UserAgent ?? string.Empty, entry.Stack ?? string.Empty); return Ok(); } } public sealed class ClientLogEntry { public string? Level { get; set; } public string? Source { get; set; } public string? Message { get; set; } public string? Url { get; set; } public string? Route { get; set; } public string? Screen { get; set; } public string? Feature { get; set; } public string? Action { get; set; } public string? Step { get; set; } public string? Entity { get; set; } public string? EntityId { get; set; } public string? DataKey { get; set; } public string? BuildVersion { get; set; } public string? UserAgent { get; set; } public string? Stack { get; set; } }