feat(i18n): add 67 missing dashboard keys and guard placeholder integrity - #64
Conversation
Audited every key the core_api dashboard references against this repo's
source of truth. 67 were only ever present in the frontend's bundled English
fallback (i18n-utils.ts), so non-English users saw English for them and the
strings were never offered to Crowdin for translation.
integrations.lightspeed.* 45 Lightspeed X-Series connect/outlets/sync UI
programs.edit.dataTools.* 11 whole-program points reset control
broadcast.form.sent* 5 post-send delivery summary
app.auth.register.* 3 ToS / DPA / privacy links
customers.*.pointsClamped 2 overspend-prevented event label
nav.lightspeed 1
English text is copied verbatim from the frontend fallback so the two agree.
Deliberately NOT added: a stray '_comment' key carrying a Portuguese editorial
note ('Traducoes portuguesas (Portugal) - a completar via Lokalise AI
Translation') that leaked into the English bundle. It is not a translatable
string and should be removed from the frontend fallback instead.
en-US only, per the flow the giftCards keys already follow: validate-locales
now reports */common alongside the pre-existing */giftCards until the strings
round-trip through Crowdin (crowdin:upload -> translate -> crowdin:download).
…ders
Both consumers substitute {{variable}} — i18next in the dashboard and
translation_loader.py on the backend — so the single-brace {id} this key carried
was never replaced. The dashboard calls it as
t('loyalty.forms.scanForm.showCustomer', { id: field.value }), so every locale
rendered the literal text '#{id}' instead of the customer number. es-ES had lost
the placeholder altogether and showed no number at all.
Adds two checks to the language suite:
- no single-brace {var}, with an allowlist for strings whose braces are not
interpolation: the WordPress plugin substitutes {name}/{value}/{currency}
itself and its 'adjust the message' string instructs merchants to type them,
and tab.placeholderInfo documents the ${Name} pass syntax.
- every target locale carries the same variables as en-US. Key parity cannot
see this class of defect — the key is present, its variable is not — which is
how es-ES dropped the customer number unnoticed.
Ten errors/notifications keys and seven translations that dropped or invented a
variable are listed in the test as pending rather than fixed here: the former
need their consumer confirmed, the latter are translation content that belongs
in a Crowdin pass. The checks stop new regressions meanwhile.
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Greptile SummaryThe PR expands the en-US source catalog with dashboard translation keys and corrects customer-ID interpolation across supported locales.
Confidence Score: 5/5The PR appears safe to merge, with no actionable changed-code defect identified. The locale edits consistently use the configured double-brace interpolation syntax, and the new validation operates over fixed supported locales while preserving explicitly documented existing exceptions.
|
| Filename | Overview |
|---|---|
| packages/i18n/locales/en-US/common.json | Adds the missing dashboard source strings and corrects the customer-ID interpolation syntax; no actionable defect identified. |
| packages/i18n/src/tests/all-languages.test.js | Adds placeholder syntax and parity guardrails using trusted locale constants and explicit known-defect exceptions; no actionable defect identified. |
| packages/i18n/locales/es-ES/common.json | Restores the previously omitted customer ID with the correct interpolation variable. |
| packages/i18n/locales/en-GB/common.json | Corrects the customer-ID placeholder to the supported double-brace syntax. |
| packages/i18n/locales/es-MX/common.json | Corrects the customer-ID placeholder to the supported double-brace syntax. |
| packages/i18n/locales/fr/common.json | Corrects the customer-ID placeholder to the supported double-brace syntax. |
| packages/i18n/locales/it/common.json | Corrects the customer-ID placeholder to the supported double-brace syntax. |
| packages/i18n/locales/pt-BR/common.json | Corrects the customer-ID placeholder to the supported double-brace syntax. |
| packages/i18n/locales/pt-PT/common.json | Corrects the customer-ID placeholder to the supported double-brace syntax. |
Reviews (1): Last reviewed commit: "fix(i18n): make scanForm.showCustomer in..." | Re-trigger Greptile
…y locale
Review feedback:
- The variable extractor captured only the identifier before a dot, so
{{shop.name}} and {{shop.domain}} both read as 'shop' and a translation could
substitute one for the other undetected. Dots are now part of the name.
- Single-brace exemptions applied to a whole key, permanently blinding every
locale for it. They now name the specific variable, so any other single-brace
variable in those strings still fails, and a locale corrected to {{var}} simply
stops matching.
- The parity check skipped keys absent from the target on the grounds that key
coverage was asserted elsewhere; that assertion only covers 'common', so a
missing key in errors/emails/notifications escaped both checks. Absent keys are
now reported, with the pre-existing giftCards backlog exempted by namespace.
Widening the extractor immediately exposed two defects it had been blind to:
- common.templates.detail.deleteButton read 'Delete {template.name}' in en-US —
a JS template literal captured as text by an extractor. The key exists, so
i18next returned it verbatim and the button rendered the literal placeholder.
Set to 'Delete', matching all seven other locales.
- errors.operations.failed_to_renew_certificate had its PLACEHOLDER NAME
translated: {mensaje} in es-ES/es-MX, {mensagem} in pt-BR/pt-PT. Those would
never interpolate even once the braces are doubled, because the caller passes
'message'. Identifier restored, translated prose kept.
Also seeds the 67 new keys into the seven target locales with the English source
text, which is what CI's key-coverage tests require. This changes nothing for
users — the dashboard already served English for these via its bundled fallback —
and it puts the strings in front of Crowdin for a real translation pass.
Full suite green: 243 passed.
Dismissed because a newer commit was pushed; Greptile will re-review the current head.
|
@CodeAnt-AI: review |
|
CodeAnt AI is running the review. |
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Sequence DiagramThis PR adds missing dashboard translations across supported locale resources and ensures dynamic placeholders remain consistent. The flow shows localized lookup, placeholder interpolation, and automated integrity checks. sequenceDiagram
participant Dashboard
participant I18n
participant LocaleFiles
participant User
participant TestSuite
Dashboard->>I18n: Request dashboard text with values
I18n->>LocaleFiles: Load selected locale keys
LocaleFiles-->>I18n: Return localized text and placeholders
I18n-->>Dashboard: Interpolate placeholder values
Dashboard-->>User: Render localized dashboard text
TestSuite->>LocaleFiles: Scan all locale strings
TestSuite->>TestSuite: Verify placeholder syntax and parity
TestSuite-->>TestSuite: Report integrity result
Generated by CodeAnt AI |
|
CodeAnt AI finished running the review. |
|
@haim-barad Please help me to merge this. Thanks! |
User description
Summary
Audited every i18n key the core_api dashboard references against this repo's en-US source of truth. 67 keys existed only in the frontend's bundled English fallback, so they were never offered to Crowdin and non-English users saw English. Also fixes one key whose placeholder never interpolated, and adds tests so both classes of defect cannot recur silently.
Missing keys added (
locales/en-US/common.json)integrations.lightspeed.*programs.edit.dataTools.*broadcast.form.sent*app.auth.register.*customers.*.pointsClampednav.lightspeedEnglish copied verbatim from the frontend fallback so the two agree. Verified 0 original keys lost or modified (2783 -> 2850).
Deliberately NOT added: a stray
_commentkey carrying a Portuguese editorial note that leaked into the English bundle. It is not a translatable string; removed on the core_api side instead.Placeholder fix
loyalty.forms.scanForm.showCustomerstored a single-brace{id}. Both consumers interpolate{{variable}}— i18next in the dashboard,translation_loader.pyon the backend — so the dashboard, which calls it ast(..., { id: field.value }), rendered the literal text#{id}in every locale. es-ES had lost the placeholder entirely and showed no number at all. Fixed across all 8 locales.Guardrail (
src/__tests__/all-languages.test.js)Two rules, 15 tests:
{var}Rule 2 is the important one: key parity cannot see a translator deleting a variable — the key is present, its variable is not — which is exactly how es-ES lost the customer number.
Verified non-vacuous: injecting
#{id}and dropping{{name}}from French makes both rules fail with pinpointed messages.Known issues are listed explicitly in the test with the reason each is unresolved, rather than silently allowlisted:
LITERAL_TOKEN_KEYS— permanent. The WordPress plugin substitutes{name}/{value}/{currency}itself and instructs merchants to type them;tab.placeholderInfodocuments the${Name}pass syntax. Doubling these would break the plugin.PENDING_SINGLE_BRACE— 10errors/notificationskeys with no caller in core_api, likely consumed by the Square/Shopify/Clover/WordPress repos. Needs the consumer confirmed before changing.PENDING_PARITY— 6 Italian strings that dropped a variable, and a pt-BR subject that invented{{merchantName}}that nothing supplies. Left for a Crowdin pass rather than machine-written prose.Expected CI state
validate-locales/ key-coverage tests now report*/commonalongside the pre-existing*/giftCards, until the new strings round-trip through Crowdin (crowdin:upload-> translate ->crowdin:download). Measured: baseline on main had 7 key-coverage mismatches, this branch has 14 — same class, same cause. The suite was already red before this change.CodeAnt-AI Description
Add missing dashboard translations and keep localized placeholders working
What Changed
Impact
✅ Lightspeed and dashboard features show translated labels✅ Customer numbers appear correctly after scans✅ Clearer certificate error details✅ Fewer untranslated or broken localized messages💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.