docs/I18N.md
Rama main · réplica de lectura del repositorio original.
# Internationalization and Localization
## Purpose
OpenVPM should remain one shared codebase that can support multiple languages,
regional formatting conventions, and optional country-specific capabilities
without creating country forks.
This document defines the initial architecture principles for internationalizing
OpenVPM. It intentionally avoids selecting a runtime i18n library or introducing
country-specific regulatory behavior. Those decisions should happen in focused
follow-up PRs after the project agrees on the boundaries.
## Goals
- Keep English as the canonical source language and fallback.
- Support UI translation without changing routing or business behavior.
- Resolve dates, times, numbers, and currencies through explicit locale-aware
formatting helpers.
- Keep language, formatting locale, country, terminology, and regulatory
capabilities separate.
- Allow country-specific features to be added later as opt-in capabilities.
- Preserve the current default behavior for existing users.
## Non-goals
- Do not create separate country forks of OpenVPM.
- Do not hardcode Italian, or any other language, into the core UI.
- Do not add fiscal, tax, prescription, or reporting rules to translation files.
- Do not implement country-specific integrations as part of the base i18n layer.
- Do not choose a third-party i18n runtime before the minimum architecture and
migration path are agreed.
## Core concepts
### Language
Language controls UI copy and message selection.
Examples:
- `en`
- `it`
- `fr`
English remains the canonical language. Other languages should fall back to
English when a message is missing.
### Formatting locale
Formatting locale controls presentation of dates, times, numbers, currencies,
and similar values.
Examples:
- `en-US`
- `en-GB`
- `it-IT`
Formatting should use explicit helpers rather than scattered `toLocale*` calls
inside components and routes.
### Country
Country controls business context and future optional capabilities.
Examples:
- `US`
- `IT`
- `GB`
Country must not be treated as the same thing as language. A clinic can use
English UI in Italy, Italian UI in Switzerland, or English UI with UK formatting.
### Terminology
Terminology is product language within a supported language. Veterinary software
often needs domain-specific phrasing rather than literal translation.
Terminology should be documented separately from code and from regulatory logic.
### Country-specific capabilities
Capabilities are optional features that may depend on country context, such as
country-specific invoicing, prescription workflows, or reporting integrations.
These capabilities should be modular and opt-in. They are not part of the base
translation layer.
## Architecture principles
1. **Single codebase**
OpenVPM should support localization through shared architecture, not through
forks.
2. **English fallback**
English copy is the canonical baseline. Missing translations must fall back
to English.
3. **Separate concerns**
UI language, formatting locale, country, terminology, and country-specific
capabilities are separate concerns.
4. **No regulations in translations**
Translation files may contain user-facing text. They must not contain tax,
legal, prescription, or reporting rules.
5. **Incremental migration**
Internationalization should be introduced through small, reversible PRs that
preserve existing behavior.
6. **Explicit formatting**
Currency, date, time, and number formatting should go through shared helpers
so behavior can be tested and changed consistently.
7. **Reviewable scope**
Each i18n PR should touch one coherent surface: documentation, formatting
helpers, one route, one message namespace, or one terminology glossary.
## Recommended migration path
### PR 1: Architecture documentation
Add this document and define the boundaries for i18n, localization, formatting,
terminology, and country-specific capabilities.
No runtime behavior changes.
### PR 2: Formatting surface
Confirm and extend the existing locale formatting helpers as the canonical API
for dates, times, numbers, and currencies.
Replace only targeted hardcoded formatting calls. Keep behavior equivalent for
English defaults.
### PR 3: HTML language fallback
Make the document language explicit while preserving the current English
fallback behavior.
Avoid route restructuring.
### PR 4: Message catalog proof of concept
Introduce a minimal message catalog pattern with English as the complete
baseline and one small UI surface as an example.
Do not translate the whole application in one PR.
### PR 5: Italian localization seed
Add the first Italian terminology and translation seed for a small, coherent
workflow.
Keep Italian localization separate from Italian fiscal or regulatory
integrations.
## Italian localization boundary
Italian support in OpenVPM is a localization effort inside the main OpenVPM
project. It is not a fork and does not have a standalone name.
The Italian localization may include:
- Italian UI translations.
- Italian veterinary terminology.
- Italian date, time, number, and currency formatting.
- Italian documentation for users and contributors.
The Italian localization must not automatically include:
- Electronic invoicing.
- National health reporting integrations.
- Veterinary electronic prescription integrations.
- Country-specific legal or fiscal workflows.
Those items should be handled later as explicit country-specific capabilities or
integrations.
## Contributor checklist
Before opening an i18n or localization PR, verify that the change:
- Preserves English behavior.
- Has a clear fallback path.
- Does not mix translation with regulatory logic.
- Does not introduce a new dependency unless the PR explicitly justifies it.
- Does not change database schema unless the PR is specifically about persisted
locale settings.
- Is small enough to review independently.
- Includes tests or reproducible verification where behavior changes.