> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fim.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Contribuer

> Conventions de développement, sécurité des types, tests et normes de qualité du code pour les contributeurs de FIM One.

<Tip>
  Cette page couvre les conventions de développement et les normes de qualité du code. Pour le guide complet de contribution — incluant le Programme Pioneer, les tests sur le terrain, le processus de PR et les liens communautaires — consultez [CONTRIBUTING.md sur GitHub](https://github.com/fim-ai/fim-one/blob/master/CONTRIBUTING.md).
</Tip>

## Configuration

Prérequis : Python 3.11+, [uv](https://docs.astral.sh/uv/), Node.js 18+, pnpm.

```bash theme={null}
git clone https://github.com/fim-ai/fim-one.git && cd fim-one
cp example.env .env                        # LLM_API_KEY is optional for contributors
uv sync --all-extras                       # Python dependencies
cd frontend && pnpm install && cd ..       # frontend dependencies
bash scripts/setup-hooks.sh                # pre-commit hooks (required)
```

<Note>
  `LLM_API_KEY` est requis uniquement pour exécuter le backend localement ou pour prévisualiser la sortie des paramètres régionaux traduits automatiquement lors de la validation. Les contributeurs sans clé peuvent toujours valider les modifications EN — un workflow GitHub Actions traduit sur `master` après la fusion de la PR. Voir [i18n](#i18n) ci-dessous.
</Note>

Vérifiez que tout fonctionne :

```bash theme={null}
uv run pytest tests/ -x -q                # tests
uv run mypy src/fim_one/                   # type check
uv run ruff check src/                     # lint
cd frontend && pnpm build && cd ..         # frontend build
```

***

## Sécurité des types

Le mode strict de mypy est appliqué. L'ensemble du code passe avec zéro erreur, et le hook pre-commit exécute mypy sur chaque fichier `.py` staged avec vérification complète de la chaîne d'importation.

**Règles :**

* Les annotations de type sont requises sur toutes les fonctions publiques.
* Pas de `# type: ignore` sauf pour `import-untyped` (bibliothèques tierces sans stubs).
* Utilisez `from __future__ import annotations` pour les références anticipées.
* Corrigez les types réels -- ne supprimez jamais les erreurs pour faire passer la CI.

## Tests

Chaque nouveau module **doit** avoir un fichier de test correspondant. Chaque commit de fonctionnalité **doit** inclure des tests.

| Convention | Modèle                       |
| ---------- | ---------------------------- |
| Fichier    | `tests/test_{module}.py`     |
| Classe     | `Test{Feature}`              |
| Méthode    | `test_{behavior_under_test}` |

**Règles :**

* Tous les tests existants doivent réussir avant de valider : `uv run pytest tests/ -x -q`.
* Les tests ne doivent pas dépendre de services externes -- simulez les bases de données, les serveurs MCP, les points de terminaison HTTP et les appels LLM en utilisant `unittest.mock` / `AsyncMock`.
* Exécutez les tests avec couverture : `uv run pytest --cov=fim_one`.

***

## Style de code

* **Async en priorité.** Utilisez `async def` pour les opérations liées aux E/S. Enrobez les appels synchrones avec `asyncio.to_thread()` plutôt que de bloquer la boucle d'événements.
* **Ruff pour le linting.** `uv run ruff check src/` -- la longueur des lignes est de 100 caractères.
* **Exports `__init__.py` minimaux.** Réexportez uniquement l'API publique ; gardez les symboles internes privés.
* **Gestionnaires de paquets.** `uv` pour Python, `pnpm` pour le frontend. N'utilisez jamais `pip` ou `npm`.

## Conventions Git

**Commits atomiques.** Un seul changement logique par commit. Divisez les changements non liés même s'ils ont été développés ensemble.

**Format du message de commit :** `type: description`

| Type       | Quand l'utiliser                                        |
| ---------- | ------------------------------------------------------- |
| `feat`     | Nouvelle fonctionnalité visible pour l'utilisateur      |
| `fix`      | Correction de bug                                       |
| `refactor` | Restructuration du code sans changement de comportement |
| `docs`     | Documentation uniquement                                |
| `test`     | Ajout ou mise à jour de tests                           |
| `chore`    | Build, CI, mises à jour de dépendances                  |

**Ne jamais contourner les hooks** avec `--no-verify`. Le pipeline de pré-commit existe pour détecter les erreurs avant qu'elles n'atteignent le référentiel.

***

## Pipeline de hook de pré-commit

Le hook s'exécute automatiquement à chaque commit. Il traite uniquement les fichiers staged pertinents pour chaque étape — si vous avez modifié uniquement des fichiers Python, l'étape i18n est ignorée, et vice versa.

| Ordre | Étape                                    | Déclencheur                                                                                                                       | Ce qu'il fait                                                                                                                    |
| ----- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| 0     | Garde contre les modifications de locale | Tout fichier staged sous `messages/{locale}/`, `docs/{locale}/`, ou `README.{locale}.md`                                          | Interrompt le commit — pas de contournement possible. Corrigez les traductions via `scripts/translation-glossary.md` à la place. |
| 1     | Régénération de la spécification OpenAPI | `src/fim_one/web/**/*.py` modifié                                                                                                 | Réexporte `docs/openapi.json` à partir des routes FastAPI                                                                        |
| 2     | Traduction i18n                          | `messages/en/*.json`, `docs/*.mdx`, ou `README.md` modifié (nécessite une `LLM_API_KEY` locale, sinon CI la gère après la fusion) | Traduit les clés nouvelles/modifiées dans toutes les locales cibles                                                              |
| 3     | Vérification de type mypy                | Tout `src/fim_one/**/*.py` modifié                                                                                                | Exécute mypy avec la chaîne d'importation complète sur les fichiers staged                                                       |
| 4     | Validation MDX                           | Tout fichier `.mdx` staged                                                                                                        | Valide la syntaxe JSX/MDX avant qu'elle n'atteigne Mintlify                                                                      |

Si une étape échoue, le commit est interrompu. Corrigez les erreurs signalées et réessayez.

## i18n

FIM One prend en charge 6 langues (EN, ZH, JA, KO, DE, FR). Les traductions sont entièrement automatisées.

**Modifiez uniquement les fichiers sources en anglais :**

* `frontend/messages/en/{namespace}.json` -- chaînes d'interface utilisateur
* `docs/*.mdx` (niveau racine, pas les sous-répertoires de langue) -- documentation
* `README.md` -- readme du projet

Les autres fichiers de langue (`messages/zh/`, `docs/zh/`, `README.zh.md`, etc.) sont **générés automatiquement** et le hook de pré-commit refuse inconditionnellement les commits qui les modifient manuellement. Pour corriger une mauvaise traduction, modifiez [`scripts/translation-glossary.md`](https://github.com/fim-ai/fim-one/blob/master/scripts/translation-glossary.md) — la source unique de vérité injectée dans le prompt pour chaque règle de traduction — puis régénérez les fichiers affectés avec `uv run scripts/translate.py --files <en-sources> --force`. Chaque correction du glossaire s'applique à toutes les cinq langues de manière permanente.

**Deux chemins pour générer les fichiers de langue :**

1. **Hook de pré-commit local** — s'exécute si `LLM_API_KEY` est défini dans `.env`. La traduction se fait avant le push, vous pouvez donc prévisualiser le résultat.
2. **Secours CI** — si le hook local n'avait pas de clé et a été ignoré, [`.github/workflows/i18n-sync.yml`](https://github.com/fim-ai/fim-one/blob/master/.github/workflows/i18n-sync.yml) traduit sur `master` après fusion et valide automatiquement le résultat.

Les contributeurs sans clé API peuvent valider librement les modifications EN — le chemin CI garantit que les langues arrivent correctement.

**Ajouter un nouvel espace de noms i18n :** Créez `messages/en/{ns}.json` -- les autres fichiers de langue sont générés lors du prochain commit ou sur CI après fusion.

**Forcer une retraduction complète :** `uv run scripts/translate.py --all` (nécessite une `LLM_API_KEY` locale).

## Migrations de base de données

Dev utilise SQLite, la production utilise PostgreSQL. Un ensemble de fichiers de migration Alembic doit fonctionner sur les deux.

**Règles clés :**

* Chaque nouveau modèle ORM ou colonne **doit** avoir une migration -- ne jamais compter sur `metadata.create_all()`.
* Toutes les migrations **doivent** être idempotentes -- utiliser les helpers de `fim_one.migrations.helpers` (`table_exists`, `table_has_column`, `index_exists`).
* Valeurs par défaut booléennes : `server_default=sa.text("FALSE")` / `sa.text("TRUE")`. Jamais `"0"` / `"1"` -- PostgreSQL rejette les littéraux entiers pour les colonnes booléennes.
* SQLite ne peut pas faire `ALTER COLUMN` -- utiliser `op.batch_alter_table()` pour les modifications de contraintes de colonne.
* Après avoir écrit une migration, exécuter immédiatement `uv run alembic upgrade head` pour l'appliquer.

***

## Référence rapide

```bash theme={null}
# Development
./start.sh dev                            # hot reload (Python + Next.js HMR)
./start.sh dev:api                        # API only, dev mode (hot reload)
./start.sh dev:ui                         # Frontend only, dev mode (HMR)
./start.sh api                            # FastAPI only (headless)

# Quality checks
uv run pytest tests/ -x -q               # tests (stop on first failure)
uv run pytest --cov=fim_one              # tests with coverage
uv run mypy src/fim_one/                  # type check
uv run ruff check src/                    # lint

# i18n
uv run scripts/translate.py --all         # force full retranslation

# Database
uv run alembic upgrade head               # apply migrations
uv run alembic revision -m "description"  # create new migration
```
