server i18n: move inline HTML to templates.go, localize all handler strings

- Admin & user dashboard HTML moved from handlers to templates.go with i18n.T()
- SafeVaultPath applied in sync_apply.go (note/file create/update, blob restore)
- DeleteNode/RenameNode/MoveNode fixed: correct activity type / entity variant
- Added TypeNoteDeleted, TypeNodeDeleted, TypeFolderMoved activity constants
- Added locale() helper on Server struct, removed hardcoded 'ru' in handlers
- Password policy loosened: 8-256 chars, any characters, machine-readable error codes
- check-i18n.sh: Go Cyrillic = FAIL with explicit exception list, Go locale key consistency check
This commit is contained in:
2026-06-02 11:26:54 +08:00
parent 2fa583d157
commit 7091397649
11 changed files with 435 additions and 259 deletions
+65 -17
View File
@@ -7,15 +7,23 @@ set -e
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
EXIT=0
# Find Cyrillic characters in source files, excluding allowed paths.
# The regex matches any Cyrillic character range.
# Allowed exceptions:
# - locale files (*/i18n/locales/*)
# - docs/*
# - README*
# - spaces/
# - .json files that are templates or configs
# - .md files
# Explicitly allowed Go files that may contain Cyrillic (test data, SQL migrations, i18n catalog).
# These are NOT user-facing strings — they are test fixtures, embedded SQL, or locale definitions.
ALLOWED_GO_CYRILLIC=(
"internal/core/worklog/worklog_test.go"
"internal/core/worklog/worklog.go"
"internal/core/smoke_test.go"
"internal/core/nodes/types.go"
"internal/core/nodes/repository_test.go"
"internal/core/plugins/manager_test.go"
"internal/core/actions/action_test.go"
"internal/core/actions/action.go"
"internal/core/files/file.go"
"internal/core/storage/migrations_008.sql.go"
"internal/gui/index.html.go"
"internal/i18n/catalog.go"
"cmd/verstak-gui/main.go"
)
echo "=== Checking for hardcoded Cyrillic in source code ==="
@@ -24,10 +32,29 @@ GO_CYRILLIC=$(find "$ROOT" -name '*.go' \
! -path "*/i18n/locales/*" \
-exec grep -l '[А-Яа-я]' {} \; 2>/dev/null || true)
if [ -n "$GO_CYRILLIC" ]; then
echo "WARNING: Cyrillic found in Go files (expected in server HTML templates for now):"
echo "$GO_CYRILLIC"
# Don't fail for Go files with HTML templates — they'll be refactored later
# Filter out allowed files
FILTERED=""
for f in $GO_CYRILLIC; do
rel="${f#$ROOT/}"
skip=0
for allowed in "${ALLOWED_GO_CYRILLIC[@]}"; do
if [ "$rel" = "$allowed" ]; then
skip=1
break
fi
done
if [ "$skip" -eq 0 ]; then
FILTERED="$FILTERED $f"
fi
done
if [ -n "$FILTERED" ]; then
echo ""
echo "FAIL: Cyrillic found in Go source files (outside allowed exceptions):"
echo "$FILTERED"
echo ""
echo "These should use i18n.T() instead of hardcoded Russian strings."
EXIT=1
fi
# Search for Cyrillic in Svelte/JS files (excluding locale files)
@@ -58,9 +85,11 @@ else
echo "OK: No bidi/control characters found"
fi
# Check that locale keys in ru.js and en.js match
# Check that locale keys match between ru and en for frontend AND Go
echo ""
echo "=== Checking locale key consistency ==="
# Frontend JS locales
RU_KEYS=$(grep -oP "^\s+'[^']+'" "$ROOT/frontend/src/lib/i18n/locales/ru.js" | sed "s/^ *'//;s/'$//" | sort)
EN_KEYS=$(grep -oP "^\s+'[^']+'" "$ROOT/frontend/src/lib/i18n/locales/en.js" | sed "s/^ *'//;s/'$//" | sort)
@@ -68,15 +97,34 @@ MISSING_EN=$(comm -23 <(echo "$RU_KEYS") <(echo "$EN_KEYS"))
MISSING_RU=$(comm -23 <(echo "$EN_KEYS") <(echo "$RU_KEYS"))
if [ -n "$MISSING_EN" ]; then
echo "WARNING: Keys in ru.js but missing in en.js:"
echo "WARNING: Keys in frontend ru.js but missing in en.js:"
echo "$MISSING_EN"
fi
if [ -n "$MISSING_RU" ]; then
echo "WARNING: Keys in en.js but missing in ru.js:"
echo "WARNING: Keys in frontend en.js but missing in ru.js:"
echo "$MISSING_RU"
fi
if [ -z "$MISSING_EN" ] && [ -z "$MISSING_RU" ]; then
echo "OK: All locale keys match between ru.js and en.js"
echo "OK: All frontend locale keys match between ru.js and en.js"
fi
# Go locales
GO_RU_KEYS=$(grep -oP '"[^"]+":\s*"' "$ROOT/internal/i18n/locales/ru.json" | sed 's/":.*//' | sed 's/"//g' | sort)
GO_EN_KEYS=$(grep -oP '"[^"]+":\s*"' "$ROOT/internal/i18n/locales/en.json" | sed 's/":.*//' | sed 's/"//g' | sort)
GO_MISSING_EN=$(comm -23 <(echo "$GO_RU_KEYS") <(echo "$GO_EN_KEYS"))
GO_MISSING_RU=$(comm -23 <(echo "$GO_EN_KEYS") <(echo "$GO_RU_KEYS"))
if [ -n "$GO_MISSING_EN" ]; then
echo "WARNING: Keys in Go ru.json but missing in en.json:"
echo "$GO_MISSING_EN"
fi
if [ -n "$GO_MISSING_RU" ]; then
echo "WARNING: Keys in Go en.json but missing in ru.json:"
echo "$GO_MISSING_RU"
fi
if [ -z "$GO_MISSING_EN" ] && [ -z "$GO_MISSING_RU" ]; then
echo "OK: All Go locale keys match between ru.json and en.json"
fi
exit $EXIT