ea447495d3
TaxBaik CI/CD / build-and-deploy (push) Successful in 2m7s
Groups the repo root into src (buildable source), docs (already existed), and everything else (db/, scripts/, tests/, deploy/ - deployment/ops/test assets that aren't compiled, already organized as their own folders). CI now only needs src/ to build: dotnet restore/build/test/publish all point at src/TaxBaik.sln, src/TaxBaik.Web/, src/TaxBaik.Proxy/. - git mv every project (Domain, Infrastructure, Application, Application.Tests, Web, Web.Client, Proxy) and TaxBaik.sln into src/ as a unit, so relative ProjectReference/.sln paths stay valid unchanged. - .gitea/workflows/deploy.yml: 6 dotnet restore/clean/build/test/publish invocations now point at src/. db/migrations and scripts/ stay at root (deploy_gb.sh and browser-e2e.yml only touch published output and the deployed URL, not source paths - verified, no changes needed there). - scripts/validate_admin_render.sh: admin render-mode file paths now src/TaxBaik.Web.Client/... - scripts/validate_kst_timestamps.sh: dropped deploy.sh from its target list - that script was removed in the prior cleanup commit (dead, no CI workflow referenced it) but this validator still expected it to exist. - CLAUDE.md, docs/ENGINEERING_HARNESS.md, docs/ADMIN_PATTERN_CRITIQUE_WBS.md: updated project-structure diagram, dotnet run/build commands, and grep targets to the new src/ paths (also fixed a pre-existing stale path in ADMIN_PATTERN_CRITIQUE_WBS.md that still said TaxBaik.Web/Components/Admin from before that ever moved to TaxBaik.Web.Client). - Added a Repo Root harness rule + Architecture Guardrail entries: new files belong under src/docs/tests/scripts/db/deploy, not loose at root; temp work stays outside the repo (or under a gitignored .scratch/) and is never committed. Verified locally: dotnet build/test src/TaxBaik.sln (26/26 tests), and all three scripts/validate_*.sh pass against the new layout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
76 lines
3.3 KiB
Bash
76 lines
3.3 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
# Phase 9: 어드민 페이지별 렌더모드 정상화 (2026-07-03)
|
||
#
|
||
# DESIGN: Router/Routes에는 렌더모드를 지정하지 않고, 페이지별로 개별 지정한다.
|
||
#
|
||
# RATIONALE:
|
||
# - Blazor Web App은 "전역 렌더모드"와 "페이지별 렌더모드" 중 하나만 선택할 수 있다.
|
||
# - Router/Routes에 @rendermode를 지정하면 하위 모든 페이지의 개별 @rendermode는 무시된다.
|
||
# - 로그인만 prerender: true가 필요하고(흰 화면 방지), 나머지 [Authorize] 페이지는
|
||
# prerender: false가 필요하다(인증 컨텍스트 없이 prerender 시 AuthorizeRouteView가
|
||
# 빈 화면을 그리는 문제를 피하기 위함). 이 둘을 동시에 만족하려면 전역 지정을 버리고
|
||
# 페이지별 지정으로 가야 한다.
|
||
#
|
||
# See CLAUDE.md Phase 9 for architecture details.
|
||
|
||
app_file="src/TaxBaik.Web.Client/Components/Admin/App.razor"
|
||
routes_file="src/TaxBaik.Web.Client/Components/Admin/Routes.razor"
|
||
login_file="src/TaxBaik.Web.Client/Components/Admin/Pages/Login.razor"
|
||
|
||
for file in "$app_file" "$routes_file" "$login_file"; do
|
||
if [ ! -f "$file" ]; then
|
||
echo "Missing admin render file: $file" >&2
|
||
exit 1
|
||
fi
|
||
done
|
||
|
||
# Reject InteractiveServerRenderMode anywhere (Blazor Server architecture forbidden)
|
||
if grep -rnE "InteractiveServerRenderMode" "$app_file" "$routes_file" >/dev/null; then
|
||
echo "Admin shell must NOT use InteractiveServerRenderMode (Blazor Server)." >&2
|
||
exit 1
|
||
fi
|
||
|
||
# Router/Routes must NOT declare a global rendermode boundary.
|
||
# A global rendermode on <Routes> or <Router> overrides every per-page @rendermode
|
||
# directive beneath it, which is exactly the bug this design fixes.
|
||
if grep -nE "@rendermode" "$app_file" >/dev/null; then
|
||
echo "App.razor's <Routes> must not declare a global @rendermode (breaks per-page prerender control)." >&2
|
||
exit 1
|
||
fi
|
||
|
||
if grep -nE "@rendermode" "$routes_file" >/dev/null; then
|
||
echo "Routes.razor's <Router> must not declare a global @rendermode (breaks per-page prerender control)." >&2
|
||
exit 1
|
||
fi
|
||
|
||
# Login page must explicitly prerender (shows the login form in the first HTML response).
|
||
if ! grep -nE "InteractiveWebAssemblyRenderMode\(\s*prerender:\s*true\s*\)" "$login_file" >/dev/null; then
|
||
echo "Login page must use InteractiveWebAssemblyRenderMode(prerender: true) so the form renders before WASM loads." >&2
|
||
exit 1
|
||
fi
|
||
|
||
# Only routable pages (files with a @page directive) need their own render mode.
|
||
# Child components (e.g. BlogForm.razor, FilingTable.razor) inherit the render
|
||
# mode of whichever page hosts them and must NOT declare their own.
|
||
missing_rendermode=0
|
||
while IFS= read -r -d '' page; do
|
||
[ "$page" = "$login_file" ] && continue
|
||
if ! grep -qE "^@page " "$page"; then
|
||
continue
|
||
fi
|
||
if ! grep -nE "@rendermode" "$page" >/dev/null; then
|
||
echo "⚠️ $page has no @rendermode directive (will not be interactive)." >&2
|
||
missing_rendermode=1
|
||
fi
|
||
done < <(find src/TaxBaik.Web.Client/Components/Admin/Pages -name "*.razor" -print0)
|
||
|
||
if [ "$missing_rendermode" -ne 0 ]; then
|
||
echo "One or more admin pages are missing an explicit @rendermode directive." >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "✅ Admin render harness passed (per-page render mode verified)."
|
||
echo " ℹ️ Login: prerender: true (visible before WASM loads). Other pages: WebAssembly-interactive."
|