Files
pos-system/services/ads-analytics-service-net/src/AdsAnalyticsService.API/Controllers/InsightsController.cs
Ho Ngoc Hai efabe49157 refactor(P2): standardize API responses + fix migrations + cleanup DI
Wave 3 — 3 parallel agents fixing P2 code quality issues:

Response format standardization (30 controllers across 8 services):
- Wrapped all raw DTO returns with { success: true, data: result }
- Standardized error responses with { success: false, error: { code, message } }
- Services: chat, social, membership, ads-manager, ads-serving,
  ads-billing, ads-tracking, ads-analytics
- booking-service already compliant (skipped)

Migration fixes:
- ads-billing: Fixed InvoiceId1 spurious FK (explicit HasMany navigation)
- Removed unused IRequestManager DI from: ads-analytics, ads-serving,
  booking, mkt-facebook (classes preserved for future use)

Unused dependencies:
- No Redis/Dapper DI registrations found (only NuGet refs, kept as-is)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 20:34:10 +07:00

89 lines
3.2 KiB
C#

using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using AdsAnalyticsService.API.Application.DTOs;
namespace AdsAnalyticsService.API.Controllers;
/// <summary>
/// EN: API Controller for insights and recommendations.
/// VI: API Controller insights và khuyến nghị.
/// </summary>
[ApiController]
[Authorize]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/ads-analytics/insights")]
[Produces("application/json")]
public class InsightsController : ControllerBase
{
private readonly ILogger<InsightsController> _logger;
public InsightsController(ILogger<InsightsController> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
/// <summary>
/// EN: Get audience insights.
/// VI: Lấy insights đối tượng.
/// </summary>
[HttpGet("audience")]
[ProducesResponseType(typeof(List<AudienceInsightDto>), StatusCodes.Status200OK)]
public IActionResult GetAudienceInsights(
[FromQuery] Guid? campaignId = null,
[FromQuery] DateTime? startDate = null,
[FromQuery] DateTime? endDate = null)
{
// EN: Return mock audience insights
// VI: Trả về mock audience insights
var insights = new List<AudienceInsightDto>
{
new("25-34", "Female", "Ho Chi Minh City", 15000, 4.5m),
new("25-34", "Male", "Hanoi", 12000, 4.2m),
new("35-44", "Female", "Da Nang", 8000, 3.8m),
new("18-24", "Male", "Ho Chi Minh City", 10000, 5.1m)
};
_logger.LogInformation("Generated audience insights for campaign {CampaignId}", campaignId);
return Ok(new { success = true, data = insights });
}
/// <summary>
/// EN: Get performance insights and recommendations.
/// VI: Lấy insights hiệu suất và khuyến nghị.
/// </summary>
[HttpGet("performance")]
[ProducesResponseType(typeof(List<PerformanceInsightDto>), StatusCodes.Status200OK)]
public IActionResult GetPerformanceInsights([FromQuery] Guid advertiserId)
{
// EN: Return mock performance recommendations
// VI: Trả về mock performance recommendations
var insights = new List<PerformanceInsightDto>
{
new(
Guid.NewGuid(),
"Summer Sale Campaign",
"Low CTR",
"Consider refreshing ad creative. Current CTR (1.2%) is below industry average (2.5%)",
15.5m),
new(
Guid.NewGuid(),
"Brand Awareness Q1",
"High CPA",
"Your cost per acquisition ($25) is high. Try narrowing your audience targeting or adjusting bid strategy",
22.3m),
new(
Guid.NewGuid(),
"Product Launch",
"Budget Underspend",
"Campaign is only spending 60% of daily budget. Consider increasing bids or expanding audience",
18.7m)
};
_logger.LogInformation("Generated performance insights for advertiser {AdvertiserId}", advertiserId);
return Ok(new { success = true, data = insights });
}
}