using Gateway.Security; using Gateway.Services; using Microsoft.AspNetCore.Mvc; namespace Gateway.Controllers; /// /// Metric sync trigger — called by Management API or Azure Functions timer. /// Pulls campaign performance data from provider containers and writes /// it into the database, then triggers recommendation evaluation. /// Secured by internal service key (X-Service-Key header). /// [ApiController] [Route("api/sync")] public sealed class MetricSyncController : ControllerBase { private readonly MetricSyncService _sync; private readonly AuthorizationGuard _guard; private readonly ILogger _log; public MetricSyncController( MetricSyncService sync, AuthorizationGuard guard, ILogger log) { _sync = sync; _guard = guard; _log = log; } /// /// Sync metrics for a specific client. /// Pulls from all active channel campaign providers, writes to DB, /// then triggers recommendation evaluation. /// [HttpPost("metrics/{clientId}")] public async Task SyncClient( string clientId, [FromQuery] string? startDate, [FromQuery] string? endDate, CancellationToken ct) { var (ok, err) = _guard.RequireServiceKey(); if (!ok) return StatusCode(403, new { ok = false, error = err }); _log.LogInformation("[MetricSync] Manual sync triggered for client {ClientId}", clientId); var result = await _sync.SyncClientMetricsAsync(clientId, startDate, endDate, ct); return Ok(new { ok = result.Success, clientId = result.ClientId, campaignsProcessed = result.CampaignsProcessed, metricsWritten = result.MetricsWritten, recommendationsGenerated = result.RecommendationsGenerated, skipped = result.Skipped, errors = result.Errors, error = result.Error }); } }