diff --git a/README.md b/README.md
index eb625580405d814381aaef21755f4aac6caebba9..8a26e674b5ded1ddbb2b98776d3ed110408cdc41 100644
--- a/README.md
+++ b/README.md
@@ -229,3 +229,19 @@ Pour s'aider, on peut afficher la valeur dans la console :
 ```js
 $: console.log(parameterSmicMensuel, smicValue)
 ```
+
+### Générer les YAML de test OpenFisca à partir des cas-type LexImpact
+
+```bash
+npx tsx src/scripts/generate_openfisca_tests_yaml.ts -y 2025 ../../openfisca-france/tests/leximpact/
+```
+
+- Le paramètre `year` générera les variables d'output pour l'année `year`
+- L'argument par défaut `outdir` est le chemin où l'on veut exporter les YAML générés. Ceux-ci ont vocation à être pushés dans openfisca_france/tests/leximpact
+
+Les YAML générés contiennent, pour chaque cas-type, toutes les variables d'entrées du cas-type dans le fichier `test_cases.json`.
+Les valeurs sont mensualisées pour toutes les variables mensuelles.
+
+La section `output:` du YAML contient toutes les variables calculées, présentes à la fois dans les décompositions LexImpact **et** dans les variables du country-package Openfisca-France.
+
+Les valeurs des variables de type Enum, sont remplacées par leur index dans les valeurs possibles de l'Enum.
diff --git a/src/scripts/generate_openfisca_tests_yaml.ts b/src/scripts/generate_openfisca_tests_yaml.ts
index f64630a3bfbce8977743ede0c760d721bd4581fb..ee781d75d93ca3893bf7b4a6b8ee82ceef7e5a8a 100644
--- a/src/scripts/generate_openfisca_tests_yaml.ts
+++ b/src/scripts/generate_openfisca_tests_yaml.ts
@@ -10,8 +10,13 @@ import {
   variableSummaryByName,
 } from "$lib/variables"
 import { nonVirtualVariablesName } from "$lib/decompositions"
-import type { EntityByKey } from "@openfisca/json-model"
-import { entityByKey } from "$lib/entities"
+import type {
+  EntityByKey,
+  Entity,
+  GroupEntity,
+  PersonEntity,
+} from "@openfisca/json-model"
+import { entityByKey, personEntityKey } from "$lib/entities"
 
 type JsonObject = { [key: string]: any }
 
@@ -43,6 +48,36 @@ const optionsDefinitions = [
 ]
 const options = commandLineArgs(optionsDefinitions)
 
