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.AspNetCore.Components.WebAssembly.Http
|
||||||
@using Microsoft.JSInterop
|
@using Microsoft.JSInterop
|
||||||
@using MudBlazor
|
@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
|
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||||
@@ -402,12 +402,11 @@ app.MapStaticAssets();
|
|||||||
// AllowAnonymous: JWT 미들웨어가 Blazor 셸 요청을 401로 차단하지 않도록 한다.
|
// AllowAnonymous: JWT 미들웨어가 Blazor 셸 요청을 401로 차단하지 않도록 한다.
|
||||||
// 인증은 Blazor AuthorizeRouteView → RedirectToLogin 에서 처리한다.
|
// 인증은 Blazor AuthorizeRouteView → RedirectToLogin 에서 처리한다.
|
||||||
// Phase 8: WebAssembly 렌더 모드 완전 마이그레이션
|
// Phase 8: WebAssembly 렌더 모드 완전 마이그레이션
|
||||||
// - App.razor: TaxBaik.WasmClient (호스트, WebAssembly)
|
// - App.razor: TaxBaik.Web (메인 웹 서버)
|
||||||
// - Routes + Pages + Shared + Layout + Forms: TaxBaik.WasmClient (WebAssembly)
|
// - Routes + Pages + Shared + Layout + Forms: TaxBaik.Web (메인 웹 서버)
|
||||||
// MapRazorComponents는 자동으로 root 컴포넌트의 어셈블리 로드
|
// 모든 Blazor 컴포넌트가 웹 서버에서 통합 서비스됨
|
||||||
// 동일 어셈블리의 Page/Shared 컴포넌트는 자동 발견되므로 AddAdditionalAssemblies 불필요
|
// API는 웹 서버에서만 제공 (클라이언트 프로젝트 분리 불필요)
|
||||||
// (같은 어셈블리를 2번 등록하면 "Assembly already defined" 에러 발생)
|
app.MapRazorComponents<TaxBaik.Web.Components.Admin.App>()
|
||||||
app.MapRazorComponents<TaxBaik.WasmClient.Components.Admin.App>()
|
|
||||||
.AddInteractiveWebAssemblyRenderMode()
|
.AddInteractiveWebAssemblyRenderMode()
|
||||||
.AllowAnonymous();
|
.AllowAnonymous();
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\TaxBaik.Application\TaxBaik.Application.csproj" />
|
<ProjectReference Include="..\TaxBaik.Application\TaxBaik.Application.csproj" />
|
||||||
<ProjectReference Include="..\TaxBaik.Infrastructure\TaxBaik.Infrastructure.csproj" />
|
<ProjectReference Include="..\TaxBaik.Infrastructure\TaxBaik.Infrastructure.csproj" />
|
||||||
<ProjectReference Include="..\TaxBaik.Web.Client\TaxBaik.Web.Client.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaxBaik.Web", "TaxBaik.Web\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaxBaik.Application.Tests", "TaxBaik.Application.Tests\TaxBaik.Application.Tests.csproj", "{47D1F07D-F11B-4343-A3C3-1872F0C46AE3}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaxBaik.Application.Tests", "TaxBaik.Application.Tests\TaxBaik.Application.Tests.csproj", "{47D1F07D-F11B-4343-A3C3-1872F0C46AE3}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaxBaik.Web.Client", "TaxBaik.Web.Client\TaxBaik.Web.Client.csproj", "{C46C51D4-9E87-47DF-AB76-2E794F64FD5F}"
|
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Reference in New Issue
Block a user