Files
taxbaik/TaxBaik.Web.Client/Components/Admin/Shared/AdminTelemetryContext.razor
T
kjh2064 8202c3278b
TaxBaik CI/CD / build-and-deploy (push) Failing after 2m17s
refactor: complete WebAssembly migration - proper architecture
Phase 8: Complete WebAssembly 렌더 모드 전환 (정공법)

Migration Summary:
- ALL Admin components → TaxBaik.Web.Client
- Routes.razor, Pages/*, Layout/*, Shared/*, Forms/*
- App.razor → TaxBaik.WasmClient (호스트 컴포넌트)
- Shared utilities → TaxBaik.Application.Utils

Architecture:
 App.razor: TaxBaik.WasmClient (WebAssembly, 호스트)
 Routes + Pages: TaxBaik.WasmClient (WebAssembly)
 Layout + Shared + Forms: TaxBaik.WasmClient (WebAssembly)
 Services: TaxBaik.Web (API-First)

Key Changes:
- Namespaces: TaxBaik.Web.Components.Admin → TaxBaik.WasmClient.Components.Admin
- Shared utilities: TaxBaik.Application.Utils (single source of truth)
- Program.cs: MapRazorComponents<TaxBaik.WasmClient.Components.Admin.App>()
- _Imports.razor: Components/Admin 폴더에 재구성

Build Status:  0 errors, 0 warnings

Benefits:
- Stateless server (no Circuit memory)
- Client-side rendering (WebAssembly)
- Unlimited concurrent users (horizontal scaling)
- ERP-ready architecture

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-03 01:03:51 +09:00

108 lines
6.3 KiB
Plaintext

@using System.Text.RegularExpressions
@inject IJSRuntime Js
@inject NavigationManager Navigation
@code {
[Parameter] public string Screen { get; set; } = "";
[Parameter] public string Feature { get; set; } = "";
[Parameter] public string Action { get; set; } = "";
[Parameter] public string Step { get; set; } = "";
[Parameter] public string Entity { get; set; } = "";
[Parameter] public string EntityId { get; set; } = "";
[Parameter] public string DataKey { get; set; } = "";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
try
{
var route = GetRoute();
var context = ResolveContext(route);
await Js.InvokeVoidAsync("taxbaikAdminSession.setContext",
string.IsNullOrWhiteSpace(Screen) ? context.Screen : Screen,
string.IsNullOrWhiteSpace(Feature) ? context.Feature : Feature,
string.IsNullOrWhiteSpace(Action) ? context.Action : Action,
string.IsNullOrWhiteSpace(Step) ? context.Step : Step,
string.IsNullOrWhiteSpace(Entity) ? context.Entity : Entity,
string.IsNullOrWhiteSpace(EntityId) ? context.EntityId : EntityId,
string.IsNullOrWhiteSpace(DataKey) ? context.DataKey : DataKey);
}
catch
{
// telemetry must never block rendering
}
}
}
private string GetRoute()
{
var path = Navigation.ToBaseRelativePath(Navigation.Uri);
return string.IsNullOrWhiteSpace(path) ? "/" : "/" + path.TrimStart('/');
}
private static (string Screen, string Feature, string Action, string Step, string Entity, string EntityId, string DataKey) ResolveContext(string route)
=> route.ToLowerInvariant() switch
{
"/" => ("admin/index", "shell", "load", "index", "admin", "", "index"),
"/admin/login" => ("admin/login", "auth", "render", "login page", "auth", "", "login"),
"/admin/dashboard" => ("admin/dashboard", "dashboard", "load", "summary", "dashboard", "", "summary"),
"/admin/common-codes" => ("admin/common-codes", "common-code", "load", "group list", "common_code", "", "group"),
"/admin/blog" => ("admin/blog", "content", "load", "list", "blog", "", "list"),
"/admin/blog/create" => ("admin/blog/create", "content", "create", "form", "blog", "", "create"),
"/admin/blog/0/edit" => ("admin/blog/edit", "content", "edit", "form", "blog", "0", "edit"),
"/admin/inquiries" => ("admin/inquiries", "customer-request", "load", "list", "inquiry", "", "list"),
"/admin/inquiries/create" => ("admin/inquiries/create", "customer-request", "create", "form", "inquiry", "", "create"),
"/admin/settings" => ("admin/settings", "system", "load", "settings", "site_setting", "", "settings"),
"/admin/announcements" => ("admin/announcements", "content", "load", "list", "announcement", "", "list"),
"/admin/announcements/create" => ("admin/announcements/create", "content", "create", "form", "announcement", "", "create"),
"/admin/companies" => ("admin/companies", "company", "load", "list", "company", "", "list"),
"/admin/faqs" => ("admin/faqs", "faq", "load", "list", "faq", "", "list"),
"/admin/tax-profiles" => ("admin/tax-profiles", "tax-profile", "load", "list", "tax_profile", "", "list"),
"/admin/tax-filing-schedules" => ("admin/tax-filing-schedules", "schedule", "load", "list", "tax_filing_schedule", "", "list"),
"/admin/contracts" => ("admin/contracts", "crm", "load", "list", "contract", "", "list"),
"/admin/consulting-activities" => ("admin/consulting-activities", "crm", "load", "list", "consulting_activity", "", "list"),
"/admin/revenue-trackings" => ("admin/revenue-trackings", "crm", "load", "list", "revenue_tracking", "", "list"),
"/admin/clients" => ("admin/clients", "customer", "load", "list", "client", "", "list"),
"/admin/tax-filings" => ("admin/tax-filings", "tax-filing", "load", "list", "tax_filing", "", "list"),
"/admin/season-simulator" => ("admin/season-simulator", "schedule", "load", "simulator", "season", "", "simulator"),
_ => ResolveDynamicContext(route)
};
private static (string Screen, string Feature, string Action, string Step, string Entity, string EntityId, string DataKey) ResolveDynamicContext(string route)
{
var normalized = route.ToLowerInvariant().TrimEnd('/');
foreach (var pattern in new[]
{
("/admin/blog/", "admin/blog/edit", "content", "edit", "form", "blog", "edit"),
("/admin/announcements/", "admin/announcements/edit", "content", "edit", "form", "announcement", "edit"),
("/admin/inquiries/", "admin/inquiries/edit", "customer-request", "edit", "form", "inquiry", "edit"),
("/admin/clients/", "admin/clients/detail", "customer", "view", "detail", "client", "detail"),
("/admin/companies/", "admin/companies/edit", "company", "edit", "form", "company", "edit"),
("/admin/faqs/", "admin/faqs/edit", "faq", "edit", "form", "faq", "edit"),
("/admin/tax-profiles/", "admin/tax-profiles/edit", "tax-profile", "edit", "form", "tax_profile", "edit"),
("/admin/tax-filing-schedules/", "admin/tax-filing-schedules/edit", "schedule", "edit", "form", "tax_filing_schedule", "edit"),
})
{
if (!normalized.StartsWith(pattern.Item1, StringComparison.OrdinalIgnoreCase))
continue;
var remainder = normalized[pattern.Item1.Length..].Trim('/');
var id = ExtractLeadingId(remainder);
if (string.IsNullOrWhiteSpace(id))
id = remainder.Split('/', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() ?? "";
return (pattern.Item2, pattern.Item3, pattern.Item4, pattern.Item5, pattern.Item6, id, pattern.Item7);
}
return (route.Trim('/'), "admin", "load", "view", "admin", "", route.Trim('/'));
}
private static string ExtractLeadingId(string value)
{
var match = Regex.Match(value, @"^\d+");
return match.Success ? match.Value : "";
}
}