+async function fetchWithRetries(
+  url: string,
+  options: RequestInit,
+  maxRetries = 5,
+  delay = 10000,
+) {
+  for (let attempt = 1; attempt <= maxRetries; attempt++) {
+    try {
+      const response = await fetch(url, options)
+
+      if (response.ok) {
+        return response
+      }
+
+      console.warn(
+        `Calling Openfisca API. Attempt ${attempt} : Failed with status ${response.status}`,
+      )
+    } catch (error) {
+      console.error(`Error on attempt ${attempt} :`, error)
+    }
+
+    if (attempt < maxRetries) {
+      console.log(`New attempt in ${delay / 1000}s...`)
+      await new Promise((res) => setTimeout(res, delay))
+    }
+  }
+
+  throw new Error(`Failed calling OpenFisca API after ${maxRetries} attempts`)
+}
+
 function removeSpacesFromKeys(
   obj: JsonObject,
   replacedKeys: { [key: string]: string },
@@ -180,12 +215,25 @@ function splitVariablesByCategory(
 
   for (const [variable, value] of Object.entries(entityData)) {
     if (outputVariablesList.includes(variable)) {
-      output[variable] = value
+      if (
+        variableSummaryByName[variable].value_type === "Enum" &&
+        variableSummaryByName[variable].possible_values !== undefined
+      ) {
+        // Replace Enum values by their index in possible_values
+        const newValue: Record<string, number> = {}
+        for (const [period, periodValue] of Object.entries(value)) {
+          newValue[period] = Object.keys(
+            variableSummaryByName[variable].possible_values,
+          ).indexOf(periodValue as string)
+        }
+        output[variable] = newValue
+      } else {
+        output[variable] = value
+      }
     } else {
       input[variable] = value
     }
   }
-
   return { input, output }
 }
 
@@ -223,11 +271,13 @@ function buildYamlOutput(
   const jsonForYamlOutput: {
     name: string
     period: string
+    max_spiral_loops: number
     input: JsonObject
     output: JsonObject
   } = {
     name: name,
     period: year,
+    max_spiral_loops: 4,
     input: {},
     output: {},
   }
@@ -289,7 +339,43 @@ function getEntityKeyFromKeyPlural(
   return null
 }
 
+function isGroupEntity(entity: Entity): entity is GroupEntity {
+  return (entity as GroupEntity).roles !== undefined
+}
+
+function isKeyOrPlural(str: string): boolean {
+  const keys = Object.keys(entityByKey)
+
+  for (const key of keys) {
+    const entity = entityByKey[key]
+    if (entity.key === str || entity.key_plural === str) {
+      return true
+    }
+    if (isGroupEntity(entity) && entity.roles) {
+      for (const role of entity.roles) {
+        if (role.key === str || role.key_plural === str) {
+          return true
+        }
+        if (role.subroles) {
+          for (const subrole of role.subroles) {
+            if (subrole.key === str || subrole.key_plural === str) {
+              return true
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return false
+}
+
 async function main() {
+  console.info("Initializing...")
+  const personsEntityKey = Object.entries(entityByKey)
+    .filter(([, entity]) => entity.is_person)
+    .map(([key]) => key)[0]
+
   const year = options.year
   const outdir = options.outdir
 
@@ -323,6 +409,8 @@ async function main() {
   const testCasesCore = testCasesCoreUnknown as unknown as Situation[]
 
   for (const testCase of testCasesCore) {
+    console.info("Processing ", testCase.id)
+    let testCaseContainsMissingVariable = false
     let jsonForApiCall: JsonObject = {}
     const outputVariablesList: Array<string> = []
 
@@ -332,6 +420,7 @@ async function main() {
 
     const sections = ["familles", "foyers_fiscaux", "menages", "individus"]
 
+    // Mensualise monthly input variables
     for (const section of sections) {
       if (testCase[section] !== undefined) {
         for (const entityKey in testCase[section]) {
@@ -344,12 +433,27 @@ async function main() {
                 testCase[section][entityKey][variable],
                 variable,
               )
+            } else if (
+              !openFiscaVariablesList.hasOwnProperty(variable) &&
+              !isKeyOrPlural(variable)
+            ) {
+              console.warn(
+                "variable",
+                variable,
+                "does not exists in openFisca-France.",
+              )
+              testCaseContainsMissingVariable = true
             }
           }
         }
       }
     }
 
+    if (testCaseContainsMissingVariable) {
+      console.warn("Ignoring test case", testCase.id)
+      continue
+    }
+
     for (const section of sections) {
       if (testCase[section] !== undefined) {
         jsonForApiCall.input[section] = removeSpacesFromKeys(
@@ -397,205 +501,41 @@ async function main() {
       }
     }
 
-    // {
-    //     // INDIVIDUS
-    //     if (testCase.individus !== undefined) {
-    //       jsonForApiCall.input.individus = removeSpacesFromKeys(
-    //         testCase.individus,
-    //         replacedKeys,
-    //       )
-    //       for (const individuKey in jsonForApiCall.input.individus) {
-    //         for (const variable of variablesToCalculate) {
-    //           //   console.log(variable)
-    //           if (variableSummaryByName[variable] !== undefined) {
-    //             if (
-    //               variableSummaryByName[variable].entity === "individu" &&
-    //               jsonForApiCall.input.individus[individuKey][variable] ===
-    //                 undefined
-    //             ) {
-    //               outputVariablesList.push(variable)
-    //               switch (variableSummaryByName[variable].definition_period) {
-    //                 case "year": {
-    //                   jsonForApiCall.input.individus[individuKey][variable] = {
-    //                     [year]: null,
-    //                   }
-    //                   break
-    //                 }
-    //                 case "month": {
-    //                   const monthVariableSection = {}
-    //                   for (let month = 1; month <= 12; month++) {
-    //                     const monthString = month < 10 ? "0" + month : month
-    //                     const monthPeriod = year + "-" + monthString
-    //                     Object.assign(monthVariableSection, { [monthPeriod]: null })
-    //                   }
-    //                   jsonForApiCall.input.individus[individuKey][variable] =
-    //                     monthVariableSection
-    //                 }
-    //               }
-    //             }
-    //           } else {
-    //             console.log("cette variable n'existe pas dans summary : ", variable)
-    //           }
-    //         }
-    //       }
-    //     } else {
-    //       console.error("No section 'individus' in file ", testCase)
-    //     }
-
-    //     // MENAGES
-    //     if (testCase.menages !== undefined) {
-    //       jsonForApiCall.input.menages = removeSpacesFromKeys(
-    //         testCase.menages,
-    //         replacedKeys,
-    //       )
-    //       for (const menageKey in jsonForApiCall.input.menages) {
-    //         for (const variable of variablesToCalculate) {
-    //           if (variableSummaryByName[variable] !== undefined) {
-    //             if (variableSummaryByName[variable].entity === "menage") {
-    //               outputVariablesList.push(variable)
-    //               switch (variableSummaryByName[variable].definition_period) {
-    //                 case "year": {
-    //                   jsonForApiCall.input.menages[menageKey][variable] = {
-    //                     [year]: null,
-    //                   }
-    //                   break
-    //                 }
-    //                 case "month": {
-    //                   const monthVariableSection = {}
-    //                   for (let month = 1; month <= 12; month++) {
-    //                     const monthString = month < 10 ? "0" + month : month
-    //                     const monthPeriod = year + "-" + monthString
-    //                     Object.assign(monthVariableSection, { [monthPeriod]: null })
-    //                   }
-    //                   jsonForApiCall.input.menages[menageKey][variable] =
-    //                     monthVariableSection
-    //                 }
-    //               }
-    //             }
-    //           } else {
-    //             // console.log("cette variable n'existe pas dans summary : ", variable)
-    //           }
-    //         }
-    //       }
-    //     } else {
-    //       console.warn("No section 'menages' in file ", testCase)
-    //     }
-
-    //     // FOYERS FISCAUX
-    //     if (testCase.foyers_fiscaux !== undefined) {
-    //       jsonForApiCall.input.foyers_fiscaux = removeSpacesFromKeys(
-    //         testCase.foyers_fiscaux,
-    //         replacedKeys,
-    //       )
-    //       for (const foyerFiscalKey in jsonForApiCall.input.foyers_fiscaux) {
-    //         for (const variable of variablesToCalculate) {
-    //           if (variableSummaryByName[variable] !== undefined) {
-    //             if (variableSummaryByName[variable].entity === "foyer_fiscal") {
-    //               outputVariablesList.push(variable)
-    //               switch (variableSummaryByName[variable].definition_period) {
-    //                 case "year": {
-    //                   jsonForApiCall.input.foyers_fiscaux[foyerFiscalKey][
-    //                     variable
-    //                   ] = {
-    //                     [year]: null,
-    //                   }
-    //                   break
-    //                 }
-    //                 case "month": {
-    //                   const monthVariableSection = {}
-    //                   for (let month = 1; month <= 12; month++) {
-    //                     const monthString = month < 10 ? "0" + month : month
-    //                     const monthPeriod = year + "-" + monthString
-    //                     Object.assign(monthVariableSection, { [monthPeriod]: null })
-    //                   }
-    //                   jsonForApiCall.input.foyers_fiscaux[foyerFiscalKey][
-    //                     variable
-    //                   ] = monthVariableSection
-    //                 }
-    //               }
-    //             }
-    //           } else {
-    //             // console.log("cette variable n'existe pas dans summary : ", variable)
-    //           }
-    //         }
-    //       }
-    //     } else {
-    //       console.warn("No section 'foyers_fiscaux' in file ", testCase)
-    //     }
-
-    //     // FAMILLES
-    //     if (testCase.familles !== undefined) {
-    //       jsonForApiCall.input.familles = removeSpacesFromKeys(
-    //         testCase.familles,
-    //         replacedKeys,
-    //       )
-    //       for (const familleKey in jsonForApiCall.input.familles) {
-    //         for (const variable of variablesToCalculate) {
-    //           if (variableSummaryByName[variable] !== undefined) {
-    //             if (variableSummaryByName[variable].entity === "famille") {
-    //               outputVariablesList.push(variable)
-    //               switch (variableSummaryByName[variable].definition_period) {
-    //                 case "year": {
-    //                   jsonForApiCall.input.familles[familleKey][variable] = {
-    //                     [year]: null,
-    //                   }
-    //                   break
-    //                 }
-    //                 case "month": {
-    //                   const monthVariableSection = {}
-    //                   for (let month = 1; month <= 12; month++) {
-    //                     const monthString = month < 10 ? "0" + month : month
-    //                     const monthPeriod = year + "-" + monthString
-    //                     Object.assign(monthVariableSection, { [monthPeriod]: null })
-    //                   }
-    //                   jsonForApiCall.input.familles[familleKey][variable] =
-    //                     monthVariableSection
-    //                 }
-    //               }
-    //             }
-    //           } else {
-    //             // console.log("cette variable n'existe pas dans summary : ", variable)
-    //           }
-    //         }
-    //       }
-    //     } else {
-    //       console.warn("No section 'familles' in file ", testCase)
-    //     }
-    //   }
     jsonForApiCall = replaceValuesFromReplacedKeys(jsonForApiCall, replacedKeys)
-
-    // fs.writeFile(
-    //   path.join(".", testCase.id + ".json"),
-    //   JSON.stringify(jsonForApiCall.input, null, 2),
-    // )
-
-    const simulatedTestCaseFromOpenFiscaApi = await fetch(
-      "https://api.fr.openfisca.org/latest/calculate",
-      // "http://localhost:5000/calculate",
-      {
-        body: JSON.stringify(jsonForApiCall.input),
-        headers: {
-          Accept: "application/json",
-          "Content-Type": "application/json; charset=utf-8",
-        },
-        method: "POST",
+    console.info("Launching simulation on OpenFisca France API...")
+    const openFiscaApiUrl = "https://api.fr.openfisca.org/latest/calculate"
+    const openFiscaApiOptions: RequestInit = {
+      body: JSON.stringify(jsonForApiCall.input),
+      headers: {
+        Accept: "application/json",
+        "Content-Type": "application/json; charset=utf-8",
       },
-    )
-    if (!simulatedTestCaseFromOpenFiscaApi.ok) {
-      console.error(
-        `Error ${
-          simulatedTestCaseFromOpenFiscaApi.status
-        } while calling Openfisca France API`,
-      )
-      return
+      method: "POST",
     }
+    let simulatedTestCaseFromOpenFiscaApi: Response | null = null
 
+    try {
+      simulatedTestCaseFromOpenFiscaApi = await fetchWithRetries(
+        openFiscaApiUrl,
+        openFiscaApiOptions,
+      )
+
+      if (!simulatedTestCaseFromOpenFiscaApi.ok) {
+        console.error(
+          `Giving up calling openFisca API because of status ${simulatedTestCaseFromOpenFiscaApi.status}`,
+        )
+        return
+      }
+    } catch (error) {
+      console.error("Error : ", error)
+    }
+    console.info("Post-processing...")
     const simulatedTestCase = cleanSimulatedJson(
-      await simulatedTestCaseFromOpenFiscaApi.json(),
+      await simulatedTestCaseFromOpenFiscaApi!.json(),
     )
 
     const jsonForYamlOutput = buildYamlOutput(
-      testCase.id,
+      testCase.id!,
       year,
       simulatedTestCase,
       outputVariablesList,
@@ -609,6 +549,7 @@ async function main() {
     // Remove quotes around year keys
     const cleanedYaml = yamlOutput.replace(/'(\d{4})':/g, "$1:")
     await fs.writeFile(path.join(outdir, testCase.id + ".yml"), cleanedYaml)
+    console.info("YAML file written :", outdir, testCase.id + ".yml")
   }
 }