- Update CLAUDE.md to reflect new directory structure - Add ancien-confluent and proto-confluent language variants - Reorganize ConfluentTranslator with modular architecture - Add comprehensive user guide (GUIDE_UTILISATION.md) - Update API documentation and configuration files - Clean up obsolete documentation files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
21 KiB
API ConfluentTranslator
Documentation technique de l'API REST du serveur ConfluentTranslator.
Architecture
- Framework : Express.js
- LLM : Anthropic Claude / OpenAI GPT
- Port : 3000 (configurable via
PORT) - Base URL :
http://localhost:3000 - Authentification : API key via header
X-API-Keyou query paramapiKey
Authentification
Toutes les requêtes (sauf /api/health) nécessitent une API key valide.
Header :
X-API-Key: <votre-token-uuid>
Query param :
?apiKey=<votre-token-uuid>
Rôles :
user: Accès aux endpoints de traduction et consultationadmin: Accès complet incluant gestion des tokens
Rate Limiting
Endpoints admin
- Limite : 50 requêtes / 5 minutes (par IP)
- Headers :
X-RateLimit-Limit,X-RateLimit-Remaining
Endpoints LLM (traduction)
- Limite par défaut : 20 requêtes / jour (par API key)
- Admin : Illimité
- Custom keys : Pas de limite (utilise vos propres clés LLM)
- Bypass : Fournir
customAnthropicKeyoucustomOpenAIKeydans le body
Endpoints publics
GET /api/health
Endpoint de santé du serveur (public, pas d'auth requise).
Réponse :
{
"status": "ok",
"timestamp": "2025-12-04T10:30:00.000Z",
"version": "1.0.0"
}
Exemple :
curl http://localhost:3000/api/health
GET /api/validate
Valide une API key et retourne les informations utilisateur.
Headers requis :
X-API-Key: <token>
Réponse :
{
"valid": true,
"user": "Admin",
"role": "admin"
}
Exemple :
curl -H "X-API-Key: YOUR_TOKEN" http://localhost:3000/api/validate
GET /api/llm/limit
Vérifie la limite LLM pour l'API key courante (toujours retourne 200).
Headers requis :
X-API-Key: <token>
Réponse (autorisé) :
{
"allowed": true,
"remaining": 15,
"limit": 20,
"used": 5
}
Réponse (limite atteinte) :
{
"allowed": false,
"error": "Daily LLM request limit reached",
"limit": 20,
"used": 20
}
Exemple :
curl -H "X-API-Key: YOUR_TOKEN" http://localhost:3000/api/llm/limit
Gestion des lexiques
GET /lexique
Retourne le lexique ancien-confluent (legacy, pour compatibilité).
Headers requis :
X-API-Key: <token>
Réponse : Objet JSON du lexique complet
Exemple :
curl -H "X-API-Key: YOUR_TOKEN" http://localhost:3000/lexique
GET /api/lexique/:variant
Retourne le lexique pour une variante spécifique.
Paramètres :
variant(path) :protoouancien
Headers requis :
X-API-Key: <token>
Réponse : Objet JSON du lexique
Exemple :
curl -H "X-API-Key: YOUR_TOKEN" http://localhost:3000/api/lexique/proto
curl -H "X-API-Key: YOUR_TOKEN" http://localhost:3000/api/lexique/ancien
GET /api/stats
Statistiques du lexique (nombre de racines, compositions, etc.).
Paramètres :
variant(query, optionnel) :protoouancien(défaut:ancien)
Headers requis :
X-API-Key: <token>
Réponse :
{
"motsCF": 450,
"motsFR": 380,
"totalTraductions": 520,
"racines": 67,
"racinesSacrees": 15,
"racinesStandards": 52,
"compositions": 120,
"verbes": 12,
"verbesIrreguliers": 0,
"particules": 25,
"nomsPropes": 8,
"marqueurs": 15,
"pronoms": 10,
"autres": 5
}
Exemple :
curl -H "X-API-Key: YOUR_TOKEN" "http://localhost:3000/api/stats?variant=ancien"
POST /api/reload
Recharge les lexiques depuis les fichiers JSON (admin seulement).
Headers requis :
X-API-Key: <token-admin>
Réponse :
{
"success": true,
"message": "Lexiques reloaded",
"stats": {
"proto": 450,
"ancien": 520
}
}
Exemple :
curl -X POST -H "X-API-Key: ADMIN_TOKEN" http://localhost:3000/api/reload
Recherche et analyse
GET /api/search
Recherche un mot dans le lexique.
Paramètres :
q(query, requis) : Mot à recherchervariant(query, optionnel) :protoouancien(défaut:ancien)direction(query, optionnel) :fr2confouconf2fr(défaut:fr2conf)
Headers requis :
X-API-Key: <token>
Réponse :
{
"query": "regard",
"variant": "ancien",
"direction": "fr2conf",
"results": [
{
"mot": "regard",
"traductions": [
{
"confluent": "sili",
"type": "racine",
"contexte": "observation, vision"
}
]
}
]
}
Exemple :
curl -H "X-API-Key: YOUR_TOKEN" "http://localhost:3000/api/search?q=regard&variant=ancien"
curl -H "X-API-Key: YOUR_TOKEN" "http://localhost:3000/api/search?q=sili&direction=conf2fr"
POST /api/analyze/coverage
Analyse la couverture lexicale d'un texte français avant traduction.
Body :
{
"text": "Les enfants observent la confluence",
"target": "ancien"
}
Headers requis :
X-API-Key: <token>
Réponse :
{
"coverage": 85.5,
"found": [
{
"word": "enfants",
"confluent": "naku",
"type": "racine",
"score": 1.0
},
{
"word": "observer",
"confluent": "sili",
"type": "racine",
"score": 1.0
}
],
"missing": [
{
"word": "la",
"suggestions": []
}
],
"stats": {
"totalWords": 5,
"uniqueWords": 5,
"foundCount": 4,
"missingCount": 1,
"entriesUsed": 15,
"useFallback": false
},
"needsFullRoots": false,
"recommendation": "Good coverage - context only",
"variant": "ancien"
}
Exemple :
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"Les enfants observent","target":"ancien"}' \
http://localhost:3000/api/analyze/coverage
Traduction
POST /translate
Endpoint principal de traduction FR → Confluent (avec layers 1-3).
Body :
{
"text": "Les enfants observent la confluence",
"target": "ancien",
"provider": "anthropic",
"model": "claude-sonnet-4-20250514",
"temperature": 1.0,
"useLexique": true,
"customAnthropicKey": "optional-sk-ant-...",
"customOpenAIKey": "optional-sk-..."
}
Paramètres :
text(requis) : Texte français à traduiretarget(requis) :protoouancienprovider(requis) :anthropicouopenaimodel(requis) : Nom du modèle (ex:claude-sonnet-4-20250514,gpt-4o)temperature(optionnel) : 0.0-2.0 (défaut: 1.0, divisé par 2 pour Claude)useLexique(optionnel) : Utiliser le système contextuel (défaut: true)customAnthropicKey(optionnel) : Clé API Anthropic personnalisée (bypass rate limit)customOpenAIKey(optionnel) : Clé API OpenAI personnalisée (bypass rate limit)
Headers requis :
X-API-Key: <token>
Réponse :
{
"layer1": {
"translation": "naku ve sili uraakota"
},
"layer2": {
"wordsFound": [
{
"input": "enfants",
"confluent": "naku",
"type": "racine",
"score": 1.0
}
],
"wordsNotFound": ["la"],
"entriesUsed": 15,
"totalLexiqueSize": 520,
"tokensFullLexique": 45000,
"tokensUsed": 8500,
"tokensSaved": 36500,
"savingsPercent": 81.1,
"useFallback": false,
"expansionLevel": 2,
"rootsUsed": 0
},
"layer3": {
"analyse": "Phrase simple avec sujet et verbe...",
"strategie": "Utilisation des racines connues...",
"decomposition": "naku (enfants) + ve (marque verbale)...",
"notes": "SOV respecté...",
"wordsCreated": []
},
"translation": "naku ve sili uraakota"
}
Layers :
- Layer 1 : Traduction finale
- Layer 2 : Métadonnées contextuelles (COT côté serveur)
- Layer 3 : Explications LLM (COT côté LLM)
Exemple :
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"text":"Les enfants observent la confluence",
"target":"ancien",
"provider":"anthropic",
"model":"claude-sonnet-4-20250514",
"temperature":1.0
}' \
http://localhost:3000/translate
Avec clé personnalisée :
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"text":"Bonjour",
"target":"ancien",
"provider":"anthropic",
"model":"claude-sonnet-4-20250514",
"customAnthropicKey":"sk-ant-..."
}' \
http://localhost:3000/translate
POST /api/translate/raw
Traduction brute sans parsing (debug).
Body : Identique à /translate
Headers requis :
X-API-Key: <token>
Réponse :
{
"raw_output": "ANALYSE:\nPhrase simple...\n\nConfluent:\nnaku ve sili",
"metadata": {
"wordsFound": [...],
"entriesUsed": 15,
"tokensUsed": 8500
},
"length": 245,
"lines": 12
}
Exemple :
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"text":"Test",
"target":"ancien",
"provider":"anthropic",
"model":"claude-sonnet-4-20250514"
}' \
http://localhost:3000/api/translate/raw
POST /api/translate/batch
Traduction par lot (recherche lexique uniquement, sans LLM).
Body :
{
"words": ["regard", "libre", "enfant"],
"target": "ancien"
}
Headers requis :
X-API-Key: <token>
Réponse :
{
"target": "ancien",
"results": {
"regard": {
"found": true,
"traduction": "sili",
"all_traductions": [
{
"confluent": "sili",
"type": "racine",
"contexte": "observation"
}
]
},
"libre": {
"found": true,
"traduction": "aska",
"all_traductions": [...]
},
"enfant": {
"found": false
}
}
}
Exemple :
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"words":["regard","libre"],"target":"ancien"}' \
http://localhost:3000/api/translate/batch
POST /api/translate/conf2fr
Traduction Confluent → Français (mot-à-mot ou détaillée).
Body :
{
"text": "naku ve sili uraakota",
"variant": "ancien",
"detailed": false
}
Paramètres :
text(requis) : Texte en Confluentvariant(optionnel) :protoouancien(défaut:ancien)detailed(optionnel) : Inclure détails morphologiques (défaut: false)
Headers requis :
X-API-Key: <token>
Réponse (simple) :
{
"translation": "enfants voir confluence",
"coverage": 100,
"wordsTranslated": 3,
"wordsNotTranslated": 0
}
Réponse (detailed=true) :
{
"translation": "enfants voir confluence",
"tokens": [
{
"confluent": "naku",
"french": "enfants",
"found": true,
"type": "racine"
},
{
"confluent": "ve",
"french": "voir",
"found": true,
"type": "verbe"
}
],
"coverage": 100,
"wordsTranslated": 3,
"wordsNotTranslated": 0
}
Exemple :
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"naku ve sili","variant":"ancien","detailed":true}' \
http://localhost:3000/api/translate/conf2fr
POST /api/translate/conf2fr/llm
Traduction Confluent → Français avec raffinement LLM.
Body :
{
"text": "naku ve sili uraakota",
"variant": "ancien",
"provider": "anthropic",
"model": "claude-sonnet-4-20250514",
"customAnthropicKey": "optional",
"customOpenAIKey": "optional"
}
Headers requis :
X-API-Key: <token>
Réponse :
{
"confluentText": "naku ve sili uraakota",
"rawTranslation": "enfants voir confluence",
"refinedTranslation": "Les enfants observent la Confluence",
"translation": "Les enfants observent la Confluence",
"tokens": [...],
"coverage": 100,
"wordsTranslated": 3,
"wordsNotTranslated": 0,
"provider": "anthropic",
"model": "claude-sonnet-4-20250514"
}
Exemple :
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"text":"naku ve sili",
"variant":"ancien",
"provider":"anthropic",
"model":"claude-sonnet-4-20250514"
}' \
http://localhost:3000/api/translate/conf2fr/llm
POST /api/debug/prompt
Génère le prompt système sans appeler le LLM (debug).
Body :
{
"text": "Les enfants observent",
"target": "ancien",
"useLexique": true
}
Headers requis :
X-API-Key: <token>
Réponse :
{
"prompt": "Tu es un traducteur expert...\n\n# CONTEXTE LEXICAL...",
"metadata": {
"wordsFound": [...],
"entriesUsed": 15,
"tokensUsed": 8500,
"tokensSaved": 36500
},
"stats": {
"promptLength": 12450,
"promptLines": 280
}
}
Exemple :
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"Test","target":"ancien","useLexique":true}' \
http://localhost:3000/api/debug/prompt
Endpoints admin
Tous les endpoints admin nécessitent un token avec role: "admin".
POST /api/admin/tokens
Créer un nouveau token d'accès.
Body :
{
"name": "John Doe",
"role": "user"
}
Paramètres :
name(requis) : Nom du tokenrole(optionnel) :userouadmin(défaut:user)
Headers requis :
X-API-Key: <token-admin>
Réponse :
{
"success": true,
"token": {
"id": "uuid-v4",
"name": "John Doe",
"role": "user",
"apiKey": "uuid-v4-full-key",
"createdAt": "2025-12-04T10:30:00.000Z",
"active": true
}
}
Exemple :
curl -X POST -H "X-API-Key: ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Alice","role":"user"}' \
http://localhost:3000/api/admin/tokens
GET /api/admin/tokens
Liste tous les tokens (clés masquées).
Headers requis :
X-API-Key: <token-admin>
Réponse :
{
"tokens": [
{
"id": "admin",
"name": "Admin",
"role": "admin",
"apiKey": "12345678...",
"createdAt": "2025-12-01T00:00:00.000Z",
"active": true,
"lastUsed": "2025-12-04T10:25:00.000Z"
},
{
"id": "uuid",
"name": "Alice",
"role": "user",
"apiKey": "abcdef12...",
"createdAt": "2025-12-04T10:30:00.000Z",
"active": true
}
]
}
Exemple :
curl -H "X-API-Key: ADMIN_TOKEN" http://localhost:3000/api/admin/tokens
POST /api/admin/tokens/:id/disable
Désactiver un token.
Paramètres :
id(path) : ID du token
Headers requis :
X-API-Key: <token-admin>
Réponse :
{
"success": true,
"message": "Token disabled"
}
Exemple :
curl -X POST -H "X-API-Key: ADMIN_TOKEN" \
http://localhost:3000/api/admin/tokens/uuid-123/disable
POST /api/admin/tokens/:id/enable
Réactiver un token.
Paramètres :
id(path) : ID du token
Headers requis :
X-API-Key: <token-admin>
Réponse :
{
"success": true,
"message": "Token enabled"
}
Exemple :
curl -X POST -H "X-API-Key: ADMIN_TOKEN" \
http://localhost:3000/api/admin/tokens/uuid-123/enable
DELETE /api/admin/tokens/:id
Supprimer un token (sauf admin).
Paramètres :
id(path) : ID du token
Headers requis :
X-API-Key: <token-admin>
Réponse :
{
"success": true,
"message": "Token deleted"
}
Erreur (tentative de suppression admin) :
{
"error": "Token not found or cannot be deleted"
}
Exemple :
curl -X DELETE -H "X-API-Key: ADMIN_TOKEN" \
http://localhost:3000/api/admin/tokens/uuid-123
GET /api/admin/stats
Statistiques globales (tokens et logs).
Headers requis :
X-API-Key: <token-admin>
Réponse :
{
"tokens": {
"totalTokens": 5,
"activeTokens": 4
},
"logs": {
"totalRequests": 1250,
"successfulRequests": 1180,
"failedRequests": 70,
"avgResponseTime": 245
}
}
Exemple :
curl -H "X-API-Key: ADMIN_TOKEN" http://localhost:3000/api/admin/stats
GET /api/admin/logs
Récupérer les logs de requêtes.
Paramètres :
limit(query, optionnel) : Nombre de logs (défaut: 100)user(query, optionnel) : Filtrer par nom d'utilisateurpath(query, optionnel) : Filtrer par endpointstatusCode(query, optionnel) : Filtrer par code HTTP
Headers requis :
X-API-Key: <token-admin>
Réponse :
{
"logs": [
{
"timestamp": "2025-12-04T10:30:00.000Z",
"method": "POST",
"path": "/translate",
"statusCode": 200,
"responseTime": 1250,
"user": "Alice",
"ip": "127.0.0.1"
}
]
}
Exemple :
curl -H "X-API-Key: ADMIN_TOKEN" \
"http://localhost:3000/api/admin/logs?limit=50&user=Alice"
Gestion des erreurs
Codes HTTP
| Code | Signification | Exemple |
|---|---|---|
| 200 | Succès | Traduction réussie |
| 400 | Requête invalide | Paramètre manquant |
| 401 | Non authentifié | API key manquante ou invalide |
| 403 | Non autorisé | Accès admin requis, token désactivé |
| 404 | Non trouvé | Token inexistant |
| 429 | Trop de requêtes | Rate limit dépassé |
| 500 | Erreur serveur | Erreur LLM, lexique non chargé |
Format des erreurs
{
"error": "Message d'erreur descriptif"
}
Erreur rate limit (429) :
{
"error": "Daily LLM request limit reached",
"limit": 20,
"used": 20
}
Erreur admin (429) :
{
"error": "Too many admin requests."
}
Rate Limiting - Headers
Admin endpoints :
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1701686400
LLM endpoints : Pas de headers, vérifier via /api/llm/limit
Modèles supportés
Anthropic
claude-opus-4-20250514(le plus puissant)claude-sonnet-4-20250514(recommandé - équilibré)claude-haiku-4-20250514(rapide et économique)
OpenAI
gpt-4o(recommandé)gpt-4o-mini(économique)gpt-4-turbo
Exemples complets
Workflow complet de traduction
# 1. Valider l'API key
curl -H "X-API-Key: YOUR_TOKEN" http://localhost:3000/api/validate
# 2. Analyser la couverture lexicale
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"Les enfants observent","target":"ancien"}' \
http://localhost:3000/api/analyze/coverage
# 3. Vérifier la limite LLM
curl -H "X-API-Key: YOUR_TOKEN" http://localhost:3000/api/llm/limit
# 4. Traduire
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"text":"Les enfants observent la confluence",
"target":"ancien",
"provider":"anthropic",
"model":"claude-sonnet-4-20250514"
}' \
http://localhost:3000/translate
Traduction avec clé personnalisée (bypass rate limit)
curl -X POST -H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"text":"Bonjour monde",
"target":"ancien",
"provider":"anthropic",
"model":"claude-sonnet-4-20250514",
"customAnthropicKey":"sk-ant-api03-YOUR-KEY"
}' \
http://localhost:3000/translate
Recherche bidirectionnelle
# FR → Confluent
curl -H "X-API-Key: YOUR_TOKEN" \
"http://localhost:3000/api/search?q=regard&direction=fr2conf"
# Confluent → FR
curl -H "X-API-Key: YOUR_TOKEN" \
"http://localhost:3000/api/search?q=sili&direction=conf2fr"
Notes techniques
Système contextuel (useLexique)
Quand useLexique: true (défaut), le serveur :
- Analyse le texte français
- Recherche les mots dans le lexique
- Génère un prompt optimisé avec seulement les entrées pertinentes
- Économise jusqu'à 81% de tokens
Expansion levels :
0: Mots exacts trouvés1: + Racines des mots trouvés2: + Liaisons sacrées3: Fallback (tout le lexique)
Parsing de réponse LLM
Le serveur parse automatiquement les sections :
ANALYSE:→layer3.analyseSTRATÉGIE:→layer3.strategieConfluent:→layer1.translationDécomposition:→layer3.decompositionNotes:→layer3.notes
Sécurité
- Tokens : UUID v4 stockés dans
data/tokens.json - HTTPS : Recommandé en production
- CORS : À configurer selon besoins
- JWT_SECRET : Changer en production (
.env) - Admin token : Stocké au premier lancement (console)
Dépannage
"API key required"
→ Ajouter header X-API-Key ou query param ?apiKey=...
"Token disabled"
→ Réactiver via /api/admin/tokens/:id/enable
"Daily LLM request limit reached"
→ Attendre minuit OU utiliser customAnthropicKey/customOpenAIKey
"Lexique not loaded"
→ Vérifier les fichiers JSON dans data/ OU appeler /api/reload
Rate limit admin
→ Attendre 5 minutes OU espacer les requêtes
Support
Pour plus d'informations :
- Architecture :
ConfluentTranslator/STRUCTURE.md - Guide admin :
ConfluentTranslator/docs/admin/ADMIN_GUIDE.md - Sécurité :
ConfluentTranslator/docs/security/README_SECURITY.md