feat(i18n): fix translation QA issues and add automation (#16756)

## Summary

This PR fixes translation QA issues and adds automation to prevent
future issues.

### Translation Fixes
- Fixed **escaped Unicode sequences** in translations (e.g.,
`\u62db\u5f85` → `招待`)
- Removed **corrupted control characters** from .po files (null bytes,
invalid characters)
- Fixed **missing/incorrect placeholders** in various languages
- Deleted **35 problematic translations** via Crowdin API that had
variable mismatches

### New Scripts (in `packages/twenty-utils/`)
- `fix-crowdin-translations.ts` - Auto-fixes encoding issues and syncs
to Crowdin
- `fix-qa-issues.ts` - Fixes specific QA issues via Crowdin API
- `translation-qa-report.ts` - Generates weekly QA report from Crowdin
API

### New Workflow
- `i18n-qa-report.yaml` - Weekly workflow that creates a PR with
translation QA issues for review

### Other Changes
- Moved GitHub Actions from `.github/workflows/actions/` to
`.github/actions/`
- Fixed `date-utils.ts` to avoid nested `t` macros in plural expressions
(root cause of confusing placeholders)

### QA Status After Fixes
| Category | Count | Status |
|----------|-------|--------|
| variables | 0  | Fixed |
| tags | 1 | Minor |
| empty | 0  | Fixed |
| spaces | 127 | Low priority |
| numbers | 246 | Locale-specific |
| special_symbols | 268 | Locale-specific |
This commit is contained in:
Félix Malfait
2025-12-22 17:30:46 +01:00
committed by GitHub
parent ede261abf4
commit e6491d6a80
114 changed files with 1668 additions and 976 deletions
@@ -52,7 +52,7 @@ msgstr "'n Gekoppelde rekening"
#. js-lingui-id: cOSBjW
#: src/modules/dashboard/standard-objects/dashboard.workspace-entity.ts
msgid "A dashboard"
msgstr "7n Paneel"
msgstr ""
#. js-lingui-id: ixdsnM
#: src/engine/core-modules/dns-manager/exceptions/dns-manager.exception.ts
@@ -403,7 +403,7 @@ msgstr "'n Indeksmetadata-fout het voorgekom."
#. js-lingui-id: +MvnxO
#: src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-index-metadata-validator.service.ts
msgid "An index must contain at least one field"
msgstr "80Nag \\b0aan vergelykings \\b8met ten minste een veld"
msgstr ""
#. js-lingui-id: SOp/Vw
#: src/engine/core-modules/workspace-invitation/workspace-invitation.exception.ts
@@ -3463,12 +3463,12 @@ msgstr "الاسم"
#. js-lingui-id: 2m6Fru
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name-availability.util.ts
msgid "Name \"{name}\" is not available"
msgstr "هذا الاسم غير متاح"
msgstr "الاسم \"{name}\" غير متاح"
#. js-lingui-id: U8mbyw
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name-availability.util.ts
msgid "Name \"{name}\" is not available as it is already used by another field"
msgstr "هذا الاسم غير متاح لأنه مستخدم بالفعل من قبل حقل آخر"
msgstr "الاسم \"{name}\" غير متاح لأنه مستخدم بالفعل من قبل حقل آخر"
#. js-lingui-id: dBDpp2
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name-availability.util.ts
@@ -3150,7 +3150,7 @@ msgstr "Ubicació"
#. js-lingui-id: hg6l4j
#: src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/format-result-with-group-by-dimension-values.util.ts
msgid "March"
msgstr "Mar7"
msgstr ""
#. js-lingui-id: hw7Mwk
#: src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service.ts
@@ -1208,7 +1208,7 @@ msgstr "Des permissions de champ contradictoires ont été détectées sur un ch
#. js-lingui-id: LZf/L8
#: src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts
msgid "Could not find flat entity in maps"
msgstr "Impossible de trouver l27entite9 plate dans les cartes"
msgstr ""
#. js-lingui-id: jBrX/g
#: src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-index-metadata-validator.service.ts
@@ -5810,12 +5810,12 @@ msgstr "Métadonnées de l'objet de vue lié au champ de vue introuvables"
#: src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts
#: src/engine/metadata-modules/flat-view-field/utils/from-delete-view-field-input-to-flat-view-field-or-throw.util.ts
msgid "View field to delete not found"
msgstr "Champ de vue 1e delete 2non trouv7e"
msgstr ""
#. js-lingui-id: DXyYuh
#: src/engine/metadata-modules/flat-view-field/utils/from-destroy-view-field-input-to-flat-view-field-or-throw.util.ts
msgid "View field to destroy not found"
msgstr "Champ de vue 1e d2e2struire 2non trouv7e"
msgstr ""
#. js-lingui-id: Fpy/K1
#: src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -3931,7 +3931,7 @@ msgstr "ערך אפשרות חורג מ-63 תווים."
#. js-lingui-id: zEGChV
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-enum-flat-field-metadata.util.ts
msgid "Option value format not supported"
msgstr "פורמט ערך האפשרות אינו נתמך"
msgstr ""
#. js-lingui-id: /wsRPd
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-enum-flat-field-metadata.util.ts
@@ -3942,7 +3942,7 @@ msgstr "נדרש ערך אפשרות."
#. js-lingui-id: Kub9t0
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-enum-flat-field-metadata.util.ts
msgid "Option value must be a string of at least one character"
msgstr "ערך האפשרות חייב להיות מחרוזת של לפחות תו אחד"
msgstr ""
#. js-lingui-id: EabrTR
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-enum-flat-field-metadata.util.ts
@@ -5736,7 +5736,7 @@ msgstr "האימות נכשל עבור 0 אובייקטים ו-0 שדות"
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-enum-flat-field-metadata.util.ts
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-enum-flat-field-metadata.util.ts
msgid "Value must be in UPPER_CASE and follow snake_case \"{sanitizedValue}\""
msgstr "תַאִים לִהְיוֹת בְּאוֹתִיּוֹת רִשׁוֹנוֹת  ובפורמט snake_case \"{sanitizedValue}\""
msgstr ""
#. js-lingui-id: gj6Gxm
#: src/engine/core-modules/email-verification/email-verification.exception.ts
@@ -3903,7 +3903,7 @@ msgstr "L'etichetta dell'opzione supera i 63 caratteri"
#. js-lingui-id: h8lHqX
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-enum-flat-field-metadata.util.ts
msgid "Option label format not supported"
msgstr "Il formato dell'etichetta opzione non 8supportato"
msgstr ""
#. js-lingui-id: +E9N4m
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-enum-flat-field-metadata.util.ts
@@ -3437,7 +3437,7 @@ msgstr "アップサート中に一致するレコードが複数見つかりま
#. js-lingui-id: 6rLmLu
#: src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/get-matching-record-id.util.ts
msgid "Multiple records found with the same unique field values for {conflictingFieldsValues}. Cannot determine which record to update."
msgstr "{ConflictingFieldsValues} のために同一フィールド値を持つ複数のレコードが見つかりました。どのレコードを更新するか判断できません。"
msgstr "{conflictingFieldsValues} のために同一フィールド値を持つ複数のレコードが見つかりました。どのレコードを更新するか判断できません。"
#. js-lingui-id: B9dbXq
#: src/engine/core-modules/billing/billing.exception.ts
@@ -3468,7 +3468,7 @@ msgstr "이름 \"{name}\"을 사용할 수 없습니다."
#. js-lingui-id: U8mbyw
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name-availability.util.ts
msgid "Name \"{name}\" is not available as it is already used by another field"
msgstr "이름은 다른 필드에 이미 사용되었기 때문에 사용할 수 없습니다."
msgstr "이름 \"{name}\"은 다른 필드에 이미 사용되었기 때문에 사용할 수 없습니다."
#. js-lingui-id: dBDpp2
#: src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name-availability.util.ts
@@ -2457,7 +2457,7 @@ msgstr "Ongeldige CALDAV-inloggegevens. Controleer uw gebruikersnaam en wachtwoo
#. js-lingui-id: X7+bC6
#: src/engine/core-modules/record-transformer/utils/transform-phones-value.util.ts
msgid "Invalid calling code {callingCode}"
msgstr "Ongeldige landcode {countryCode}"
msgstr "Ongeldige belcode {callingCode}"
#. js-lingui-id: tG/2Q/
#: src/engine/core-modules/captcha/captcha.guard.ts
@@ -2482,7 +2482,7 @@ msgstr "Ongeldige ID van gekoppeld account."
#. js-lingui-id: 1PtrY0
#: src/engine/core-modules/record-transformer/utils/transform-phones-value.util.ts
msgid "Invalid country code {countryCode}"
msgstr "Ongeldig belcode {callingCode}"
msgstr "Ongeldige landcode {countryCode}"
#. js-lingui-id: 0RwhuX
#: src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception.ts
@@ -2311,7 +2311,7 @@ msgstr "Id"
#. js-lingui-id: Ebc83S
#: src/modules/company/standard-objects/company.workspace-entity.ts
msgid "Ideal Customer Profile: Indicates whether the company is the most suitable and valuable customer for you"
msgstr "Ideal kundprofil: Anger om f\\u00f6retaget \\u00e4r den mest l\\u00e4mpliga och v\\u00e4rdefulla kunden f\\u00f6r dig"
msgstr "Ideal kundprofil: Anger om företaget är den mest lämpliga och värdefulla kunden för dig"
#. js-lingui-id: 6cVc+b
#: src/engine/core-modules/sso/sso.exception.ts
@@ -2884,7 +2884,7 @@ msgstr "Inbjudan är skadad."
#: src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts
#: src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts
msgid "Is canceled"
msgstr "\\u00c4r inst\\u00e4lld"
msgstr "Är inställd"
#. js-lingui-id: k+g9Uh
#: src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts
@@ -2892,19 +2892,19 @@ msgstr "\\u00c4r inst\\u00e4lld"
#: src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts
#: src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts
msgid "Is Contact Auto Creation Enabled"
msgstr "\\u00c4r automatisk skapande av kontakt aktiverad"
msgstr "Är automatisk skapande av kontakt aktiverad"
#. js-lingui-id: uBx1xd
#: src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts
#: src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts
msgid "Is Full Day"
msgstr "\\u00c4r heldag"
msgstr "Är heldag"
#. js-lingui-id: 3iAfL2
#: src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity.ts
#: src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity.ts
msgid "Is Organizer"
msgstr "\\u00c4r organisat\\u00f6r"
msgstr "Är organisatör"
#. js-lingui-id: VrHWrH
#: src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts
@@ -2918,7 +2918,7 @@ msgstr "Är skickad mapp"
#: src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts
#: src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts
msgid "Is Sync Enabled"
msgstr "\\u00c4r synkronisering aktiverad"
msgstr "Är synkronisering aktiverad"
#. js-lingui-id: BHCUSr
#: src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts
@@ -2954,12 +2954,12 @@ msgstr "JSON-objekt som innehåller anpassade anslutningsparametrar"
#. js-lingui-id: AQuLwi
#: src/modules/workflow/common/standard-objects/workflow-version.workspace-entity.ts
msgid "Json object to provide steps"
msgstr "Json-objekt f\\u00f6r att tillhandah\\u00e5lla steg"
msgstr "Json-objekt för att tillhandahålla steg"
#. js-lingui-id: fOjmZ1
#: src/modules/workflow/common/standard-objects/workflow-version.workspace-entity.ts
msgid "Json object to provide trigger"
msgstr "Json-objekt f\\u00f6r att tillhandah\\u00e5lla trigger"
msgstr "Json-objekt för att tillhandahålla trigger"
#. js-lingui-id: eCBMag
#: src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/utils/validate-agent-response-format.util.ts
@@ -2969,7 +2969,7 @@ msgstr "JSON-svarformat kräver ett schema"
#. js-lingui-id: TVc0/Q
#: src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts
msgid "Json value for event details"
msgstr "Json-v\\u00e4rde f\\u00f6r h\\u00e4ndelsedetaljer"
msgstr "Json-värde för händelsedetaljer"
#. js-lingui-id: u4ex5r
#: src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/format-result-with-group-by-dimension-values.util.ts
@@ -3070,7 +3070,7 @@ msgstr "Etikett får inte innehålla kommatecken"
#. js-lingui-id: vXIe7J
#: src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts
msgid "Language"
msgstr "Spr\\u00e5k"
msgstr "Språk"
#. js-lingui-id: hHtzNQ
#: src/modules/connected-account/standard-objects/connected-account.workspace-entity.ts
@@ -3106,7 +3106,7 @@ msgstr "Senaste synkhistorik-ID"
#. js-lingui-id: tGwswq
#: src/engine/twenty-orm/base.workspace-entity.ts
msgid "Last time the record was changed"
msgstr "Senaste tiden posten \\u00e4ndrades"
msgstr "Senaste tiden posten ändrades"
#. js-lingui-id: o1zvNS
#: src/engine/twenty-orm/base.workspace-entity.ts
@@ -3122,7 +3122,7 @@ msgstr "Linked Object Metadata Id"
#. js-lingui-id: 6YiMr4
#: src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts
msgid "Linked Record cached name"
msgstr "Cachenamn f\\u00f6r l\\u00e4nkad post"
msgstr "Cachenamn för länkad post"
#. js-lingui-id: sgHAxx
#: src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts
@@ -3139,7 +3139,7 @@ msgstr "LinkedIn"
#. js-lingui-id: LeFv/R
#: src/modules/person/standard-objects/person.workspace-entity.ts
msgid "List of opportunities for which that person is the point of contact"
msgstr "Lista \\u00f6ver m\\u00f6jligheter f\\u00f6r vilka personen \\u00e4r kontaktpunkt"
msgstr "Lista över möjligheter för vilka personen är kontaktpunkt"
#. js-lingui-id: wJijgU
#: src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts
@@ -3176,7 +3176,7 @@ msgstr "Maj"
#: src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts
#: src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts
msgid "Meet Link"
msgstr "M\\u00f6tesl\\u00e4nk"
msgstr "Möteslänk"
#. js-lingui-id: xDAtGP
#: src/modules/messaging/common/standard-objects/message.workspace-entity.ts
@@ -3296,7 +3296,7 @@ msgstr "Meddelande synkroniserat med en meddelandekanal"
#. js-lingui-id: de2nM/
#: src/modules/messaging/common/standard-objects/message-thread.workspace-entity.ts
msgid "Message Thread"
msgstr "Meddelandetr\\u00e5d"
msgstr "Meddelandetråd"
#. js-lingui-id: km1jgD
#: src/modules/messaging/common/standard-objects/message.workspace-entity.ts
@@ -3307,7 +3307,7 @@ msgstr "Meddelandetråd-ID"
#. js-lingui-id: RD0ecC
#: src/modules/messaging/common/standard-objects/message-thread.workspace-entity.ts
msgid "Message Threads"
msgstr "Meddelandetr\\u00e5dar"
msgstr "Meddelandetrådar"
#. js-lingui-id: t7TeQU
#: src/modules/messaging/common/standard-objects/message.workspace-entity.ts
@@ -3319,22 +3319,22 @@ msgstr "Meddelanden"
#: src/modules/messaging/common/standard-objects/message.workspace-entity.ts
#: src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts
msgid "Messages from the channel."
msgstr "Meddelanden fr\\u00e5n kanalen."
msgstr "Meddelanden från kanalen."
#. js-lingui-id: rYPBO7
#: src/modules/messaging/common/standard-objects/message-thread.workspace-entity.ts
msgid "Messages from the thread."
msgstr "Meddelanden fr\\u00e5n tr\\u00e5den."
msgstr "Meddelanden från tråden."
#. js-lingui-id: XcKQrV
#: src/modules/connected-account/standard-objects/connected-account.workspace-entity.ts
msgid "Messaging provider access token"
msgstr "Access-token fr\\u00e5n meddelandeleverant\\u00f6ren"
msgstr "Access-token från meddelandeleverantören"
#. js-lingui-id: 80EvIk
#: src/modules/connected-account/standard-objects/connected-account.workspace-entity.ts
msgid "Messaging provider refresh token"
msgstr "Uppdateringstoken fr\\u00e5n meddelandeleverant\\u00f6ren"
msgstr "Uppdateringstoken från meddelandeleverantören"
#. js-lingui-id: akOVAq
#: src/engine/metadata-modules/workspace-metadata-version/exceptions/workspace-metadata-version.exception.ts
@@ -3511,12 +3511,12 @@ msgstr "Namnet måste vara i camelCase-format."
#. js-lingui-id: EEVPOx
#: src/modules/favorite-folder/standard-objects/favorite-folder.workspace-entity.ts
msgid "Name of the favorite folder"
msgstr "Namnet p\\u00e5 favoritmappen"
msgstr "Namnet på favoritmappen"
#. js-lingui-id: csMjko
#: src/modules/workflow/common/standard-objects/workflow-run.workspace-entity.ts
msgid "Name of the workflow run"
msgstr "Namnet p\\u00e5 arbetsfl\\u00f6dets k\\u00f6rning"
msgstr "Namnet på arbetsflödets körning"
#. js-lingui-id: P+jdmX
#: src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-name.util.ts
@@ -5182,7 +5182,7 @@ msgstr "Arbetsflödets automatiserade triggring typ"
#. js-lingui-id: od0omS
#: src/modules/workflow/common/standard-objects/workflow.workspace-entity.ts
msgid "The workflow last published version id"
msgstr "ID f\\u00f6r den senast publicerade versionen av arbetsfl\\u00f6det"
msgstr "ID för den senast publicerade versionen av arbetsflödet"
#. js-lingui-id: /EdWx6
#: src/modules/workflow/common/standard-objects/workflow.workspace-entity.ts
@@ -5404,12 +5404,12 @@ msgstr "Denna variabel kan endast ställas in via miljön."
#. js-lingui-id: Zl0BJl
#: src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity.ts
msgid "Thread External Id"
msgstr "Externt id f\\u00f6r tr\\u00e5d"
msgstr "Externt id för tråd"
#. js-lingui-id: RSSbWN
#: src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity.ts
msgid "Thread id from the messaging provider"
msgstr "Tr\\u00e5d-id fr\\u00e5n meddelandeleverant\\u00f6ren"
msgstr "Tråd-id från meddelandeleverantören"
#. js-lingui-id: sS8v5K
#: src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts
@@ -5665,7 +5665,7 @@ msgstr "Användarvänligt felmeddelande"
#. js-lingui-id: d1BTW8
#: src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts
msgid "User Id"
msgstr "Anv\\u00e4ndar-id"
msgstr "Användar-id"
#. js-lingui-id: pMOjQa
#: src/engine/core-modules/auth/token/services/access-token.service.ts