Un blueprint concret,Où se place OpenAPI+ Spec-Kit+ d’OpenAPI.yaml p+ workflow CI adapté (Odoo / RAG / Claude)+Comment Claude intervient comme QA contractuel / RAG

summary: Créer un devis Odoo à partir d'une commande vocale transcrite

Je vais te donner un blueprint concret, directement réutilisable :

  1. Où se place OpenAPI dans Synergia
  2. Une Spec-Kit adaptée Synergia
  3. Un exemple d’OpenAPI.yaml pour une route clé
  4. Un workflow CI adapté (Odoo / RAG / Claude)
  5. Comment Claude intervient comme QA contractuel / RAG

1️⃣ Où se place OpenAPI dans Synergia ?

Architecture logique :

[Fronts] (Web, mobile, WearOS, Call center UI) ↓ [API BFF Synergia] ←→ [Odoo Online (JSON-RPC)] ↓ [Supabase RAG] ←→ [LLM (Claude / OpenAI)]

👉 C’est l’API BFF Synergia (ton middleware Node/TS) qui doit être :

  • décrite par OpenAPI
  • validée par la CI
  • utilisée par les fronts (Web / RN / agents voix)

Exemples de routes BFF typiques :

  • POST /api/voice-orders → crée un devis Odoo à partir d’une transcription + RAG
  • GET /api/patients/{id}/summary → récupère info Odoo + RAG (dossier structuré)
  • POST /api/nurse/events → push d’événements (visite, chute, alerte) vers Odoo

C’est cette couche-là que tu verrouilles par OpenAPI.

2️⃣ Spec-Kit Synergia (exemple)

Fichier : specs/synergia-voice-orders.spec.md

# SPEC v1.0 — Synergia Voice Orders API PROJECT: Name: "Synergia Voice Orders" Domain: "Care Management / Seniors" Owner: "Synergia Core Team" Version: "0.1.0" OBJECTIVE: Permettre aux infirmiers de dicter des commandes vocales. Ces commandes sont transcrites, interprétées via RAG, puis transformées en devis Odoo (sale.order + sale.order.line). BACKGROUND: - ERP principal: Odoo Online (SaaS) - Webhook / API BFF: Node.js + TypeScript - RAG: Supabase (embeddings produits + nomenclature) - LLM: Claude 3.5 / OpenAI (non bloquant, interchangeable) REQUIREMENTS: - API REST BFF décrite dans `docs/synergia-openapi.yaml` - Routes minimales: - POST /api/voice-orders - GET /api/voice-orders/{id} - Types stricts TypeScript - Validation Zod côté BFF - Aucun appel direct Odoo depuis le front (tout passe par le BFF) TASKS: [T1] Définir les schémas OpenAPI pour /api/voice-orders [T2] Implémenter le contrôleur BFF (Node/TS) [T3] Implémenter le connecteur Odoo (JSON-RPC) [T4] Intégrer RAG Supabase (matching produits) [T5] Écrire les tests Jest (unitaires + intégration) [T6] Mettre en place CI: - validation OpenAPI - openapi-diff - tests - rapport Claude si contrat violé OUTPUTS: - `docs/synergia-openapi.yaml` - Code BFF (controllers, services, clients Odoo/RAG) - Tests Jest/playwright - Workflow CI `.github/workflows/synergia-contract.yml` VALIDATION: [V1] Tous les tests passent (npm test) [V2] `docs/synergia-openapi.yaml` est valide OpenAPI [V3] Pas d’écart non justifié entre spec et implémentation (diff traité) [V4] Les réponses de /api/voice-orders respectent les schémas JSON (facturé par l’IA) décrits dans OpenAPI NON-GOALS: - Gestion des paiements patient (phase ultérieure) - Gestion fine des droits infirmiers (géré par Odoo pour l’instant)

👉 Cette Spec-Kit devient la source de vérité pour :

  • dev humains
  • agents IA (Claude Code, Copilot, Agent-3)
  • pipeline de test & vérification

3️⃣ Exemple d’OpenAPI pour une route Synergia clé

Fichier : docs/synergia-openapi.yaml (extrait)

