feat: add Ads Billing Service to docker-compose and implement Admin Campaigns Controller in Ads Manager Service.
This commit is contained in:
@@ -1012,6 +1012,64 @@ services:
|
||||
- "traefik.http.routers.ads-serving-admin.entrypoints=web"
|
||||
- "traefik.http.routers.ads-serving-admin.service=ads-serving-service"
|
||||
|
||||
# Ads Billing Service .NET - Billing, Invoicing & Payment Management
|
||||
ads-billing-service-net:
|
||||
build:
|
||||
context: ../../services/ads-billing-service-net
|
||||
dockerfile: Dockerfile
|
||||
image: goodgo/ads-billing-service-net:latest
|
||||
container_name: ads-billing-service-net-local
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- ASPNETCORE_URLS=http://+:8080
|
||||
# EN: Database - Neon PostgreSQL
|
||||
# VI: Cơ sở dữ liệu - Neon PostgreSQL
|
||||
- ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=ads_billing_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
|
||||
# EN: IAM Service Communication
|
||||
# VI: Giao tiếp IAM Service
|
||||
- IamService__BaseUrl=http://iam-service-net:8080
|
||||
- IamService__ServiceName=ads-billing-service
|
||||
# EN: Wallet Service Communication
|
||||
# VI: Giao tiếp Wallet Service
|
||||
- WalletService__BaseUrl=http://wallet-service-net:8080
|
||||
# EN: JWT Configuration
|
||||
# VI: Cấu hình JWT
|
||||
- Jwt__Authority=http://iam-service-net:8080
|
||||
- Jwt__Audience=goodgo-api
|
||||
- Jwt__RequireHttpsMetadata=false
|
||||
ports:
|
||||
- "5023:8080"
|
||||
depends_on:
|
||||
iam-service-net:
|
||||
condition: service_healthy
|
||||
wallet-service-net:
|
||||
condition: service_healthy
|
||||
traefik:
|
||||
condition: service_started
|
||||
networks:
|
||||
- microservices-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
# EN: Public API routes for billing, invoices, credit lines
|
||||
# VI: Routes API công khai cho billing, hóa đơn, tín dụng
|
||||
- "traefik.http.routers.ads-billing-service.rule=PathPrefix(`/api/v1/ads-billing/accounts`) || PathPrefix(`/api/v1/ads-billing/invoices`) || PathPrefix(`/api/v1/ads-billing/credit-lines`)"
|
||||
- "traefik.http.routers.ads-billing-service.entrypoints=web"
|
||||
- "traefik.http.services.ads-billing-service.loadbalancer.server.port=8080"
|
||||
- "traefik.http.services.ads-billing-service.loadbalancer.healthcheck.path=/health/live"
|
||||
- "traefik.http.services.ads-billing-service.loadbalancer.healthcheck.interval=10s"
|
||||
# EN: Admin API routes for billing management
|
||||
# VI: Routes API Admin để quản lý billing
|
||||
- "traefik.http.routers.ads-billing-admin.rule=PathPrefix(`/api/v1/admin/ads-billing`)"
|
||||
- "traefik.http.routers.ads-billing-admin.entrypoints=web"
|
||||
- "traefik.http.routers.ads-billing-admin.service=ads-billing-service"
|
||||
|
||||
# Jaeger - Distributed Tracing
|
||||
# jaeger:
|
||||
# image: jaegertracing/all-in-one:1.47
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
using AdsManagerService.API.Application.Queries;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AdsManagerService.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// EN: Admin API Controller for campaign management and oversight.
|
||||
/// VI: API Controller Admin cho quản lý và giám sát chiến dịch.
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/v1/admin/ads-manager/campaigns")]
|
||||
[Produces("application/json")]
|
||||
public class AdminCampaignsController : ControllerBase
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
private readonly ILogger<AdminCampaignsController> _logger;
|
||||
|
||||
public AdminCampaignsController(IMediator mediator, ILogger<AdminCampaignsController> logger)
|
||||
{
|
||||
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EN: List all campaigns across all advertisers (Admin only).
|
||||
/// VI: Liệt kê tất cả chiến dịch của tất cả advertisers (Admin only).
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(ListCampaignsResult), StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<ListCampaignsResult>> ListAllCampaigns(
|
||||
[FromQuery] string? status,
|
||||
[FromQuery] int page = 1,
|
||||
[FromQuery] int pageSize = 50)
|
||||
{
|
||||
var query = new ListCampaignsQuery
|
||||
{
|
||||
Status = status,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
|
||||
var result = await _mediator.Send(query);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EN: Get campaign statistics.
|
||||
/// VI: Lấy thống kê chiến dịch.
|
||||
/// </summary>
|
||||
[HttpGet("stats")]
|
||||
[ProducesResponseType(typeof(CampaignStatsDto), StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<CampaignStatsDto>> GetCampaignStats()
|
||||
{
|
||||
var stats = await _mediator.Send(new GetCampaignStatsQuery());
|
||||
return Ok(stats);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EN: Campaign statistics DTO.
|
||||
/// VI: DTO thống kê chiến dịch.
|
||||
/// </summary>
|
||||
public record CampaignStatsDto
|
||||
{
|
||||
public int TotalCampaigns { get; init; }
|
||||
public int ActiveCampaigns { get; init; }
|
||||
public int PausedCampaigns { get; init; }
|
||||
public int DraftCampaigns { get; init; }
|
||||
public int CompletedCampaigns { get; init; }
|
||||
public decimal TotalSpend { get; init; }
|
||||
public decimal TotalBudget { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EN: Query to get campaign statistics.
|
||||
/// VI: Query lấy thống kê chiến dịch.
|
||||
/// </summary>
|
||||
public record GetCampaignStatsQuery : IRequest<CampaignStatsDto>;
|
||||
Reference in New Issue
Block a user