{formatDate(event.startTime, { day: 'numeric', month: 'short' })}
+{formatCurrency(item.price, 'EUR')}
+``` + +Never call `.toLocaleDateString('de-DE', …)` or `Intl.NumberFormat('de-DE', …)` +directly — those pin output to German regardless of the active locale. +The helpers in `$lib/i18n/format.ts` pull the active locale from the +svelte-i18n store and map (`de → de-DE`, `en → en-US`, …). + +For date-fns formatters that need a locale object, use +`getDateFnsLocale()` from the same module instead of importing +`{ de }` from `'date-fns/locale'`. diff --git a/CLAUDE.md b/CLAUDE.md index c8d678df1..79f83a0f2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,13 +84,22 @@ Quality: pnpm run build pnpm run type-check pnpm run format -pnpm run validate:all # turbo recursion + pgSchema + crypto registry — run before push +pnpm run validate:all # turbo + pgSchema + theme + i18n + crypto — run before push pnpm run test:coverage # emit v8 coverage under per-package coverage/ ``` `validate:all` is the local mirror of the CI `validate` job — it runs in -seconds and fails fast on any of the three invariant checks. Use it as a -pre-push gate. +seconds and fails fast on any invariant check. Currently bundled: + +- `validate:turbo` — no recursive `turbo run` calls in non-root packages +- `validate:pg-schema` — every Drizzle table uses `pgSchema(...)` +- `validate:theme-{variables,utilities,parity}` — token coverage across CSS variants +- `validate:i18n-parity` — every namespace mirrors DE's key-set across all 5 locales +- `validate:i18n-hardcoded` — ratcheting baseline; new German strings without `$_()` fail +- `validate:i18n-keys` — `$_('key')` calls must resolve to a defined DE key (baseline-tracked) +- `check:crypto` + `audit:encrypted-tools` — every Dexie table classified, every AI tool aware of encryption + +Use it as a pre-push gate. ## Key Architecture Notes