refactor(gateway): split monolithic style.css and app.js into per-surface modules (#2683)

The gateway's static frontend had grown into two merge-conflict hotspots: a
6 887-line `style.css` and an 11 189-line `app.js`, each a catch-all for every
surface of the SPA. Any two PRs touching different tabs were likely to collide.

This change splits both files by surface/concern while preserving bytes and
behavior. `STYLE_CSS` and `APP_JS` in `crates/ironclaw_gateway/src/assets.rs`
now `concat!(include_str!(...))` the split pieces at compile time, so the
served `/style.css` and `/app.js` URLs are unchanged and the existing
workspace-overlay (`custom.css`) path still works. Cuts land on function /
block boundaries; `node --check` validates the concat. Admin assets move
under `static/admin/` for symmetry. Per-commit safety + CI workflow validate
the split files per-file instead of the old monolith.

- Styles split into 20 files under `static/styles/{base,layout}.css +
  styles/{components,primitives,surfaces}/*.css`
- JS split into 24 files under `static/js/{core,surfaces}/*.js`
- No URL, CSP, or behavioural change — pure file-layout refactor

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Illia Polosukhin
2026-04-20 00:12:29 +09:00
committed by GitHub
parent e8ae9487bb
commit a35f9d9ab5
56 changed files with 18239 additions and 18112 deletions

View File

@@ -54,11 +54,11 @@ resolve_base_ref() {
if git diff --cached --quiet 2>/dev/null; then
HAS_STAGED_CHANGES=0
I18N_CHANGED=$(git diff --name-only -- 'crates/ironclaw_gateway/static/i18n/*.js' 2>/dev/null || true)
GATEWAY_APP_JS_CHANGED=$(git diff --name-only -- 'crates/ironclaw_gateway/static/app.js' 2>/dev/null || true)
GATEWAY_APP_JS_CHANGED=$(git diff --name-only -- 'crates/ironclaw_gateway/static/js/' 2>/dev/null || true)
else
HAS_STAGED_CHANGES=1
I18N_CHANGED=$(git diff --cached --name-only -- 'crates/ironclaw_gateway/static/i18n/*.js' 2>/dev/null || true)
GATEWAY_APP_JS_CHANGED=$(git diff --cached --name-only -- 'crates/ironclaw_gateway/static/app.js' 2>/dev/null || true)
GATEWAY_APP_JS_CHANGED=$(git diff --cached --name-only -- 'crates/ironclaw_gateway/static/js/' 2>/dev/null || true)
fi
if [ -n "$I18N_CHANGED" ]; then
# Resolve script location even when invoked via a symlink (the
@@ -84,28 +84,43 @@ if [ -n "$I18N_CHANGED" ]; then
fi
fi
# Gateway frontend JS must parse cleanly; a syntax error leaves the auth shell
# visible and prevents the app bootstrap from running at all.
# Gateway frontend JS must parse cleanly; a syntax error in any split
# module leaves the auth shell visible and prevents bootstrap from running.
# The monolithic `app.js` was split into per-surface/per-concern modules
# under `static/js/` that are concatenated at compile time into a single
# `APP_JS` constant (see `crates/ironclaw_gateway/src/assets.rs`). Cuts
# land on top-level symbol boundaries, so each file is self-parseable —
# a per-file `node --check` is sufficient.
if [ -n "$GATEWAY_APP_JS_CHANGED" ]; then
if ! command -v node >/dev/null 2>&1; then
echo ""
echo "Commit blocked: Node.js is required to validate gateway app.js syntax."
echo "Commit blocked: Node.js is required to validate gateway JS syntax."
echo "Install Node.js and rerun the commit, or bypass with git commit --no-verify"
exit 1
fi
GATEWAY_APP_JS_TMP=$(mktemp "${TMPDIR:-/tmp}/gateway-app-js.XXXXXX.js")
trap 'rm -f "${TEST_BOUNDARIES_FILE:-}" "${GATEWAY_APP_JS_TMP:-}"' EXIT
if [ "$HAS_STAGED_CHANGES" -eq 1 ]; then
git show ":crates/ironclaw_gateway/static/app.js" > "$GATEWAY_APP_JS_TMP"
else
cp crates/ironclaw_gateway/static/app.js "$GATEWAY_APP_JS_TMP"
fi
GATEWAY_JS_TMP=$(mktemp "${TMPDIR:-/tmp}/gateway-js.XXXXXX.js")
trap 'rm -f "${TEST_BOUNDARIES_FILE:-}" "${GATEWAY_JS_TMP:-}"' EXIT
FAILED=0
while IFS= read -r f; do
[ -z "$f" ] && continue
# Only validate files still present (skip deletes).
if [ "$HAS_STAGED_CHANGES" -eq 1 ]; then
git show ":$f" > "$GATEWAY_JS_TMP" 2>/dev/null || continue
else
[ -f "$f" ] || continue
cp "$f" "$GATEWAY_JS_TMP"
fi
if ! node --check "$GATEWAY_JS_TMP" >/dev/null 2>&1; then
echo " ✗ syntax error: $f"
FAILED=1
fi
done <<<"$GATEWAY_APP_JS_CHANGED"
if ! node --check "$GATEWAY_APP_JS_TMP" >/dev/null; then
if [ "$FAILED" -eq 1 ]; then
echo ""
echo "Commit blocked: gateway app.js failed syntax validation."
echo "Fix the parse error in crates/ironclaw_gateway/static/app.js or bypass with git commit --no-verify"
echo "Commit blocked: one or more gateway JS modules failed syntax validation."
echo "Fix the parse error(s) above or bypass with git commit --no-verify"
exit 1
fi
fi