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>
89 lines
3.2 KiB
C#
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 });
|
|
}
|
|
}
|