feat(arch-rules): JS-016 blocks hardcoded 'en-US' in JS at error severity
Some checks failed
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / ruff (push) Successful in 17s
CI / pytest (push) Has been cancelled

Architecture rule that fails CI on any new toLocaleDateString /
toLocaleString / toLocaleTimeString / new Intl.* call that hardcodes
'en-US' instead of using I18n.locale. The whole codebase was cleaned
in the preceding commits (06e59f73, bb4c4004, dd1f9af8) so the rule
ships at error severity from day one.

- Rule definition in .architecture-rules/frontend.yaml under
  javascript_rules; exceptions: i18n.js (defines the helper), vendor/.
- _check_hardcoded_locale in scripts/validate/validate_architecture.py
  wired into both JS validation sites (full scan + per-file -f mode).
- Suppressible per-line with `// noqa: JS-016` for the rare case where
  a specific locale is genuinely required (e.g., a US-only invoice
  formatter that must use en-US regardless of UI language).

Validator output: 0 JS-016 hits across the codebase. Negative-tested
with a planted violation — rule fires correctly and clears on
removal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-24 23:52:14 +02:00
parent bb4c400436
commit eaf180c64f
2 changed files with 77 additions and 0 deletions

View File

@@ -485,6 +485,45 @@ class ArchitectureValidator:
# JS-015: Check for native confirm() instead of confirm_modal macros
self._check_confirm_usage(file_path, content, lines)
# JS-016: Check for hardcoded 'en-US' in locale-aware APIs
self._check_hardcoded_locale(file_path, content, lines)
_HARDCODED_LOCALE_RE = re.compile(
r"(toLocaleDateString|toLocaleString|toLocaleTimeString|new\s+Intl\.\w+)\(\s*['\"]en-US['\"]"
)
def _check_hardcoded_locale(
self, file_path: Path, content: str, lines: list[str]
):
"""JS-016: Reject hardcoded 'en-US' in toLocale* / Intl.* calls.
Dates and numbers must respect the user's dashboard language. Use
`I18n.locale` from static/shared/js/i18n.js instead of a hardcoded tag.
Exceptions: i18n.js itself (defines the helper) and vendor/.
Suppressible per-line with `// noqa: JS-016`.
"""
name = file_path.name
path_str = str(file_path).replace("\\", "/")
if name == "i18n.js" or "/vendor/" in path_str:
return
for i, line in enumerate(lines, 1):
if not self._HARDCODED_LOCALE_RE.search(line):
continue
if "noqa: js-016" in line.lower() or "noqa: js016" in line.lower():
continue
self._add_violation(
rule_id="JS-016",
rule_name="Do not hardcode 'en-US' (or any locale) in Intl/toLocale calls",
severity=Severity.ERROR,
file_path=file_path,
line_number=i,
message="Hardcoded 'en-US' ignores the user's dashboard language",
context=line.strip()[:80],
suggestion="Replace 'en-US' with I18n.locale (from static/shared/js/i18n.js)",
)
def _check_toast_usage(self, file_path: Path, content: str, lines: list[str]):
"""JS-009: Check for alert() or window.showToast instead of Utils.showToast()"""
# Skip utils.js (where showToast is defined)
@@ -3287,6 +3326,9 @@ class ArchitectureValidator:
# JS-014: Check that store API calls don't include storeCode in path
self._check_store_api_paths(file_path, content, lines)
# JS-016: Check for hardcoded 'en-US' in locale-aware APIs
self._check_hardcoded_locale(file_path, content, lines)
def _check_platform_settings_usage(
self, file_path: Path, content: str, lines: list[str]
):