refactor: Phase 7-3 Complete - All Blazor pages API-First migration
TaxBaik CI/CD / build-and-deploy (push) Successful in 3m2s
TaxBaik CI/CD / build-and-deploy (push) Successful in 3m2s
**Blazor Pages Refactored (9 pages):** ✅ ClientList.razor (Service → IClientBrowserClient) ✅ ClientEdit.razor (Service → IClientBrowserClient) ✅ TaxFilingList.razor (Service → ITaxFilingBrowserClient) ✅ FilingTable.razor (Service → ITaxFilingBrowserClient) ✅ FaqList.razor (Service → IFaqBrowserClient) ✅ FaqEdit.razor (Service → IFaqBrowserClient) ✅ AnnouncementList.razor (Service → IAnnouncementBrowserClient) ✅ AnnouncementEdit.razor (Service → IAnnouncementBrowserClient) ✅ Previously: Dashboard, InquiryTable, InquiryDetail **Pattern Applied Consistently:** - Removed all direct service injections (Service Layer) - Injected specialized Browser Clients (API Layer) - Error handling with Snackbar notifications - Try-catch for all API calls - Graceful fallbacks (empty lists on error) **Phase 7 Complete: 100% API-First Refactoring** All admin pages now use: ClientBrowserClient → /api/client (Clients) TaxFilingBrowserClient → /api/tax-filing (Tax Filings) FaqBrowserClient → /api/faq (FAQs) AnnouncementBrowserClient → /api/announcement (Announcements) InquiryBrowserClient → /api/inquiry (Inquiries) AdminDashboardClient → /api/admin-dashboard (Dashboard) **SOLID + Maintainability Achieved:** ✓ Single Responsibility: Each client = one domain ✓ Open/Closed: Extensible without modifying Blazor ✓ Dependency Inversion: Blazor → Abstractions, not services ✓ Interface Segregation: Fine-grained client interfaces ✓ Liskov Substitution: Interchangeable implementations Build: ✅ Success (0 errors) Status: Ready for Phase 6 (SignalR Integration) Next: NotificationHub for real-time dashboard updates Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
@page "/admin/faqs/create"
|
||||
@page "/admin/faqs/{Id:int}/edit"
|
||||
@attribute [Authorize]
|
||||
@using TaxBaik.Application.Services
|
||||
@using TaxBaik.Web.Services
|
||||
@using TaxBaik.Domain.Entities
|
||||
@inject FaqService FaqService
|
||||
@inject IFaqBrowserClient FaqClient
|
||||
@inject NavigationManager Navigation
|
||||
@inject ISnackbar Snackbar
|
||||
|
||||
@@ -89,14 +89,23 @@
|
||||
{
|
||||
if (Id.HasValue)
|
||||
{
|
||||
var existing = await FaqService.GetByIdAsync(Id.Value);
|
||||
if (existing is null)
|
||||
try
|
||||
{
|
||||
Snackbar.Add("FAQ를 찾을 수 없습니다.", Severity.Error);
|
||||
var existing = await FaqClient.GetByIdAsync(Id.Value);
|
||||
if (existing is null)
|
||||
{
|
||||
Snackbar.Add("FAQ를 찾을 수 없습니다.", Severity.Error);
|
||||
Navigation.NavigateTo("/taxbaik/admin/faqs");
|
||||
return;
|
||||
}
|
||||
faq = existing;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"오류: {ex.Message}", Severity.Error);
|
||||
Navigation.NavigateTo("/taxbaik/admin/faqs");
|
||||
return;
|
||||
}
|
||||
faq = existing;
|
||||
}
|
||||
isLoading = false;
|
||||
}
|
||||
@@ -111,13 +120,19 @@
|
||||
{
|
||||
if (Id.HasValue)
|
||||
{
|
||||
await FaqService.UpdateAsync(faq);
|
||||
Snackbar.Add("FAQ가 수정되었습니다.", Severity.Success);
|
||||
var result = await FaqClient.UpdateAsync(Id.Value, faq);
|
||||
if (result != null)
|
||||
Snackbar.Add("FAQ가 수정되었습니다.", Severity.Success);
|
||||
else
|
||||
Snackbar.Add("수정 실패", Severity.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
await FaqService.CreateAsync(faq);
|
||||
Snackbar.Add("FAQ가 등록되었습니다.", Severity.Success);
|
||||
var result = await FaqClient.CreateAsync(faq);
|
||||
if (result != null)
|
||||
Snackbar.Add("FAQ가 등록되었습니다.", Severity.Success);
|
||||
else
|
||||
Snackbar.Add("등록 실패", Severity.Error);
|
||||
}
|
||||
Navigation.NavigateTo("/taxbaik/admin/faqs");
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@page "/admin/faqs"
|
||||
@attribute [Authorize]
|
||||
@using TaxBaik.Application.Services
|
||||
@using TaxBaik.Web.Services
|
||||
@using TaxBaik.Domain.Entities
|
||||
@inject FaqService FaqService
|
||||
@inject IFaqBrowserClient FaqClient
|
||||
@inject NavigationManager Navigation
|
||||
@inject IDialogService DialogService
|
||||
@inject ISnackbar Snackbar
|
||||
@@ -101,7 +101,15 @@
|
||||
|
||||
private async Task LoadAsync()
|
||||
{
|
||||
faqs = (await FaqService.GetAllAsync()).ToList();
|
||||
try
|
||||
{
|
||||
faqs = (await FaqClient.GetAllAsync()).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"오류: {ex.Message}", Severity.Error);
|
||||
faqs = [];
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteAsync(Faq item)
|
||||
@@ -113,8 +121,22 @@
|
||||
|
||||
if (confirmed != true) return;
|
||||
|
||||
await FaqService.DeleteAsync(item.Id);
|
||||
Snackbar.Add("FAQ가 삭제되었습니다.", Severity.Success);
|
||||
await LoadAsync();
|
||||
try
|
||||
{
|
||||
var success = await FaqClient.DeleteAsync(item.Id);
|
||||
if (success)
|
||||
{
|
||||
Snackbar.Add("FAQ가 삭제되었습니다.", Severity.Success);
|
||||
await LoadAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
Snackbar.Add("삭제 실패", Severity.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"오류: {ex.Message}", Severity.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user