Files
OmniRoute/docs/i18n/fr/CONTRIBUTING.md
Diego Rodrigues de Sa e Souza b637350680 fix(docs): re-sync the 65 documentation mirror sets; section-level docs pipeline; drift gate blocking (#13940)
1,104 mirrors rewritten over five passes of run-translation on the 22-source core set: the 14 sources edited since their translation, the 322 mirrors that were still English copies, and the frontmatter the old extractor leaked into the newer locales' bodies. The pipeline now caches per-`## `-section hashes and retranslates only changed sections, never reuses a section that is still English, rebuilds English-copy / leaked mirrors even when the source is unchanged, merges the state on save (parallel runs), and the drift gate (scoped to the core set) is blocking. Final audit: 0 stale, 0 English copies, 0 leaked frontmatter across 1,430 core mirrors.

⚠️ base-red inherited: #12732
2026-09-17 02:55:31 -03:00

25 KiB
Raw Blame History

Contributing to OmniRoute (Français)

🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW


Thank you for your interest in contributing! This guide covers everything you need to get started.


Configuration du développement

Prérequis

  • Node.js >=22.22.3 <23, ou >=24.0.0 <27 (recommandé : 24 LTS)
  • npm 10+

Utilisateurs de npm v11+ (Node 24+) : après npm install, vérifiez que les modules natifs ont été installés : node -e "require('better-sqlite3')". Si la commande échoue avec MODULE_NOT_FOUND, exécutez npm approve-scripts better-sqlite3 && npm install. Consultez Dépannage.

  • Git

Clonage et installation

git clone https://github.com/diegosouzapw/OmniRoute.git
cd OmniRoute
npm install

Variables d'environnement

# Créez votre fichier .env à partir du modèle
cp .env.example .env

# Générez les secrets requis
echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env

Variables principales pour le développement :

Variable Valeur par défaut en développement Description
PORT 20128 Port du serveur
NEXT_PUBLIC_BASE_URL http://localhost:20128 URL de base de l'interface
JWT_SECRET (à générer ci-dessus) Secret de signature JWT
INITIAL_PASSWORD CHANGEME Mot de passe de première connexion
APP_LOG_LEVEL info Niveau de verbosité des journaux

Paramètres du tableau de bord

Le tableau de bord fournit des options d'interface pour des fonctionnalités qui peuvent également être configurées au moyen de variables d'environnement :

Emplacement du paramètre Option Description
Paramètres → Avancé Mode de débogage Activer les journaux de requêtes de débogage (interface)
Paramètres → Général Visibilité de la barre latérale Afficher/masquer les sections de la barre latérale

Ces paramètres sont stockés dans la base de données et persistent après les redémarrages, remplaçant les valeurs par défaut des variables d'environnement lorsqu'ils sont définis.

Exécution en local

# Mode développement (rechargement à chaud)
npm run dev

# Build de production
npm run build    # next build → .build/next/ puis assembleStandalone → dist/
npm run start

# Compilation rapide du backend/de l'API uniquement pour les modifications des contributeurs
npm run build:contributor

# Build de publication (reconstruction propre + sentinelle HEAD — requis pour le déploiement)
npm run build:release   # rm -rf .build dist && build + écrit dist/BUILD_SHA

# Configuration courante du port
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev

Le build pour les contributeurs effectue uniquement une validation de la compilation : il n'assemble pas la distribution autonome et ne génère pas les ressources facultatives de packaging natif. Utilisez le build de production standard lorsque vous devez valider le bundle distribuable.

Structure des fichiers générés par le build

Répertoire Contenu Suivi par Git
src/ Code source de l'application (TypeScript / TSX) Oui
.build/ Fichiers intermédiaires — sortie de next build (ignorée par Git, distDir = .build/next) Non
dist/ Bundle distribuable — assemblé par assembleStandalone (ignoré par Git) Non

Le pipeline de build s'effectue en un seul passage :

npm run build
  └─ next build → .build/next/standalone  (sortie de Next.js)
  └─ assembleStandalone()                 (copie les fichiers autonomes + statiques + publics + les ressources natives)
       └─ sortie : dist/                  (server.js, .next/static/, public/, node_modules/)

npm run build:release nettoie également les deux répertoires au préalable et écrit dist/BUILD_SHA (= git rev-parse --short HEAD) comme sentinelle d'intégrité du déploiement.

npm run build:contributor utilise le profil de build du backend uniquement. Il remplace temporairement par des stubs les fichiers d'interface du tableau de bord pendant le build, conserve les gestionnaires de routes de l'API et restaure les fichiers d'origine après le build. Utilisez npm run build pour les modifications qui affectent l'interface du tableau de bord ou pour une validation complète de la publication ; le profil pour les contributeurs ne remplace pas le build de publication.

Remarque concernant le déploiement sur VPS : le répertoire distant de l'image /usr/lib/node_modules/omniroute/app/ reste inchangé. Les procédures de déploiement synchronisent le contenu de dist/ avec celui-ci à l'aide de rsync. Seul le chemin de sortie du build dans le dépôt a changé (app/dist/).

URL par défaut :

  • Tableau de bord : http://localhost:20128/dashboard
  • API : http://localhost:20128/v1

Flux de travail Git

⚠️ Ne faites JAMAIS de commit directement sur main. Utilisez toujours des branches de fonctionnalités.

Base de la PR : ciblez la branche release/vX.Y.Z active (et non main). Consultez docs/ops/BRANCHING_MODEL.md pour en savoir plus sur le modèle avec une branche par version et une balise lors de la livraison.

# Créez une branche à partir de la pointe de la version active (exemple : release/v3.8.49)
git fetch origin
git checkout -b feat/your-feature-name origin/release/v3.8.49
# ... apportez vos modifications ...
git commit -m "feat: décrivez votre modification"
git push -u origin feat/your-feature-name
# Ouvrez une Pull Request avec base = release/v3.8.49

Nommage des branches

Préfixe Objectif
feat/ Nouvelles fonctionnalités
fix/ Corrections de bogues
refactor/ Restructuration du code
docs/ Modifications de la documentation
test/ Ajouts/corrections de tests
chore/ Outillage, CI, dépendances

Messages de commit

Suivez la convention Conventional Commits :

feat: ajouter un disjoncteur pour les appels aux fournisseurs
fix: résoudre un cas limite de validation du secret JWT
docs: mettre à jour SECURITY.md avec la protection des PII
test: ajouter des tests unitaires dobservabilité
refactor(db): regrouper les tables de limitation de débit

Périmètres (v3.8) : db, sse, oauth, dashboard, api, cli, docker, ci, mcp, a2a, memory, skills, cloud-agent, guardrails, compression, auto-combo, resilience, providers, executors, translator, domain, authz.


Exécution des tests

# Tous les tests (unitaires + vitest + écosystème + e2e)
npm run test:all

# Un seul fichier de test (exécuteur de tests natif de Node.js — la plupart des tests lutilisent)
node --import tsx/esm --test tests/unit/your-file.test.ts

# Uniquement les tests unitaires affectés par votre modification (même sélecteur TIA que le contrôle CI, #8084)
npm run test:scoped            # modifications du dernier commit (ou de larborescence de travail)
npm run test:scoped:staged     # modifications indexées uniquement — convient bien à une exécution avant commit
npm run test:scoped:full       # reconstruit dabord la carte du graphe dimportation (après lajout ou le déplacement de fichiers)
# Le code de sortie 1 + « run the full suite » signifie quun fichier central (tsconfig, package.json, …) ou
# une source non mappée a été modifié — le sélecteur échoue de manière sûre et nignore jamais silencieusement des tests.

# Vitest (serveur MCP, autoCombo, cache)
npm run test:vitest

# Tests E2E (nécessite Playwright)
npm run test:e2e

# Tests E2E des clients de protocole (transports MCP, A2A)
npm run test:protocols:e2e

# Tests de compatibilité avec lécosystème
npm run test:ecosystem

# Seuil de couverture : 60 % des instructions/lignes/fonctions/branches
npm run test:coverage
npm run coverage:report

# Vérification du linting et du formatage
npm run lint
npm run check

# Test de fumée contrôlé de combinaisons avec de vrais services en amont (nécessite un accès au VPS et de vrais crédits fournisseur)
# Interroge de VRAIS fournisseurs — cela coûte un peu. Ne sexécute JAMAIS dans la CI. Est ignoré proprement sans lactivation.
# Nécessite : un accès ssh root@192.168.0.15 (charge un instantané de base de données en lecture seule depuis le VPS).
RUN_COMBO_LIVE=1 npm run test:combo:live

# Test de fumée en direct sur le VPS de phase 3 — scripts Node ESM simples, interrogeant directement le serveur .15 actif.
# Nécessite : un accès ssh root@192.168.0.15 (combinaisons créées/supprimées via SQLite par SSH).
# Interroge de VRAIS fournisseurs (faible coût). Crée/supprime uniquement les combinaisons __live_test__*. Ne sexécute JAMAIS dans la CI.
# REQUIRE_API_KEY=false sur .15, donc aucune clé dAPI nest nécessaire, mais respecte COMBO_LIVE_BASE_URL / COMBO_LIVE_API_KEY si elles sont définies.
npm run test:combo:live:vps              # 7 scénarios HTTP (priorité/round-robin/pondéré/coût/fusion/auto + état de santé)
npm run test:combo:live:vps:failover     # ajoute un véritable scénario de basculement entre fournisseurs (8 au total)

Remarques sur la couverture :

  • npm run test:coverage mesure la couverture du code source pour la suite principale de tests unitaires, exclut tests/** et inclut open-sse/**
  • Les pull requests doivent maintenir le seuil de couverture à 60 % ou plus pour les instructions/lignes/fonctions/branches
  • Si une PR modifie du code de production dans src/, open-sse/, electron/ ou bin/, elle doit ajouter ou mettre à jour des tests automatisés dans la même PR
  • npm run coverage:report affiche le rapport détaillé fichier par fichier de la dernière exécution de la couverture
  • npm run test:coverage:legacy conserve lancienne métrique à des fins de comparaison historique
  • Consultez docs/ops/COVERAGE_PLAN.md pour la feuille de route damélioration progressive de la couverture

Exigences relatives aux pull requests

Avant douvrir une PR, suivez le parcours de contribution recommandé afin dexécuter la boucle ciblée correspondant à vos modifications. La suite complète de tests unitaires (4 fragments CI), Vitest, le seuil de couverture de 60 % ou plus et la compilation de production relèvent de la CI — leur exécution en local napporte aucune information supplémentaire par rapport aux vérifications déjà effectuées sur la PR et peut saturer lhôte sur les machines plus modestes (#8084) :

  • Exécutez les fichiers de test qui couvrent votre modification : node --import tsx/esm --test tests/unit/<file>.test.ts
  • Exécutez npm run lint
  • Ajoutez ou mettez à jour des tests automatisés dans la même PR chaque fois que le code de production est modifié
  • Mentionnez les fichiers de test modifiés ou ajoutés dans la description de la PR lorsque le code de production a été modifié
  • Vérifiez le résultat SonarQube sur la PR lorsque les secrets du projet sont configurés dans la CI

État actuel des tests : 122 fichiers de tests unitaires couvrant :

  • Les traducteurs de fournisseurs et la conversion de formats
  • La limitation du débit, le disjoncteur et la résilience
  • Le cache sémantique, lidempotence et le suivi de la progression
  • Les opérations de base de données et le schéma (21 modules de base de données)
  • Les flux OAuth et lauthentification
  • La validation des points de terminaison dAPI (Zod v4)
  • Les outils du serveur MCP et lapplication des portées
  • Les systèmes de mémoire et de compétences

Style du code

  • ESLint — Exécutez npm run lint avant de valider
  • Prettier — Formatage automatique via lint-staged lors de la validation (2 espaces, points-virgules, guillemets doubles, largeur de 100 caractères, virgules finales es5)
  • TypeScript — Tout le code de src/ utilise .ts/.tsx ; open-sse/ utilise .ts/.js ; documentez avec TSDoc (@param, @returns, @throws)
  • Pas de eval() — ESLint applique no-eval, no-implied-eval, no-new-func
  • Validation Zod — Utilisez des schémas Zod v4 pour valider toutes les entrées dAPI
  • Nommage : fichiers = camelCase/kebab-case, composants = PascalCase, constantes = UPPER_SNAKE

Gestion des erreurs / blocs catch vides

Ne laissez jamais un catch sans explication. Classez-le dans lune des deux catégories suivantes (cela rend opérationnelle la règle stricte « ne jamais ignorer silencieusement les erreurs dans les flux SSE ») :

  • Intentionnel (notre propre nettoyage/télémétrie au mieux) — un échec est ici attendu et sans conséquence ; ajoutez un commentaire dune ligne expliquant la raison, sans journalisation (la journalisation à chaque requête est précisément le bruit que cette convention vise à éviter).

    } catch {} // la fermeture dun contrôleur déjà fermé après la déconnexion du client est attendue
    
  • À journaliser (code externe/fourni par lappelant, ou lorsque lerreur ignorée modifie le flux de contrôle) — conservez le bloc catch (ne le laissez jamais interrompre le flux), mais émettez un console.debug/warn contextuel afin que léchec puisse être détecté.

    } catch (e) {
      console.debug("[STREAM] erreur du rappel onFailure :", e);
    }
    

Consultez open-sse/utils/stream.ts et open-sse/utils/streamHandler.ts pour des exemples dapplication.


Project Structure

src/                        # TypeScript (.ts / .tsx)
├── app/                    # Next.js 16 App Router
│   ├── (dashboard)/        # Dashboard pages (23 sections)
│   ├── api/                # API routes (51 directories)
│   └── login/              # Auth pages (.tsx)
├── domain/                 # Policy engine (policyEngine, comboResolver, costRules, etc.)
├── lib/                    # Core business logic (.ts)
│   ├── a2a/                # Agent-to-Agent v0.3 protocol server
│   ├── acp/                # Agent Communication Protocol registry
│   ├── compliance/         # Compliance policy engine
│   ├── db/                 # SQLite database layer (110 top-level modules + 130 migrations)
│   ├── memory/             # Persistent conversational memory
│   ├── oauth/              # OAuth providers, services, and utilities
│   ├── skills/             # Extensible skill framework
│   ├── usage/              # Usage tracking and cost calculation
│   └── localDb.ts          # Re-export layer only — never add logic here
├── middleware/              # Request middleware (promptInjectionGuard)
├── mitm/                   # MITM proxy (cert, DNS, target routing)
├── shared/
│   ├── components/         # React components (.tsx)
│   ├── constants/          # Provider definitions (329), MCP scopes, routing strategies
│   ├── utils/              # Circuit breaker, sanitizer, auth helpers
│   └── validation/         # Zod v4 schemas
└── sse/                    # SSE proxy pipeline

open-sse/                   # @omniroute/open-sse workspace
├── executors/              # 89 executor implementation modules
├── handlers/               # 11 request handlers (chat, responses, embeddings, images, etc.)
├── mcp-server/             # MCP server (107 tools, 3 transports, 32 scopes)
├── services/               # 178 top-level services (combo, autoCombo, rateLimitManager, etc.)
├── translator/             # Format translators (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama)
├── transformer/            # Responses API transformer
└── utils/                  # 22 utility modules (stream, TLS, proxy, logging)

electron/                   # Electron desktop app (cross-platform)

tests/
├── unit/                   # Node.js test runner (122 test files)
├── integration/            # Integration tests
├── e2e/                    # Playwright tests
├── security/               # Security tests
├── translator/             # Translator-specific tests
└── load/                   # Load tests

docs/                       # Documentation
├── ARCHITECTURE.md         # System architecture
├── API_REFERENCE.md        # All endpoints
├── USER_GUIDE.md           # Provider setup, CLI integration
├── TROUBLESHOOTING.md      # Common issues
├── MCP-SERVER.md           # MCP server (107 tools)
├── A2A-SERVER.md           # A2A agent protocol
├── AUTO-COMBO.md           # Auto-combo engine
├── CLI-TOOLS.md            # CLI tools integration
├── COVERAGE_PLAN.md        # Test coverage improvement plan
├── openapi.yaml            # OpenAPI specification
└── adr/                    # Architecture Decision Records

Ajout dun nouveau fournisseur

Étape 1 : Enregistrer les constantes du fournisseur

Ajoutez-les à src/shared/constants/providers.ts — elles sont validées par Zod au chargement du module.

Étape 2 : Ajouter un exécuteur (si une logique personnalisée est nécessaire)

Créez un exécuteur dans open-sse/executors/your-provider.ts en étendant lexécuteur de base.

Étape 3 : Ajouter un traducteur (si le format nest pas celui dOpenAI)

Créez des traducteurs de requêtes/réponses dans open-sse/translator/.

Étape 4 : Ajouter une configuration OAuth (si le fournisseur utilise OAuth)

Ajoutez les identifiants OAuth dans src/lib/oauth/constants/oauth.ts et le service dans src/lib/oauth/services/.

Si le fournisseur en amont distribue un client_id/secret OAuth public ou une clé dAPI Web Firebase dans son CLI public ou son bundle de navigateur, ne lintégrez pas sous forme de chaîne littérale. Utilisez resolvePublicCred() depuis open-sse/utils/publicCreds.ts et ajoutez une entrée doctets masquée à EMBEDDED_DEFAULTS. Le processus obligatoire complet est documenté dans docs/security/PUBLIC_CREDS.md.

Dans les gestionnaires/exécuteurs, les messages derreur transmis au client doivent passer par buildErrorBody() / sanitizeErrorMessage() depuis open-sse/utils/error.ts — ne placez jamais directement err.stack ou err.message dans le corps dune réponse. Consultez docs/security/ERROR_SANITIZATION.md.

Étape 5 : Enregistrer les modèles

Ajoutez les définitions des modèles dans open-sse/config/providerRegistry.ts.

Étape 6 : Ajouter des tests

Écrivez des tests unitaires dans tests/unit/ couvrant au minimum :

  • Lenregistrement du fournisseur
  • La traduction des requêtes/réponses
  • La gestion des erreurs

Liste de contrôle de la Pull Request

  • Les tests réussissent (npm test)
  • Le linting réussit (npm run lint)
  • Le build réussit (npm run build)
  • Les types TypeScript ont été ajoutés pour les nouvelles fonctions et interfaces publiques
  • Aucun secret ni aucune valeur de repli codés en dur
  • Les identifiants publics des services en amont sont intégrés via resolvePublicCred() (voir docs/security/PUBLIC_CREDS.md), jamais sous forme de littéraux
  • Les réponses d'erreur passent par buildErrorBody() / sanitizeErrorMessage() — aucune trace de pile brute dans le corps des réponses (voir docs/security/ERROR_SANITIZATION.md)
  • Les commandes shell (exec / spawn) transmettent les valeurs d'exécution via env, et non par interpolation de chaînes
  • Toutes les entrées sont validées avec des schémas Zod
  • Un fragment de journal des modifications a été ajouté sous changelog.d/{features|fixes|maintenance}/<PR>-<slug>.md pour les changements visibles par les utilisateurs (voir changelog.d/README.md) — ne modifiez pas directement CHANGELOG.md ; les fragments sont agrégés au moment de la publication et ne créent jamais de conflits entre les Pull Requests
  • La documentation a été mise à jour (le cas échéant)
  • Aucune nouvelle alerte CodeQL / Secret-Scanning n'a été ouverte, ou chacune a été rejetée avec une justification technique faisant référence au document docs/security/ pertinent
  • Les routes qui lancent des processus enfants (/api/mcp/, /api/cli-tools/runtime/) sont classées comme isLocalOnlyPath() dans src/server/authz/routeGuard.ts — voir la Règle stricte nº 15
  • Aucun pied de message Co-Authored-By dans les messages de commit — les commits doivent apparaître uniquement sous l'identité Git du propriétaire du dépôt (Règle stricte nº 16)

Releasing

Releases are managed via the /generate-release workflow. When a new GitHub Release is created, the package is automatically published to npm via GitHub Actions.


Obtenir de laide