diff --git a/CLAUDE.md b/CLAUDE.md index 3dddbaf..a9fcc7a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -134,7 +134,24 @@ export DOTNET_PRINT_TELEMETRY_MESSAGE=false **완료**: 2026-07-03 / WebAssembly 기반 아키텍처 확정 + 프로덕션 검증 -**현재 상태**: **✅ Phase 1-8 COMPLETE & VERIFIED (2026-07-03)** +**⚠️ Phase 8 알려진 한계 (Phase 9에서 수정됨)**: +Phase 8에서는 ``(App.razor)와 ``(Routes.razor)에 전역 `@rendermode`를 지정해 `prerender: false`로 고정했다. 그 결과 로그인 화면을 포함한 모든 어드민 페이지가 WASM 다운로드 완료 전까지 빈 화면/스피너만 보여주는 문제가 있었다(`scripts/validate_admin_render.sh`에 이 트레이드오프가 "기능 우선, 흰 화면 0.5~2초 감수"로 기록되어 있었음). 이는 `docs/ENGINEERING_HARNESS.md`의 "로그인 화면은 예외적으로 서버 프리렌더 허용" 규칙을 충족하지 못한 상태였다. Phase 9에서 페이지별 개별 렌더모드 지정으로 교체했다. + +#### Phase 9: 어드민 페이지별 렌더모드 정상화 ✅ (2026-07-03) +- [x] `App.razor`/`Routes.razor`에서 전역 `@rendermode` 제거 (Router/Routes 자체는 렌더모드를 강제하지 않음) +- [x] `Login.razor`만 `@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true))`로 명시 → 로그인 폼이 최초 HTML 응답에 정적으로 포함되어 WASM 다운로드 중에도 즉시 표시됨 +- [x] 나머지 `[Authorize]` 어드민 페이지는 `@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false))`로 명시 유지 → 인증 컨텍스트 없이 prerender될 때 `AuthorizeRouteView`가 빈 화면을 그리는 문제(Phase 8 초기에 겪었던 문제) 재발 방지 +- [x] WASM 부팅 완료 전 로그인 버튼은 "준비 중" 비활성 상태로 표시, 부팅 완료 시 정상 상태로 전환(업데이트 스플래시) + +**핵심 원칙**: Blazor Web App은 "전역 렌더모드" 또는 "페이지별 렌더모드" 중 하나만 선택할 수 있다. Router/Routes에 렌더모드를 지정하면 그 하위 모든 페이지의 개별 `@rendermode` 지시자는 무시된다. 로그인만 예외적으로 prerender가 필요하므로 전역 방식을 버리고 페이지별 방식으로 전환했다. + +**완료**: 2026-07-03 / 로그인 흰 화면 제거 + 인증 페이지 안정성 유지 + +**보류된 결정 (2026-07-03, 향후 별도 Phase)**: +- 공개 홈페이지 Razor Pages → MVC(Controller+View) 전면 재작성: 기능적 이득 없이 운영 중인 SEO 트래픽 페이지 전체를 기계적으로 재작성하는 고비용 작업이라 이번엔 보류. 필요 시 Phase 10으로 별도 진행. +- 포털(고객용, `Pages/Portal/*`, 현재 Razor Pages + 쿠키/OAuth) → 어드민과 동일한 MudBlazor+WASM 전환: 완전히 새로운 프로젝트 구조가 필요해 이번 범위에서 제외. 필요 시 Phase 11로 별도 진행. + +**현재 상태**: **✅ Phase 1-9 COMPLETE & VERIFIED (2026-07-03)** - ✅ 모든 API 엔드포인트 구현됨 - ✅ 모든 Browser Client 구현됨 - ✅ 16개 Blazor 페이지 API-First 마이그레이션 완료 @@ -2035,7 +2052,7 @@ else | 항목 | 이전 | 현재 | 개선 | |------|------|------|------| -| **Blazor 프리렌더링** | `prerender: false` | `prerender: true` | 흰 화면 제거 | +| **Blazor 프리렌더링** | 전역 `prerender: false` (로그인 포함 전체 흰 화면) | 페이지별 지정 (로그인만 `prerender: true`, 나머지 `false`) | 로그인 흰 화면 제거, 인증 페이지는 그대로 안정 | | **배포 헬스 체크** | 40 × 3초 = 120초 | 20 × 3초 = 60초 | -50% | | **E2E 배포 대기** | 30 × 5초 = 150초 | 20 × 3초 = 60초 | -60% | | **Playwright 병렬** | `fullyParallel: false` | CI에서 `true` | 테스트 병렬화 | diff --git a/TaxBaik.Web.Client/Components/Admin/App.razor b/TaxBaik.Web.Client/Components/Admin/App.razor index 6a64f6a..dcf43a8 100644 --- a/TaxBaik.Web.Client/Components/Admin/App.razor +++ b/TaxBaik.Web.Client/Components/Admin/App.razor @@ -35,8 +35,17 @@

