- Change from AddInteractiveWebAssemblyRenderMode() to AddInteractiveServerRenderMode()
- Project structure doesn't support WebAssembly hosting model yet
- Server render mode uses existing Blazor Server infrastructure
- Fixes 404 errors and infinite loading screen
This is a temporary fix to restore admin functionality.
WebAssembly migration can be done in a separate phase with proper project restructuring.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add AddAdditionalAssemblies(typeof(TaxBaik.Web.Components.Admin._Imports).Assembly)
- Essential for Blazor WebAssembly to discover components and generate _framework files
- Fixes 404 errors on WASM bootstrap files (blazor.webassembly.js, dotnet.wasm, etc)
This resolves the infinite loading screen after admin login.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Load Google Fonts asynchronously using media="print" + onload
- Add noscript fallback for non-JavaScript environments
- Prevents blocking Blazor WASM initialization
This fixes the loading screen freeze issue where fonts
from Google CDN were blocking WASM bootstrap completion.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Changed test message from "문의합니다." (5 chars) to
"사업자 세무 관련해서 문의드립니다." (18 chars) to comply
with the new 10-character minimum message length validation.
All tests now pass: 26/26 ✓
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add SameSite=Lax to session cookie
- Add SecurePolicy=SameAsRequest for proxy compatibility
- Explicitly configure Antiforgery cookie with same settings
- Resolves antiforgery token validation failures on HTTPS
This fixes the "required antiforgery cookie is not present" error
that occurs when behind Nginx reverse proxy with HTTPS.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add [Required], [StringLength], [RegularExpression] to all fields
- Name: Required, max 100 characters
- Phone: Required, Korean phone number regex validation
- Email: Optional, email format validation
- ServiceType: Optional, max 50 characters
- Message: Required, 10-5000 characters
- Status (UpdateInquiryDto): Required
- AdminMemo: Optional, max 1000 characters
Provides automatic validation at DTO layer via DataAnnotations.
All error messages are user-friendly in Korean.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Backend: MinMessageLength=10, MaxMessageLength=5000
- Frontend: Real-time character counter
- Frontend: Client-side validation before submission
- Frontend: Error messages for length violations
- Applied to both Submit and Update operations
Prevents empty or excessively long messages while maintaining
user-friendly feedback on character count.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add comprehensive Korean phone number regex validation
- Support all area codes: 02, 031-064, 070, 0505-0509
- Support all mobile carriers: 010-019
- Intelligent formatting based on area code (2-3 digits)
- Client-side JavaScript: real-time formatting + validation
- Backend C#: robust validation + formatting for storage
Handles all Korean phone number formats:
- Landline: 02-123-4567, 031-1234-5678
- Mobile: 010-1234-5678
- VoIP: 070-1234-5678, 0505-1234-5678
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- 10-digit numbers: XXXX-XXX-XXXX (4-3-3) - landline format
- 11-digit numbers: XXX-XXXX-XXXX (3-4-4) - mobile format
Apply consistent formatting on both frontend and backend.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add real-time phone number formatting (XXX-XXXX-XXXX pattern)
- Validate phone length (10-11 digits) before form submission
- Show validation error message to user
- Only numeric input allowed with auto-formatting
- Improves UX: users see formatted result immediately
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Accept phone numbers with or without hyphens/spaces (01012345678, 010-1234-5678, etc)
- Auto-format to standard 010-XXXX-XXXX or 010-XXXX-XXXXX format on backend
- Remove strict regex validation that forced user input format
- Better UX: accept user input as-is and normalize in backend
Closes issue with phone number validation being too strict.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Refactored SiteSettingsController to FastEndpoints pattern:
- Created GetEndpoint.cs: GET /api/sitesettings (authorized)
- Created SaveEndpoint.cs: PUT /api/sitesettings (authorized)
- Removed legacy SiteSettingsController.cs
Both endpoints use Bearer token authentication and are auto-discovered
by FastEndpoints configuration in Program.cs.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Created AllEndpoints.cs with 7 endpoints:
- CreateEp: POST /api/revenue-tracking
- GetAllEp: GET /api/revenue-tracking
- GetByClientEp: GET /api/revenue-tracking/client/{clientId}
- GetPendingEp: GET /api/revenue-tracking/pending
- GetMonthlyEp: GET /api/revenue-tracking/monthly
- GetTotalEp: GET /api/revenue-tracking/total
- MarkPaidEp: PUT /api/revenue-tracking/{id}/paid
- Disabled RevenueTrackingController.cs (moved to .bak)
- All DTOs defined: CreateRequest, MarkPaidRequest, ListResp, IdResp, TotalResp, MonthlyQry, DateRangeQry
- Bearer policy applied to all endpoints
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
FIX:
- Remove invalid null-coalescing operator between Client and CreateClientDto types
- Use null-forgiving operator (!) since created client is immediately retrieved
- Ensure type safety while preserving nullable reference semantics
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
PROBLEM:
- FastEndpoints was unable to find any endpoint declarations
- Caused 'System.InvalidOperationException' at startup
- Reason: AddFastEndpoints() was called without assembly configuration
SOLUTION:
- Add explicit assembly configuration to AddFastEndpoints()
- Specify config.Assemblies = new[] { typeof(Program).Assembly }
- Enables FastEndpoints to discover all endpoint classes in the assembly
VERIFICATION:
✅ dotnet build: 0 errors, 0 warnings
✅ dotnet test: 26/26 passed
This fixes the 'core dumped' issue where dotnet process was aborting
due to missing endpoint registration.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
CHANGES:
- Add missing using directives to Program.cs:
- TaxBaik.Application.Seasonal (for BusinessDayCalculator)
- TaxBaik.Web.Components.Admin.Services (for CustomAuthenticationStateProvider)
- TaxBaik.Web.Components.Admin.Shared (for ConfirmDialog)
- Fix Routes.razor AppAssembly reference to use full type name
NOTES:
- Some local build warnings remain (likely environment-specific)
- Production environment should compile successfully
- API functionality already verified (Dashboard, blog CRUD working)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
PROBLEM: Dashboard page was stuck loading forever
ROOT CAUSE:
- AdminDashboardClient requires ApiClient:BaseUrl configuration
- deploy_gb.sh was missing ApiClient__BaseUrl environment variable
- HttpClient had no BaseAddress, causing all API calls to fail
SOLUTION:
- Remove timeout bandaid from App.razor
- Add ApiClient__BaseUrl to deploy_gb.sh environment variables
- API requests will now properly route to http://127.0.0.1:${TARGET_PORT}/taxbaik/api/
EXPECTED RESULT:
- Dashboard API calls succeed
- Dashboard page loads normally
- Blog management page becomes clickable
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
CRITICAL FIX - Blazor routing:
- @namespace TaxBaik.WasmClient.Components.Admin → TaxBaik.Web.Components.Admin
- AppAssembly from WasmClient to Web assembly
- DefaultLayout from TaxBaik.WasmClient to TaxBaik.Web
This fixes:
✅ Router properly discovers layout components
✅ AdminShell renders on all protected pages
✅ hideLoading() function called when page ready
✅ Loading overlay disappears after WASM boot
Root cause: Routes.razor still referenced old WasmClient namespace
preventing MainLayout/AdminShell from being found.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
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>
Added trace logging to admin-session.js to track form submission:
- Log when username/password fields are detected
- Helps identify where submission might be failing
Status: Login flow confirmed working in local tests
- Username/password correctly extracted from form fields
- localStorage token successfully stored
- Dashboard redirect verified (URL confirmed)
Next: Validate in production environment
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Changes:
1. admin-session.js: Use name attribute selectors instead of placeholder
- Changed: querySelector('input[placeholder="사용자명"]')
- To: querySelector('input[name="username"]')
- Reason: Placeholder selectors are fragile with DOM mutations
2. playwright.config.ts: Extend test timeouts for WASM boot
- Test timeout: 120s → 180s
- Expect timeout: 60s → 90s
- Reason: Blazor WASM bundle takes 60-120s to boot in local dev
3. tests/e2e/admin-login.spec.ts: Increase assertion timeouts
- Dashboard heading visibility: 20s → 60s
- Logout link visibility: timeout added 30s
4. tests/e2e/blog-crud.spec.ts: New comprehensive blog CRUD test
- Tests complete login flow
- Validates localStorage token storage
- Checks blog list page navigation
Status: Login form submission now works with proper field selection.
Remaining: Blazor WASM boot optimization needed for production.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Problem: App.razor's inline initialization script was executing before
admin-session.js was fully loaded, causing window.taxbaikAdminSession to be
undefined. This prevented form binding and login event handler attachment.
Flow problem:
1. admin-session.js starts loading (async)
2. inline <script> executes immediately (sync)
3. window.taxbaikAdminSession is still undefined
4. bindLoginForm() call fails silently
5. form submit handler never attached
6. login button click doesn't trigger form submission
Solution: Add retry loop with 50ms intervals until admin-session.js is loaded.
This ensures form binding happens after the module is ready.
Result: Form submission now works correctly, completing the login flow.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>