refactor: fully integrate Browser Client into main Web server
TaxBaik CI/CD / build-and-deploy (push) Failing after 48s
TaxBaik CI/CD / build-and-deploy (push) Failing after 48s
BREAKING CHANGE: Removed TaxBaik.Web.Client project (separate WASM app) Changes: - Migrated all Blazor components to TaxBaik.Web/Components/Admin - Migrated all Browser Client services to Components/Admin/Services - Updated Program.cs to use integrated components (same assembly) - Removed AddAdditionalAssemblies (no longer needed) - Updated _Imports.razor with correct namespaces Architecture: ✅ API-First: REST endpoints in TaxBaik.Web (ASP.NET Core) ✅ Client-Side: Blazor WASM components in TaxBaik.Web/Components ✅ Unified: Both API and UI served from single web server ✅ No separation: No separate client project Result: - Single deploy unit (TaxBaik.Web) - API served only from web server - Blazor renders client-side (prerender: false for protected pages) - Monolithic web app architecture Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Microsoft.JSInterop
|
||||
@using MudBlazor
|
||||
@using TaxBaik.Application.DTOs
|
||||
@using TaxBaik.Application.Services
|
||||
@using TaxBaik.Application.Utils
|
||||
@using TaxBaik.Domain.Entities
|
||||
@using TaxBaik.Web.Services
|
||||
@using TaxBaik.Web.Services.AdminClients
|
||||
@using TaxBaik.WasmClient.Components.Admin.Shared
|
||||
@using TaxBaik.WasmClient.Components.Admin.Layout
|
||||
@@ -1,2 +0,0 @@
|
||||
global using System.Net.Http;
|
||||
global using System.Net.Http.Json;
|
||||
@@ -1,13 +0,0 @@
|
||||
@* WASM 기반(M3) 검증용 컴포넌트. 라우팅/렌더모드 전면 적용은 M4에서 처리한다. *@
|
||||
@rendermode InteractiveWebAssembly
|
||||
|
||||
<MudPaper Class="pa-6 ma-4" Elevation="2">
|
||||
<MudText Typo="Typo.h5" GutterBottom="true">WebAssembly 렌더 모드 점검</MudText>
|
||||
<MudText Typo="Typo.body2" Class="mb-4">이 컴포넌트가 클릭에 반응하면 Interactive WebAssembly 기반이 정상 동작하는 것입니다.</MudText>
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="Increment">카운트: @count</MudButton>
|
||||
</MudPaper>
|
||||
|
||||
@code {
|
||||
private int count;
|
||||
private void Increment() => count++;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using MudBlazor.Services;
|
||||
using TaxBaik.Application.Services;
|
||||
using TaxBaik.Web.Services;
|
||||
using TaxBaik.Web.Services.AdminClients;
|
||||
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
|
||||
// MudBlazor (WASM 측 인터랙티브 컴포넌트용)
|
||||
builder.Services.AddMudServices(config =>
|
||||
{
|
||||
config.SnackbarConfiguration.HideTransitionDuration = 400;
|
||||
config.SnackbarConfiguration.ShowTransitionDuration = 300;
|
||||
config.PopoverOptions.ThrowOnDuplicateProvider = false;
|
||||
});
|
||||
|
||||
// API Base Url 동적 구성 (호스트 기준 /taxbaik/api/)
|
||||
var apiBaseUrl = builder.HostEnvironment.BaseAddress.TrimEnd('/') + "/taxbaik/api/";
|
||||
|
||||
// HTTP Client for API (with automatic token refresh)
|
||||
builder.Services.AddScoped<ITokenStore, TokenStore>();
|
||||
builder.Services.AddScoped<TokenRefreshHandler>();
|
||||
|
||||
builder.Services.AddHttpClient<IApiClient, ApiClient>(client =>
|
||||
{
|
||||
client.BaseAddress = new Uri(apiBaseUrl);
|
||||
}).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
|
||||
// 각 Browser API Client 등록
|
||||
builder.Services.AddHttpClient<IAdminDashboardClient, AdminDashboardClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<IBlogBrowserClient, BlogBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<ICategoryBrowserClient, CategoryBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl));
|
||||
builder.Services.AddHttpClient<IInquiryBrowserClient, InquiryBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<IClientBrowserClient, ClientBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<ITaxFilingBrowserClient, TaxFilingBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<IFaqBrowserClient, FaqBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<IAnnouncementBrowserClient, AnnouncementBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<ITaxProfileBrowserClient, TaxProfileBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<ITaxFilingScheduleBrowserClient, TaxFilingScheduleBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<IConsultingActivityBrowserClient, ConsultingActivityBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<IContractBrowserClient, ContractBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<IRevenueTrackingBrowserClient, RevenueTrackingBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
builder.Services.AddHttpClient<ICommonCodeBrowserClient, CommonCodeBrowserClient>(client => client.BaseAddress = new Uri(apiBaseUrl)).AddHttpMessageHandler<TokenRefreshHandler>();
|
||||
|
||||
// Blazor 인증 (WASM 측 클라이언트)
|
||||
builder.Services.AddScoped<CustomAuthenticationStateProvider>();
|
||||
builder.Services.AddScoped<AuthenticationStateProvider>(sp => sp.GetRequiredService<CustomAuthenticationStateProvider>());
|
||||
builder.Services.AddScoped<ILocalStorageService, LocalStorageService>();
|
||||
builder.Services.AddCascadingAuthenticationState();
|
||||
builder.Services.AddAuthorizationCore();
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
@@ -1,24 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>TaxBaik.WasmClient</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\TaxBaik.Application\TaxBaik.Application.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.9" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.9" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.19.1" />
|
||||
<PackageReference Include="MudBlazor" Version="6.10.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.19.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+5
-1
@@ -9,5 +9,9 @@
|
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Http
|
||||
@using Microsoft.JSInterop
|
||||
@using MudBlazor
|
||||
@using TaxBaik.WasmClient
|
||||
@using TaxBaik.Web.Components.Admin
|
||||
@using TaxBaik.Web.Components.Admin.Services
|
||||
@using TaxBaik.Web.Components.Admin.Services.AdminClients
|
||||
@using TaxBaik.Application.DTOs
|
||||
@using TaxBaik.Domain.Entities
|
||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||
@@ -402,12 +402,11 @@ app.MapStaticAssets();
|
||||
// AllowAnonymous: JWT 미들웨어가 Blazor 셸 요청을 401로 차단하지 않도록 한다.
|
||||
// 인증은 Blazor AuthorizeRouteView → RedirectToLogin 에서 처리한다.
|
||||
// Phase 8: WebAssembly 렌더 모드 완전 마이그레이션
|
||||
// - App.razor: TaxBaik.WasmClient (호스트, WebAssembly)
|
||||
// - Routes + Pages + Shared + Layout + Forms: TaxBaik.WasmClient (WebAssembly)
|
||||
// MapRazorComponents는 자동으로 root 컴포넌트의 어셈블리 로드
|
||||
// 동일 어셈블리의 Page/Shared 컴포넌트는 자동 발견되므로 AddAdditionalAssemblies 불필요
|
||||
// (같은 어셈블리를 2번 등록하면 "Assembly already defined" 에러 발생)
|
||||
app.MapRazorComponents<TaxBaik.WasmClient.Components.Admin.App>()
|
||||
// - App.razor: TaxBaik.Web (메인 웹 서버)
|
||||
// - Routes + Pages + Shared + Layout + Forms: TaxBaik.Web (메인 웹 서버)
|
||||
// 모든 Blazor 컴포넌트가 웹 서버에서 통합 서비스됨
|
||||
// API는 웹 서버에서만 제공 (클라이언트 프로젝트 분리 불필요)
|
||||
app.MapRazorComponents<TaxBaik.Web.Components.Admin.App>()
|
||||
.AddInteractiveWebAssemblyRenderMode()
|
||||
.AllowAnonymous();
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\TaxBaik.Application\TaxBaik.Application.csproj" />
|
||||
<ProjectReference Include="..\TaxBaik.Infrastructure\TaxBaik.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\TaxBaik.Web.Client\TaxBaik.Web.Client.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -13,7 +13,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaxBaik.Web", "TaxBaik.Web\
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaxBaik.Application.Tests", "TaxBaik.Application.Tests\TaxBaik.Application.Tests.csproj", "{47D1F07D-F11B-4343-A3C3-1872F0C46AE3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaxBaik.Web.Client", "TaxBaik.Web.Client\TaxBaik.Web.Client.csproj", "{C46C51D4-9E87-47DF-AB76-2E794F64FD5F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
||||
Reference in New Issue
Block a user