# Crowdin Translation Workflow Key Parity in OpenLogi

> OpenLogi ensures Crowdin translation workflow key parity with a Rust test and CI pipeline. Prevent translation drift and runtime errors by matching locale keys to the English source.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: internals
- Published: 2026-08-24

---

**OpenLogi enforces Crowdin translation workflow key parity through a compile-time Rust test and CI pipeline that ensures every locale YAML catalog contains identical keys to the English source, preventing translation drift and runtime errors.**

OpenLogi, an open-source logistics platform developed by AprilNEA, implements a rigorous **Crowdin translation workflow key parity** system to maintain UI translation integrity. The project stores all interface strings in YAML catalogs under `crates/openlogi-ui/locales/`, where the English file ([`en.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/en.yml)) serves as the single source of truth for translation keys. This architecture ensures that missing keys cannot propagate to production, eliminating application panics and fallback string errors.

## Why Translation Key Parity Matters

Key parity guarantees that every supported language contains exactly the same set of translation keys as the English source catalog. When keys drift—present in one locale but absent from another—the application may fail to retrieve strings at runtime, causing user-facing errors or interface gaps. OpenLogi treats this as a build-breaking issue rather than a runtime concern, shifting validation left into the development and continuous integration phases.

## Compile-Time Enforcement via Rust Tests

### The locale_files_have_the_same_keys Test

The primary safeguard resides in [`crates/openlogi-ui/src/locale.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ui/src/locale.rs), specifically within the test function `locale_files_have_the_same_keys` at lines 85-135. This test loads the English source catalog and iterates through each shipped locale file, extracting key sets and asserting strict equality.

The implementation also validates the `SUPPORTED` constant, ensuring that every locale listed for production inclusion undergoes parity verification. If a developer adds a locale to `SUPPORTED` without a corresponding catalog file, or if any catalog lacks a key present in [`en.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/en.yml), the test fails immediately during `cargo test`.

The key extraction logic treats the YAML files as text streams to identify translation keys:

```rust
fn locale_keys(file: &str) -> Vec<&str> {
    file.lines()
        .filter_map(|line| line.strip_prefix('"')) // keep only lines starting with a quote
        .filter_map(|line| line.split_once("\": ").map(|(key, _)| key))
        .collect()
}

```

Run the parity check locally with:

```bash
cargo test -p openlogi-ui --test locale

```

## Continuous Integration Safeguards

### The Crowdin Synchronization Pipeline

Before any translation sync occurs, the CI pipeline defined in [`.github/workflows/crowdin.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/crowdin.yml) executes the parity test. The workflow uses configuration from [`.config/crowdin.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.config/crowdin.yml) to authenticate with the Crowdin API, then follows a strict sequence:

1. Upload the current English source catalog ([`en.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/en.yml)) to Crowdin
2. Download translated catalogs for all supported locales
3. Execute `locale_files_have_the_same_keys` to verify key alignment
4. Only commit translations back to the repository if parity passes

This guarantees that Crowdin only modifies translation *values*, never introducing or removing keys independently. The process is documented in [`docs/DEVELOPMENT.md`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/DEVELOPMENT.md) under the Crowdin translation sync section, with additional rule definitions in [`.claude/rules/i18n.md`](https://github.com/AprilNEA/OpenLogi/blob/main/.claude/rules/i18n.md).

## Adding New Translations While Maintaining Parity

When introducing new UI copy or supporting additional languages, developers must follow this sequence to preserve key parity:

1. Add the key-value pair to **every** locale YAML file in `crates/openlogi-ui/locales/`, including [`en.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/en.yml) and all target language files
2. Update the `SUPPORTED` constant in [`crates/openlogi-ui/src/locale.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ui/src/locale.rs) if introducing a new language
3. Execute the parity test locally: `cargo test -p openlogi-ui --test locale`
4. Commit the changes; the CI pipeline automatically uploads the updated English source to Crowdin and downloads the latest translations

This workflow ensures that the Crowdin platform receives only complete, synchronized keysets, preventing partial translations from entering the codebase.

## Summary

- **Source of truth**: The English catalog at [`crates/openlogi-ui/locales/en.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ui/locales/en.yml) defines the canonical keyset for all translations
- **Compile-time validation**: The `locale_files_have_the_same_keys` test in [`locale.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/locale.rs) (lines 85-135) enforces identical keys across all locale files before build completion
- **CI enforcement**: The [`.github/workflows/crowdin.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/crowdin.yml) pipeline runs parity checks before accepting any Crowdin synchronization, preventing key drift in automated workflows
- **Developer workflow**: New keys must be added to all locale files simultaneously, with verification via `cargo test -p openlogi-ui --test locale`
- **Configuration**: Crowdin project settings reside in [`.config/crowdin.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.config/crowdin.yml), while developer guidelines are documented in [`docs/DEVELOPMENT.md`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/DEVELOPMENT.md)

## Frequently Asked Questions

### What happens if a locale file is missing a key?

The `locale_files_have_the_same_keys` test fails immediately during compilation or CI execution, blocking the build. This prevents deploying an application state where a translation lookup might return `None`, which could cause runtime panics or display missing string identifiers to users.

### How do I add a new supported language to OpenLogi?

First, create a new YAML catalog in `crates/openlogi-ui/locales/` with the identical key structure as [`en.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/en.yml). Then add the locale identifier to the `SUPPORTED` constant in [`crates/openlogi-ui/src/locale.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ui/src/locale.rs). Finally, run `cargo test -p openlogi-ui --test locale` to verify parity before committing.

### Can Crowdin automatically add new keys to translation files?

No. According to the workflow defined in the source code and [`docs/DEVELOPMENT.md`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/DEVELOPMENT.md), developers must manually add new keys to all locale files before uploading to Crowdin. Crowdin only updates the translation values (the right-hand side of YAML key-value pairs) during the sync process, ensuring the English source controls the canonical key structure.

### Where is the source of truth for translation keys defined?

The English catalog at [`crates/openlogi-ui/locales/en.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ui/locales/en.yml) serves as the immutable source of truth. The parity test explicitly loads this file first and compares all other locales against its keyset. Any deviation in key presence or naming triggers a test failure, maintaining strict alignment across the project's internationalization infrastructure.