openapi: 3.1.0 info: title: Synergia Voice Orders API version: "0.1.0" paths: /api/voice-orders: post: summary: Créer un devis Odoo à partir d'une commande vocale transcrite operationId: createVoiceOrder requestBody: required: true content: application/json: schema: type: object properties: patient_id: type: string description: "ID patient Synergia / Odoo" nurse_id: type: string description: "ID infirmier Synergia / Odoo" transcript: type: string description: "Texte brut issu de la transcription Realtime" language: type: string enum: ["fr", "en"] default: "fr" required: ["patient_id", "nurse_id", "transcript"] responses: "201": description: "Devis créé dans Odoo" content: application/json: schema: type: object properties: order_id: type: string description: "ID de devis Odoo (sale.order)" order_ref: type: string total_amount: type: number currency: type: string status: type: string enum: ["draft", "sent"] parsed_lines: type: array items: type: object properties: product_id: { type: string } product_name: { type: string } quantity: { type: number } unit_price: { type: number } payor: type: string enum: ["assurance_maladie", "mutuelle", "patient"] required: ["order_id", "total_amount", "status"] "400": description: "Requête invalide" "500": description: "Erreur interne (Odoo, RAG, LLM, etc.)"

🔑 Points importants :

  • Ce schéma décrit exactement ce que doit renvoyer ton BFF.
  • Derrière, ton BFF :
    • appelle RAG Supabase pour matcher les produits
    • appelle Odoo (JSON-RPC sale.order + sale.order.line)
    • renvoie un JSON strict conforme à ce schéma.

4️⃣ Workflow CI adapté à Synergia

.github/workflows/synergia-contract.yml (version Synergia de ce qu’on a fait avant)

name: Synergia API Contract & RAG Check on: pull_request: paths: - "docs/synergia-openapi.yaml" - "src/**" - ".github/workflows/synergia-contract.yml" jobs: contract-check: runs-on: ubuntu-latest env: OPENAPI_SPEC_PATH: docs/synergia-openapi.yaml GENERATED_SPEC_PATH: docs/generated-openapi.yaml steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Node uses: actions/setup-node@v4 with: node-version: "20" - name: Install deps run: | npm install npm install -g @redocly/cli # 1. Validation OpenAPI - name: Validate Synergia OpenAPI Spec run: | redocly lint $OPENAPI_SPEC_PATH # 2. (Optionnel) Générer OpenAPI depuis le code BFF - name: Generate OpenAPI from BFF (placeholder) run: | # Par ex: npm run generate-openapi cp $OPENAPI_SPEC_PATH $GENERATED_SPEC_PATH # 3. Diff - name: Diff OpenAPI specs id: openapi_diff run: | diff -u $OPENAPI_SPEC_PATH $GENERATED_SPEC_PATH > openapi.diff || echo "DIFF_EXIT_CODE=$?" >> $GITHUB_ENV # 4. Tests BFF & RAG (unitaires + intégration) - name: Run Jest tests (BFF + RAG) run: | npm test # 5. Vérifier s'il y a un diff - name: Check if OpenAPI diff exists id: check_diff run: | if [ -s openapi.diff ]; then echo "has_diff=true" >> $GITHUB_OUTPUT else echo "has_diff=false" >> $GITHUB_OUTPUT fi # 6. Analyse contractuelle par Claude - name: Run Claude OpenAPI contract review (Synergia) if: steps.check_diff.outputs.has_diff == 'true' env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | node scripts/synergia-claude-openapi-review.js \ --spec $OPENAPI_SPEC_PATH \ --generated $GENERATED_SPEC_PATH \ --diff openapi.diff \ --output synergia-contract-report.md - name: Upload contract report if: steps.check_diff.outputs.has_diff == 'true' uses: actions/upload-artifact@v4 with: name: synergia-openapi-contract-report path: synergia-contract-report.md


5️⃣ Claude côté Synergia : QA API et QA RAG

Tu peux utiliser le même principe d’agent Claude pour :

  1. Contrat API (OpenAPI) ✅ (ce qu’on vient de faire)
  2. Qualité des réponses RAG :

Par exemple, pour le pipeline Synergia :

  • question infirmière →
  • BFF appelle RAG Supabase →
  • LLM produit une réponse structurée (JSON) :

{ "answer": "Résumé pour l'infirmière...", "citations": ["doc_123#p4", "doc_456#p2"], "risk_flags": ["check_medications_interactions"] }

Tu peux :

  • décrire ce JSON dans un schema (OpenAPI ou JSON Schema)
  • le valider en CI
  • utiliser un agent Claude pour :
    • analyser un lot de réponses RAG
    • détecter incohérences / hallucinations
    • noter la qualité (rag_quality_score)

🔚 En résumé

  • Tu as maintenant un schéma complet “Spec-Kit + OpenAPI + CI + Claude” appliqué à Synergia.
  • L’API BFF Synergia devient :
    • contractuelle (OpenAPI)
    • testée (Jest + validation OpenAPI)
    • auditable (rapport Claude sur les écarts)
  • RAG s’insère naturellement dans ce pipeline via :
    • des schemas de réponses structurées
    • les mêmes outils de validation + Claude QA.