로드 중...

+ - + diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/AdminIndex.razor b/TaxBaik.Web.Client/Components/Admin/Pages/AdminIndex.razor index 8123051..8a84080 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/AdminIndex.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/AdminIndex.razor @@ -1,5 +1,5 @@ @page "/admin" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @inject NavigationManager NavigationManager diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementEdit.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementEdit.razor index 99448b5..eb8d857 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementEdit.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementEdit.razor @@ -1,6 +1,6 @@ @page "/admin/announcements/create" @page "/admin/announcements/{Id:int}/edit" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.Web.Services diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementList.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementList.razor index 55b45eb..a8ba06a 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementList.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Announcements/AnnouncementList.razor @@ -1,5 +1,5 @@ @page "/admin/announcements" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogCreate.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogCreate.razor index f3c0f28..3934604 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogCreate.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogCreate.razor @@ -1,5 +1,5 @@ @page "/admin/blog/create" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.WasmClient.Components.Admin.Pages.Blog diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogEdit.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogEdit.razor index b2ea86e..835e38f 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogEdit.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogEdit.razor @@ -1,5 +1,5 @@ @page "/admin/blog/{id:int}/edit" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.WasmClient.Components.Admin.Pages.Blog diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogList.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogList.razor index 599aa24..6dad24b 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogList.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Blog/BlogList.razor @@ -1,5 +1,5 @@ @page "/admin/blog" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @inject IBlogBrowserClient BlogClient @inject ISnackbar Snackbar diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientDetail.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientDetail.razor index fcc0fe8..63e87c1 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientDetail.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientDetail.razor @@ -1,5 +1,5 @@ @page "/admin/clients/{ClientId:int}" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Web.Services.AdminClients diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientEdit.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientEdit.razor index b4558b5..9859fc7 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientEdit.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientEdit.razor @@ -1,6 +1,6 @@ @page "/admin/clients/create" @page "/admin/clients/{Id:int}/edit" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.Web.Services diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientList.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientList.razor index 5231a5c..e9e2f34 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientList.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Clients/ClientList.razor @@ -1,5 +1,5 @@ @page "/admin/clients" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/CommonCodes.razor b/TaxBaik.Web.Client/Components/Admin/Pages/CommonCodes.razor index 647e5bc..d7b70e5 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/CommonCodes.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/CommonCodes.razor @@ -1,5 +1,5 @@ @page "/admin/common-codes" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.Domain.Entities @attribute [Authorize] diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyCreate.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyCreate.razor index c4e7b91..7ce8f25 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyCreate.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyCreate.razor @@ -1,5 +1,5 @@ @page "/admin/companies/create" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.WasmClient.Components.Admin.Forms @inject IApiClient ApiClient diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyEdit.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyEdit.razor index 61323b5..24165c1 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyEdit.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyEdit.razor @@ -1,5 +1,5 @@ @page "/admin/companies/{id:int}/edit" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.WasmClient.Components.Admin.Forms @inject IApiClient ApiClient diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyList.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyList.razor index 8703bb2..18d14ae 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyList.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Companies/CompanyList.razor @@ -1,5 +1,5 @@ @page "/admin/companies" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @inject IApiClient ApiClient @inject ISnackbar Snackbar diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/ConsultingActivities.razor b/TaxBaik.Web.Client/Components/Admin/Pages/ConsultingActivities.razor index 7a4092f..36de9f8 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/ConsultingActivities.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/ConsultingActivities.razor @@ -1,5 +1,5 @@ @page "/admin/consulting-activities" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.WasmClient.Components.Admin.Shared @inject IConsultingActivityBrowserClient ActivityClient diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Contracts.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Contracts.razor index 096645d..994132e 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Contracts.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Contracts.razor @@ -1,5 +1,5 @@ @page "/admin/contracts" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.WasmClient.Components.Admin.Shared @inject IContractBrowserClient ContractClient diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Dashboard.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Dashboard.razor index 97965ba..e1b30b5 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Dashboard.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Dashboard.razor @@ -1,5 +1,5 @@ @page "/admin/dashboard" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.WasmClient.Components.Admin.Shared diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqEdit.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqEdit.razor index d281b40..fbf8a92 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqEdit.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqEdit.razor @@ -1,6 +1,6 @@ @page "/admin/faqs/create" @page "/admin/faqs/{Id:int}/edit" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqList.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqList.razor index b591d12..3e44bf9 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqList.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Faqs/FaqList.razor @@ -1,5 +1,5 @@ @page "/admin/faqs" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryCreate.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryCreate.razor index 9c8340e..beb8e52 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryCreate.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryCreate.razor @@ -1,5 +1,5 @@ @page "/admin/inquiries/create" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.WasmClient.Components.Admin.Forms diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryDetail.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryDetail.razor index 8737728..e6df5f3 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryDetail.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryDetail.razor @@ -1,5 +1,5 @@ @page "/admin/inquiries/{InquiryId:int}" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @inject IInquiryBrowserClient InquiryClient diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryEdit.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryEdit.razor index b1b3659..c109f97 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryEdit.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryEdit.razor @@ -1,5 +1,5 @@ @page "/admin/inquiries/{id:int}/edit" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.DTOs @using TaxBaik.WasmClient.Components.Admin.Forms diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryList.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryList.razor index 1ab790a..449d916 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryList.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Inquiries/InquiryList.razor @@ -1,5 +1,5 @@ @page "/admin/inquiries" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @inject IInquiryBrowserClient InquiryClient diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Login.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Login.razor index d8fb883..1524f6c 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Login.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Login.razor @@ -1,6 +1,6 @@ @page "/admin/login" @layout TaxBaik.WasmClient.Components.Admin.Layout.BlankLayout @attribute [AllowAnonymous] -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: true)) 로그인 diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Logout.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Logout.razor index be70c4f..24b6566 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Logout.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Logout.razor @@ -1,5 +1,5 @@ @page "/admin/logout" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services @inject CustomAuthenticationStateProvider AuthStateProvider @inject NavigationManager NavigationManager diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/RevenueTrackings.razor b/TaxBaik.Web.Client/Components/Admin/Pages/RevenueTrackings.razor index 4ec1c6a..45958ae 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/RevenueTrackings.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/RevenueTrackings.razor @@ -1,5 +1,5 @@ @page "/admin/revenue-trackings" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.WasmClient.Components.Admin.Shared @inject IRevenueTrackingBrowserClient RevenueClient diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/SeasonSimulator.razor b/TaxBaik.Web.Client/Components/Admin/Pages/SeasonSimulator.razor index 32066f5..31a96f9 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/SeasonSimulator.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/SeasonSimulator.razor @@ -1,5 +1,5 @@ @page "/admin/season-simulator" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Application.Seasonal @using TaxBaik.Application.Services diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/Settings/SiteSettings.razor b/TaxBaik.Web.Client/Components/Admin/Pages/Settings/SiteSettings.razor index 9d88619..e443d7e 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/Settings/SiteSettings.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/Settings/SiteSettings.razor @@ -1,5 +1,5 @@ @page "/admin/settings" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using System.ComponentModel.DataAnnotations @using System.Collections.Generic diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilingSchedules.razor b/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilingSchedules.razor index 8d41922..52cb455 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilingSchedules.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilingSchedules.razor @@ -1,5 +1,5 @@ @page "/admin/tax-filing-schedules" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.Domain.Entities @using TaxBaik.WasmClient.Components.Admin.Shared diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilings/TaxFilingList.razor b/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilings/TaxFilingList.razor index b02390f..62b86ed 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilings/TaxFilingList.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/TaxFilings/TaxFilingList.razor @@ -1,5 +1,5 @@ @page "/admin/tax-filings" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities diff --git a/TaxBaik.Web.Client/Components/Admin/Pages/TaxProfiles.razor b/TaxBaik.Web.Client/Components/Admin/Pages/TaxProfiles.razor index 7a03aad..b2c5d95 100644 --- a/TaxBaik.Web.Client/Components/Admin/Pages/TaxProfiles.razor +++ b/TaxBaik.Web.Client/Components/Admin/Pages/TaxProfiles.razor @@ -1,5 +1,5 @@ @page "/admin/tax-profiles" -@rendermode InteractiveWebAssembly +@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false)) @using TaxBaik.Web.Services.AdminClients @using TaxBaik.WasmClient.Components.Admin.Shared @inject ITaxProfileBrowserClient TaxProfileClient diff --git a/TaxBaik.Web.Client/Components/Admin/Routes.razor b/TaxBaik.Web.Client/Components/Admin/Routes.razor index 5cce44e..f2e15fb 100644 --- a/TaxBaik.Web.Client/Components/Admin/Routes.razor +++ b/TaxBaik.Web.Client/Components/Admin/Routes.razor @@ -1,7 +1,7 @@ @namespace TaxBaik.WasmClient.Components.Admin @using Microsoft.AspNetCore.Components.Routing - + diff --git a/TaxBaik.Web.Client/Components/Admin/Shared/AdminLoginForm.razor b/TaxBaik.Web.Client/Components/Admin/Shared/AdminLoginForm.razor index 2340adb..fca0ee3 100644 --- a/TaxBaik.Web.Client/Components/Admin/Shared/AdminLoginForm.razor +++ b/TaxBaik.Web.Client/Components/Admin/Shared/AdminLoginForm.razor @@ -28,9 +28,11 @@ diff --git a/TaxBaik.Web/Pages/Contact.cshtml b/TaxBaik.Web/Pages/Contact.cshtml index 950ad4f..f942d2b 100644 --- a/TaxBaik.Web/Pages/Contact.cshtml +++ b/TaxBaik.Web/Pages/Contact.cshtml @@ -38,7 +38,7 @@
@Html.AntiForgeryToken() -
+
@@ -73,7 +73,7 @@
- + diff --git a/TaxBaik.Web/Services/TelegramInquiryNotificationService.cs b/TaxBaik.Web/Services/TelegramInquiryNotificationService.cs index ced8bac..a9610d4 100644 --- a/TaxBaik.Web/Services/TelegramInquiryNotificationService.cs +++ b/TaxBaik.Web/Services/TelegramInquiryNotificationService.cs @@ -23,10 +23,12 @@ public class TelegramInquiryNotificationService : IInquiryNotificationService public async Task NotifyCreatedAsync(int inquiryId, string name, string phone, string serviceType, string message, string? ipAddress, DateTime createdAtUtc, CancellationToken ct = default) { var botToken = _configuration["Telegram:BotToken"]; - var chatId = _configuration["Telegram:ChatId"]; + var chatId = _configuration["Telegram:InquiryChatId"]; + if (string.IsNullOrWhiteSpace(chatId)) + chatId = _configuration["Telegram:ChatId"]; if (string.IsNullOrWhiteSpace(botToken) || string.IsNullOrWhiteSpace(chatId)) { - _logger.LogWarning("텔레그램 새 문의 알림 설정이 누락되었습니다. Telegram:BotToken 또는 Telegram:ChatId를 확인하세요."); + _logger.LogWarning("텔레그램 새 문의 알림 설정이 누락되었습니다. Telegram:BotToken 또는 Telegram:InquiryChatId/ChatId를 확인하세요."); return; } @@ -80,10 +82,12 @@ public class TelegramInquiryNotificationService : IInquiryNotificationService public async Task NotifyStatusChangedAsync(int inquiryId, string name, string phone, string serviceType, string previousStatus, string newStatus, string? changedBy = null, CancellationToken ct = default) { var botToken = _configuration["Telegram:BotToken"]; - var chatId = _configuration["Telegram:ChatId"]; + var chatId = _configuration["Telegram:InquiryChatId"]; + if (string.IsNullOrWhiteSpace(chatId)) + chatId = _configuration["Telegram:ChatId"]; if (string.IsNullOrWhiteSpace(botToken) || string.IsNullOrWhiteSpace(chatId)) { - _logger.LogWarning("텔레그램 상태 변경 알림 설정이 누락되었습니다. Telegram:BotToken 또는 Telegram:ChatId를 확인하세요."); + _logger.LogWarning("텔레그램 상태 변경 알림 설정이 누락되었습니다. Telegram:BotToken 또는 Telegram:InquiryChatId/ChatId를 확인하세요."); return; } diff --git a/TaxBaik.Web/wwwroot/js/admin-session.js b/TaxBaik.Web/wwwroot/js/admin-session.js index 4e64768..c90c1c1 100644 --- a/TaxBaik.Web/wwwroot/js/admin-session.js +++ b/TaxBaik.Web/wwwroot/js/admin-session.js @@ -239,11 +239,12 @@ window.taxbaikAdminSession = { window.addEventListener('hashchange', window.taxbaikAdminSession.syncRouteClass); if (document.documentElement.classList.contains('admin-login-route')) { + // Login prerenders immediately; no boot splash needed. window.taxbaikAdminSession.hideLoading(); } - - // Keep the initial overlay hidden unless explicitly enabled elsewhere. - window.taxbaikAdminSession.hideLoading(); + // Non-login routes: leave the overlay showing until AdminShell's + // OnAfterRenderAsync(firstRender) calls hideLoading once WASM has + // actually rendered the authenticated shell. const modal = document.getElementById('components-reconnect-modal'); if (!modal) return; @@ -266,6 +267,16 @@ window.taxbaikAdminSession = { form.dataset.bound = '1'; window.taxbaikAdminSession.traceUiState('admin-login', 'bindLoginForm attached'); + + // 업데이트 스플래시: 제출 핸들러가 실제로 붙기 전까지는 버튼을 "준비 중" 상태로 두고, + // 여기서 활성화해 사용자가 로그인 가능 시점을 알 수 있게 한다. + const readyButton = form.querySelector('#admin-login-submit'); + if (readyButton) { + readyButton.disabled = false; + const label = readyButton.querySelector('span'); + if (label) label.textContent = '로그인'; + } + form.addEventListener('submit', async function (event) { event.preventDefault(); diff --git a/docs/ADMIN_PATTERN_CRITIQUE_WBS.md b/docs/ADMIN_PATTERN_CRITIQUE_WBS.md index 7d52cc7..5ed6122 100644 --- a/docs/ADMIN_PATTERN_CRITIQUE_WBS.md +++ b/docs/ADMIN_PATTERN_CRITIQUE_WBS.md @@ -78,6 +78,7 @@ Razor Page/Form | P5-01 | CI gate 명문화 | workflow 체크 목록 | 6개 gate 모두 required | | P5-02 | 배포본 API smoke 확장 | workflow curl 추가 | Blog/Inquiry create-read-update test 2xx | | P5-03 | 운영 회귀 대시보드 | test report/version endpoint | 배포 커밋과 E2E 결과 추적 가능 | +| P4-03 | 기존 20개+ 어드민 화면을 SmartAdmin 5.5 참조(`legacy/smartadmin/`, `DOUZONE_UX_GUIDE.md`)로 재단장 (2026-07-03 시점 미착수, 향후 별도 진행) | 각 화면의 색상/카드/타이포그래피 갱신 | SmartAdmin 매핑 표 기준 적용 화면 수 / 전체 화면 수 100% | ## Immediate Refactor Order diff --git a/docs/DOUZONE_UX_GUIDE.md b/docs/DOUZONE_UX_GUIDE.md index c957363..10f0a56 100644 --- a/docs/DOUZONE_UX_GUIDE.md +++ b/docs/DOUZONE_UX_GUIDE.md @@ -65,6 +65,29 @@ ContentSurface - 색상은 의미를 유지한다. - 동일 상태는 동일 색을 사용한다. +## SmartAdmin 5.5 Design Reference (2026-07-03, 신규 화면부터 적용) + +이 섹션은 어드민의 **시각적 스킨**(색상, 카드 크롬, 로그인 화면 스타일, 셸 레이아웃) 기준이다. 위 UX Principles(고밀도, 표준 동선, 더존 정신)는 그대로 유지하고, SmartAdmin 5.5는 그 위에 입히는 룩앤필만 담당한다. + +- 소스: `legacy/smartadmin/`(로컬에 이미 포함된 v5.5 HTML/CSS 데모 패키지, Bootstrap 5 기반). 정확한 색상/여백 값이 필요하면 이 디렉터리를 직접 참조한다(추측 금지). +- 적용 범위: **향후 신규 어드민 화면부터**. 기존 20개+ 화면(Dashboard, Blog, Inquiry, Client 등)은 이번엔 재단장하지 않는다. 기존 화면을 다른 이유로 수정할 때 자연스럽게 이 기준으로 수렴시킨다. + +### 매핑 표 + +| SmartAdmin 5.5 참조 | 파일 | TaxBaik MudBlazor 대응 | +| --- | --- | --- | +| 상단 `
` 툴바 | `dashboard-control-center.html` | `AdminShell`의 `MudAppBar` | +| `