Files
taxbaik/TaxBaik.Web/Services/AdminClients/IConsultingActivityBrowserClient.cs
T
kjh2064 a16438dcc6
TaxBaik CI/CD / build-and-deploy (push) Failing after 27s
feat: Phase 5 Browser Clients and deployment notification strategy
Phase 5: Tax & CRM Browser Clients
- 5 API client interfaces (TaxProfile, Filing, Activity, Contract, Revenue)
- Automatic token refresh for all clients
- Error logging with fallback empty lists
- Program.cs DI registration

Telegram Deployment Notifications:
- System chat (-5585148480): deployment success/failure
- Inquiry chat (-5434691215): customer inquiries
- Login alerts disabled (spam prevention)

Architecture:
Blazor -> BrowserClient (HttpClient+TokenRefresh) -> API -> Services -> DB

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-28 17:26:28 +09:00

107 lines
4.0 KiB
C#

namespace TaxBaik.Web.Services.AdminClients;
using System.Text.Json;
using TaxBaik.Domain.Entities;
public interface IConsultingActivityBrowserClient
{
Task<List<ConsultingActivity>> GetAllAsync(CancellationToken ct = default);
Task<List<ConsultingActivity>> GetByClientIdAsync(int clientId, CancellationToken ct = default);
Task<List<ConsultingActivity>> GetPendingFollowupsAsync(CancellationToken ct = default);
Task<int> CreateAsync(int clientId, string activityType, DateTime activityDate, string description,
int? consultantId = null, DateTime? nextFollowupDate = null, CancellationToken ct = default);
Task UpdateAsync(int id, string? outcome = null, DateTime? nextFollowupDate = null, CancellationToken ct = default);
Task DeleteAsync(int id, CancellationToken ct = default);
}
public class ConsultingActivityBrowserClient(HttpClient httpClient, ILogger<ConsultingActivityBrowserClient> logger)
: IConsultingActivityBrowserClient
{
private const string BaseUrl = "/api/consultingactivity";
public async Task<List<ConsultingActivity>> GetAllAsync(CancellationToken ct = default)
{
try
{
return await httpClient.GetFromJsonAsync<List<ConsultingActivity>>($"{BaseUrl}", ct) ?? [];
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get consulting activities");
return [];
}
}
public async Task<List<ConsultingActivity>> GetByClientIdAsync(int clientId, CancellationToken ct = default)
{
try
{
return await httpClient.GetFromJsonAsync<List<ConsultingActivity>>($"{BaseUrl}/client/{clientId}", ct) ?? [];
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get activities for client {ClientId}", clientId);
return [];
}
}
public async Task<List<ConsultingActivity>> GetPendingFollowupsAsync(CancellationToken ct = default)
{
try
{
var response = await httpClient.GetFromJsonAsync<JsonElement>($"{BaseUrl}/pending-followups", ct);
return response.TryGetProperty("data", out var data) ? System.Text.Json.JsonSerializer.Deserialize<List<ConsultingActivity>>() ?? [];
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get pending followups");
return [];
}
}
public async Task<int> CreateAsync(int clientId, string activityType, DateTime activityDate, string description,
int? consultantId = null, DateTime? nextFollowupDate = null, CancellationToken ct = default)
{
try
{
var request = new { clientId, activityType, activityDate, description, consultantId, nextFollowupDate };
var response = await httpClient.PostAsJsonAsync(BaseUrl, request, ct);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<dynamic>(cancellationToken: ct);
return result?["id"]?.ToObject<int>() ?? 0;
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to create consulting activity");
return 0;
}
}
public async Task UpdateAsync(int id, string? outcome = null, DateTime? nextFollowupDate = null, CancellationToken ct = default)
{
try
{
var request = new { outcome, nextFollowupDate };
var response = await httpClient.PutAsJsonAsync($"{BaseUrl}/{id}", request, ct);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to update consulting activity {Id}", id);
}
}
public async Task DeleteAsync(int id, CancellationToken ct = default)
{
try
{
var response = await httpClient.DeleteAsync($"{BaseUrl}/{id}", ct);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to delete consulting activity {Id}", id);
}
}
}