Appearance
Locale Translation Workflow
SafeCall supports two kinds of translation locales:
- Site-local locale: created in one installation through the admin UI. It is usable immediately on that installation only.
- Promoted locale: committed to the project catalogs and seeded by migrations, so it ships to every installation in a release.
Create a Site-Local Locale
- Log in as an admin.
- Open System > Translations.
- Click Add locale.
- Enter a locale code such as
el, a display label such asΕλληνικά, and choose a source locale to copy from. - Translate values in the editor and save them.
The new locale appears in user settings once it is enabled in the local database.
Export a Locale
From the admin UI, choose the locale in Translations and click Export locale.
For direct database export, use:
sh
bun scripts/i18n/export-db-locale.ts --db server/db/safecall.db --locale el --out exports/el.jsonThe export format is JSON:
json
{
"version": 1,
"locale": { "code": "el", "label": "Ελληνικά", "is_promoted": false },
"exported_at": 1710000000,
"entries": [
{ "key": "shared.settings.language_label", "page": "shared.settings", "value": "Γλώσσα" }
]
}Promote a Locale Into the Product
Use the promotion script on an exported JSON file:
sh
bun scripts/i18n/promote-locale.ts --input exports/el.jsonThe script validates key, page, and placeholder parity against the English catalog, then writes:
lib/src/ui_translation_el_catalog.tsserver/migrations/044_seed_ui_translations_el_catalog.ts
After promotion, add the locale code and label to lib/src/locale.ts, regenerate migration embeds, and run validation.
Override Policy
Catalog migrations define default translations for new installations and upgrades. Site-local admin edits are runtime database values.
New promoted-locale seed migrations should use ON CONFLICT DO NOTHING for values by default, so existing client edits are not overwritten unexpectedly. Use a dedicated update migration only when an official translation should intentionally replace existing values.
Keryx Flutter and cross-surface parity
Keryx uses Flutter gen-l10n (keryx/l10n/app_{en,cs}.arb). SafeCall admin provisioning for Keryx uses the same promoted en/cs UI catalogs. See Keryx localization policy for glossary, fallback rules, and pre-store parity checklist.