feat(ops): 배포 알림과 텔레그램 리포트 추가

This commit is contained in:
2026-06-28 18:39:28 +09:00
parent d2cfcd90f0
commit 033883aac5
10 changed files with 333 additions and 4 deletions
@@ -25,6 +25,8 @@ public static class DependencyInjection
services.AddScoped<ConsultingActivityService>();
services.AddScoped<ContractService>();
services.AddScoped<RevenueTrackingService>();
services.AddScoped<TelegramReportService>();
services.AddScoped<PortalUserService>();
return services;
}
}
@@ -22,6 +22,15 @@ public class ClientService(IClientRepository repository)
public async Task<Client?> GetByIdAsync(int id, CancellationToken ct = default) =>
await repository.GetByIdAsync(id, ct);
public async Task<Client?> GetByEmailAsync(string email, CancellationToken ct = default) =>
await repository.GetByEmailAsync(email, ct);
public async Task<Client?> GetByPhoneAsync(string phone, CancellationToken ct = default) =>
await repository.GetByPhoneAsync(phone, ct);
public async Task<int> CountCreatedAtRangeAsync(DateTime startDateUtc, DateTime endDateUtc, CancellationToken ct = default) =>
await repository.CountByCreatedAtRangeAsync(startDateUtc, endDateUtc, ct);
public async Task<int> CreateAsync(CreateClientDto dto, CancellationToken ct = default)
{
if (string.IsNullOrWhiteSpace(dto.Name))
@@ -0,0 +1,74 @@
namespace TaxBaik.Application.Services;
public record TelegramDailyReport(
DateOnly Date,
int NewInquiries,
int PendingInquiries,
int NewClients,
int PendingTaxFilings,
int PendingPayments);
public record TelegramWeeklyReport(
DateOnly WeekStart,
DateOnly WeekEnd,
int NewInquiries,
int NewClients,
int UpcomingTaxFilings,
decimal RevenueThisWeek);
public class TelegramReportService(
InquiryService inquiryService,
ClientService clientService,
TaxFilingScheduleService taxFilingScheduleService,
RevenueTrackingService revenueTrackingService)
{
public async Task<TelegramDailyReport> BuildDailyReportAsync(DateOnly date, CancellationToken ct = default)
{
var start = date.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
var end = date.ToDateTime(TimeOnly.MaxValue, DateTimeKind.Utc);
return new TelegramDailyReport(
Date: date,
NewInquiries: await inquiryService.CountByDateRangeAsync(start, end, ct),
PendingInquiries: await inquiryService.CountByStatusAsync("new", ct),
NewClients: await clientService.CountCreatedAtRangeAsync(start, end, ct),
PendingTaxFilings: await taxFilingScheduleService.GetPendingCountAsync(ct),
PendingPayments: (await revenueTrackingService.GetPendingPaymentsAsync(ct)).Count());
}
public async Task<TelegramWeeklyReport> BuildWeeklyReportAsync(DateOnly weekStart, CancellationToken ct = default)
{
var weekEnd = weekStart.AddDays(6);
var start = weekStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
var end = weekEnd.ToDateTime(TimeOnly.MaxValue, DateTimeKind.Utc);
var upcomingEnd = weekEnd.AddDays(7).ToDateTime(TimeOnly.MaxValue, DateTimeKind.Utc);
var revenue = await revenueTrackingService.GetTotalRevenueAsync(start, end, ct);
return new TelegramWeeklyReport(
WeekStart: weekStart,
WeekEnd: weekEnd,
NewInquiries: await inquiryService.CountByDateRangeAsync(start, end, ct),
NewClients: await clientService.CountCreatedAtRangeAsync(start, end, ct),
UpcomingTaxFilings: (await taxFilingScheduleService.GetUpcomingDuesAsync(14, ct))
.Count(x => x.DueDate >= start && x.DueDate <= upcomingEnd),
RevenueThisWeek: revenue);
}
public static string FormatDailyMessage(TelegramDailyReport report) =>
$"<b>📊 일간 리포트</b>\n\n" +
$"기준일: <code>{report.Date:yyyy-MM-dd}</code>\n" +
$"신규 문의: <code>{report.NewInquiries}</code>\n" +
$"처리 대기 문의: <code>{report.PendingInquiries}</code>\n" +
$"신규 고객: <code>{report.NewClients}</code>\n" +
$"신고 대기: <code>{report.PendingTaxFilings}</code>\n" +
$"미수 청구: <code>{report.PendingPayments}</code>";
public static string FormatWeeklyMessage(TelegramWeeklyReport report) =>
$"<b>📈 주간 리포트</b>\n\n" +
$"기간: <code>{report.WeekStart:yyyy-MM-dd}</code> ~ <code>{report.WeekEnd:yyyy-MM-dd}</code>\n" +
$"신규 문의: <code>{report.NewInquiries}</code>\n" +
$"신규 고객: <code>{report.NewClients}</code>\n" +
$"다가오는 신고: <code>{report.UpcomingTaxFilings}</code>\n" +
$"주간 매출: <code>₩{report.RevenueThisWeek:N0}</code>";
}