diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml
index d673bb5..ee3136e 100644
--- a/.gitea/workflows/deploy.yml
+++ b/.gitea/workflows/deploy.yml
@@ -33,6 +33,8 @@ jobs:
set -e
mkdir -p ./publish-logs
start=$(date +%s)
+ # Web publish is allowed to build because Blazor/Web SDK publish needs
+ # publish-specific assets even after the solution build has completed.
dotnet publish src/TaxBaik.Web/ \
-c Release \
-o ./publish \
@@ -50,6 +52,8 @@ jobs:
run: |
set -e
mkdir -p ./publish-logs
+ # Proxy is not part of the solution restore graph, so restore it once
+ # here before publishing to avoid NETSDK1004 in CI.
dotnet restore src/TaxBaik.Proxy/
start=$(date +%s)
dotnet publish src/TaxBaik.Proxy/ \
diff --git a/src/TaxBaik.Portal.Client/TaxBaik.Portal.Client.csproj b/src/TaxBaik.Portal.Client/TaxBaik.Portal.Client.csproj
index 170d608..1521aad 100644
--- a/src/TaxBaik.Portal.Client/TaxBaik.Portal.Client.csproj
+++ b/src/TaxBaik.Portal.Client/TaxBaik.Portal.Client.csproj
@@ -11,6 +11,7 @@
+
diff --git a/src/TaxBaik.Portal.Client/_Imports.razor b/src/TaxBaik.Portal.Client/_Imports.razor
index 27e9c7e..ee04635 100644
--- a/src/TaxBaik.Portal.Client/_Imports.razor
+++ b/src/TaxBaik.Portal.Client/_Imports.razor
@@ -9,4 +9,7 @@
@using Microsoft.JSInterop
@using MudBlazor
@using TaxBaik.PortalClient
+@using TaxBaik.WasmClient.Components.Admin
+@using TaxBaik.WasmClient.Components.Admin.Layout
+@using TaxBaik.WasmClient.Components.Admin.Shared
@using static Microsoft.AspNetCore.Components.Web.RenderMode
diff --git a/src/TaxBaik.Web/Program.cs b/src/TaxBaik.Web/Program.cs
index c26b9cb..38ad826 100644
--- a/src/TaxBaik.Web/Program.cs
+++ b/src/TaxBaik.Web/Program.cs
@@ -392,6 +392,12 @@ app.MapHealthChecks("/healthz");
app.MapRazorPages(); // Sitemap.cshtml, Rss.cshtml, Feed.cshtml
app.MapStaticAssets();
+// Blazor WebAssembly Admin Client
+app.MapRazorComponents()
+ .AddInteractiveWebAssemblyRenderMode()
+ .AddAdditionalAssemblies(typeof(TaxBaik.WasmClient._Imports).Assembly)
+ .AllowAnonymous();
+
// SPA 라우팅 폴백 (가장 마지막에!)
app.MapFallbackToFile("admin/{*path:nonfile}", "admin/index.html");