diff --git a/packages/api/src/business/rules-demarches/prm/oct.machine.test.ts b/packages/api/src/business/rules-demarches/prm/oct.machine.test.ts
index 58d4f9a3b7bf4cb50c1eec407a0a46a417970f39..bca8694a82e886c2136188d32ce51c96e2b12d58 100644
--- a/packages/api/src/business/rules-demarches/prm/oct.machine.test.ts
+++ b/packages/api/src/business/rules-demarches/prm/oct.machine.test.ts
@@ -7,9 +7,9 @@ import { km2Validator } from 'camino-common/src/number'
 import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes'
 import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes'
 
-describe('vérifie l’arbre d’octroi de PRM', () => {
+describe("vérifie l'arbre d'octroi de PRM", () => {
   const prmOctMachine = new PrmOctMachine(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi)
-  test('peut créer une demande d’octroi de PRM complète en Métropole', () => {
+  test("peut créer une demande d'octroi de PRM complète en Métropole", () => {
     const { tree } = setDateAndOrderAndInterpretMachine(prmOctMachine, '2022-07-01', [
       ETES.demande.FAIT,
       ETES.enregistrementDeLaDemande.FAIT,
@@ -74,7 +74,7 @@ describe('vérifie l’arbre d’octroi de PRM', () => {
     `)
   })
 
-  test('peut créer une demande d’octroi de PRM en Guyane', () => {
+  test("peut créer une demande d'octroi de PRM en Guyane", () => {
     const etapes = [
       { ...ETES.demande.FAIT, paysId: PAYS_IDS['Département de la Guyane'], surface: km2Validator.parse(200) },
       ETES.enregistrementDeLaDemande.FAIT,
@@ -107,7 +107,7 @@ describe('vérifie l’arbre d’octroi de PRM', () => {
     `)
   })
 
-  test('peut créer une demande d’octroi de PRM en Guyane sans avis du maire', () => {
+  test("peut créer une demande d'octroi de PRM en Guyane sans avis du maire", () => {
     const etapes = [
       { ...ETES.demande.FAIT, paysId: PAYS_IDS['Département de la Guyane'], surface: km2Validator.parse(14) },
       ETES.enregistrementDeLaDemande.FAIT,
@@ -139,7 +139,7 @@ describe('vérifie l’arbre d’octroi de PRM', () => {
     `)
   })
 
-  test('peut créer une demande d’octroi de PRM en Outre mer (hors Guyane)', () => {
+  test("peut créer une demande d'octroi de PRM en Outre mer (hors Guyane)", () => {
     const etapes = [
       { ...ETES.demande.FAIT, paysId: PAYS_IDS['Wallis-et-Futuna'] },
       ETES.enregistrementDeLaDemande.FAIT,
@@ -170,7 +170,7 @@ describe('vérifie l’arbre d’octroi de PRM', () => {
     `)
   })
 
-  test('ne peut pas faire l’avis de la DREAL si la saisine des services a été faite dans les 30 jours', () => {
+  test("ne peut pas faire l'avis de la DREAL si la saisine des services a été faite dans les 30 jours", () => {
     const etapes = [
       { ...ETES.demande.FAIT, paysId: PAYS_IDS['République Française'] },
       ETES.enregistrementDeLaDemande.FAIT,
@@ -200,7 +200,7 @@ describe('vérifie l’arbre d’octroi de PRM', () => {
     )
   })
 
-  test('ne peut pas ouvrir la consultation du public si la mise en concurrence n’est pas terminée', () => {
+  test("ne peut pas ouvrir la consultation du public si la mise en concurrence n'est pas terminée", () => {
     const etapes = [
       { ...ETES.demande.FAIT, paysId: PAYS_IDS['République Française'] },
       ETES.enregistrementDeLaDemande.FAIT,
diff --git a/packages/api/src/business/validations/titre-demarche-etat-validate.test.ts b/packages/api/src/business/validations/titre-demarche-etat-validate.test.ts
index 90268ff2821b2ff838c0ca1588f20de8acd6d0d0..16e21079bfc5e49926cebe204e6d4b0d38fd0fbe 100644
--- a/packages/api/src/business/validations/titre-demarche-etat-validate.test.ts
+++ b/packages/api/src/business/validations/titre-demarche-etat-validate.test.ts
@@ -15,6 +15,7 @@ import { ProcedureSpecifiqueMachine } from '../rules-demarches/procedure-specifi
 import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts'
 import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes'
 import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes'
+import { PrmOctMachine } from '../rules-demarches/prm/oct.machine'
 
 console.warn = vi.fn()
 
@@ -247,7 +248,7 @@ describe('titreDemarcheUpdatedEtatValidate', () => {
         {
           id: newEtapeId('2'),
           typeId: 'men',
-          date: toCaminoDate('2022-05-04'),
+          date: toCaminoDate('2022-05-05'),
           statutId: 'fai',
           isBrouillon: ETAPE_IS_NOT_BROUILLON,
           communes: null,
@@ -261,7 +262,7 @@ describe('titreDemarcheUpdatedEtatValidate', () => {
       ]
     )
 
-    expect(valid.valid).toBe(true)
+    expect(valid.valid, JSON.stringify(valid)).toBe(true)
   })
 
   test('l’ajout d’une étape d’une démarche historique est valide', () => {
@@ -671,6 +672,140 @@ describe('titreDemarcheUpdatedEtatValidate', () => {
 })
 
 describe('getPossiblesEtapesTypes', () => {
+  test('peut déplacer le Rapport et avis de la DREAL avant la Consultation du public pour les Octrois de Permis exclusif de recherches ', () => {
+    const apdId = newEtapeId('apiId')
+    const etapes: TitreEtapeForMachine[] = [
+      {
+        typeId: ETAPES_TYPES.rapportEtAvisDeLaDREAL,
+        date: toCaminoDate('2024-05-29'),
+        isBrouillon: ETAPE_IS_NOT_BROUILLON,
+        id: apdId,
+        ordre: 8,
+        statutId: 'fav',
+        communes: [],
+        demarcheIdsConsentement: [],
+      },
+      {
+        typeId: ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives,
+        date: toCaminoDate('2023-12-22'),
+        isBrouillon: ETAPE_IS_NOT_BROUILLON,
+        id: newEtapeId('avisDesServicesEtCommissionsConsultatives'),
+        ordre: 6,
+        statutId: 'fai',
+        communes: [],
+        demarcheIdsConsentement: [],
+      },
+      {
+        typeId: ETAPES_TYPES.consultationDuPublic,
+        date: toCaminoDate('2024-05-28'),
+        isBrouillon: ETAPE_IS_NOT_BROUILLON,
+        id: newEtapeId('ppuID'),
+        ordre: 7,
+        statutId: 'ter',
+        communes: [],
+        demarcheIdsConsentement: [],
+      },
+      {
+        typeId: ETAPES_TYPES.demande,
+        date: toCaminoDate('2023-02-28'),
+        isBrouillon: ETAPE_IS_NOT_BROUILLON,
+        id: newEtapeId('demandeId'),
+        ordre: 1,
+        statutId: 'fai',
+        communes: [{ id: toCommuneId('64012') }],
+        demarcheIdsConsentement: [],
+      },
+      {
+        typeId: ETAPES_TYPES.avisDeMiseEnConcurrenceAuJORF,
+        date: toCaminoDate('2023-09-01'),
+        isBrouillon: ETAPE_IS_NOT_BROUILLON,
+        id: newEtapeId('anf'),
+        ordre: 5,
+        statutId: 'ter',
+        communes: [{ id: toCommuneId('64012') }],
+        demarcheIdsConsentement: [],
+      },
+      {
+        typeId: ETAPES_TYPES.enregistrementDeLaDemande,
+        date: toCaminoDate('2023-05-03'),
+        isBrouillon: ETAPE_IS_NOT_BROUILLON,
+        id: newEtapeId('men'),
+        ordre: 2,
+        statutId: 'fai',
+        communes: [],
+        demarcheIdsConsentement: [],
+      },
+      {
+        typeId: ETAPES_TYPES.saisineDuPrefet,
+        date: toCaminoDate('2023-05-03'),
+        isBrouillon: ETAPE_IS_NOT_BROUILLON,
+        id: newEtapeId('spp'),
+        ordre: 3,
+        statutId: 'fai',
+        communes: [],
+        demarcheIdsConsentement: [],
+      },
+      {
+        typeId: ETAPES_TYPES.recevabiliteDeLaDemande,
+        date: toCaminoDate('2023-06-23'),
+        isBrouillon: ETAPE_IS_NOT_BROUILLON,
+        id: newEtapeId('mcr'),
+        ordre: 4,
+        statutId: 'fav',
+        communes: [],
+        demarcheIdsConsentement: [],
+      },
+    ]
+
+    expect(
+      getPossiblesEtapesTypes(
+        new PrmOctMachine(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi),
+        TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX,
+        DEMARCHES_TYPES_IDS.Octroi,
+        ETAPES_TYPES.rapportEtAvisDeLaDREAL,
+        apdId,
+        toCaminoDate('2024-05-22'),
+        etapes
+      )
+    ).toMatchInlineSnapshot(`
+      {
+        "apd": {
+          "etapeStatutIds": [
+            "fav",
+            "def",
+            "fre",
+            "dre",
+          ],
+          "mainStep": true,
+        },
+        "mec": {
+          "etapeStatutIds": [
+            "fai",
+          ],
+          "mainStep": false,
+        },
+        "mif": {
+          "etapeStatutIds": [
+            "fai",
+          ],
+          "mainStep": false,
+        },
+        "mod": {
+          "etapeStatutIds": [
+            "fai",
+          ],
+          "mainStep": false,
+        },
+        "rif": {
+          "etapeStatutIds": [
+            "fai",
+          ],
+          "mainStep": false,
+        },
+      }
+    `)
+  })
+
   test('peut créer une étape sur une procédure spécifique vide', () => {
     expect(getPossiblesEtapesTypes(new ProcedureSpecifiqueMachine('cxm', 'oct'), 'cxm', 'oct', undefined, undefined, toCaminoDate('4000-02-01'), [])).toMatchInlineSnapshot(`
       {
@@ -743,7 +878,7 @@ describe('getPossiblesEtapesTypes', () => {
       hasTitreFrom: 'non-applicable',
       isBrouillon: ETAPE_IS_NOT_BROUILLON,
       ordre: 10,
-      date: toCaminoDate('2019-12-04'),
+      date: toCaminoDate('2019-12-06'),
       dateFin: null,
       dateDebut: null,
       duree: null,
@@ -760,7 +895,7 @@ describe('getPossiblesEtapesTypes', () => {
       hasTitreFrom: 'non-applicable',
       isBrouillon: ETAPE_IS_NOT_BROUILLON,
       ordre: 14,
-      date: toCaminoDate('2020-05-22'),
+      date: toCaminoDate('2020-05-21'),
       dateFin: null,
       dateDebut: null,
       duree: null,
@@ -777,7 +912,7 @@ describe('getPossiblesEtapesTypes', () => {
       hasTitreFrom: 'non-applicable',
       isBrouillon: ETAPE_IS_NOT_BROUILLON,
       ordre: 8,
-      date: toCaminoDate('2019-12-04'),
+      date: toCaminoDate('2019-12-05'),
       dateFin: null,
       dateDebut: null,
       duree: null,
@@ -862,7 +997,7 @@ describe('getPossiblesEtapesTypes', () => {
       hasTitreFrom: 'non-applicable',
       isBrouillon: ETAPE_IS_NOT_BROUILLON,
       ordre: 6,
-      date: toCaminoDate('2019-12-04'),
+      date: toCaminoDate('2019-12-03'),
       dateFin: null,
       dateDebut: null,
       duree: null,
@@ -972,15 +1107,10 @@ describe('getPossiblesEtapesTypes', () => {
     `)
   })
 
-  test('modifie une étape existante à la même date devrait permettre de recréer la même étape', () => {
-    for (const etape of etapes) {
-      const etapesTypesPossibles = getPossiblesEtapesTypes(machine, 'arm', 'oct', undefined, etape.id, etape.date, etapes)
-      if (Object.keys(etapesTypesPossibles).length === 0) {
-        console.error(`pas d'étapes possibles à l'étape ${JSON.stringify(etape)}. Devrait contenir AU MOINS la même étape`)
-      }
-      expect(Object.keys(etapesTypesPossibles).length).toBeGreaterThan(0)
-      expect(etapesTypesPossibles[etape.typeId]).toHaveProperty('etapeStatutIds')
-    }
+  test.each(etapes)("modifie l'étape %# existante à la même date devrait permettre de recréer la même étape", etape => {
+    const etapesTypesPossibles = getPossiblesEtapesTypes(machine, 'arm', 'oct', etape.typeId, etape.id, etape.date, etapes)
+    expect(Object.keys(etapesTypesPossibles).length, `pas d'étapes possibles à l'étape ${JSON.stringify(etape)}. Devrait contenir AU MOINS la même étape`).toBeGreaterThan(0)
+    expect(etapesTypesPossibles[etape.typeId]).toHaveProperty('etapeStatutIds')
   })
 
   test('ajoute une nouvelle étape à la fin', () => {
@@ -998,7 +1128,7 @@ describe('getPossiblesEtapesTypes', () => {
 
   test('ajoute une nouvelle étape en plein milieu', () => {
     const tested = getPossiblesEtapesTypes(machine, 'arm', 'oct', undefined, undefined, toCaminoDate('2019-12-04'), etapes)
-    expect(Object.keys(tested).toSorted()).toStrictEqual(['exp', 'mod'])
+    expect(Object.keys(tested).toSorted()).toStrictEqual(['mca', 'mim', 'mod'])
   })
 
   test('peut faire une dae, une rde et pfd AVANT la mfr', () => {
diff --git a/packages/api/src/business/validations/titre-demarche-etat-validate.ts b/packages/api/src/business/validations/titre-demarche-etat-validate.ts
index ea3c25c5891db4b20b73e70bffa6f8006dde92bb..df69a3fec9286bb1bb684e6682509d495f90df80 100644
--- a/packages/api/src/business/validations/titre-demarche-etat-validate.ts
+++ b/packages/api/src/business/validations/titre-demarche-etat-validate.ts
@@ -190,21 +190,15 @@ export const getPossiblesEtapesTypes = (
 }
 
 const etapesTypesPossibleACetteDateOuALaPlaceDeLEtape = (machine: CaminoMachines, etapes: TitreEtapeForMachine[], titreEtapeId: string | null, date: CaminoDate): EtapeTypeEtapeStatutWithMainStep => {
-  const sortedEtapes = titreEtapesSortAscByOrdre(etapes)
+  const sortedEtapes = titreEtapesSortAscByOrdre(etapes).filter(etape => etape.id !== titreEtapeId)
   const etapesAvant: Etape[] = []
   const etapesApres: Etape[] = []
-  if (isNotNullNorUndefined(titreEtapeId)) {
-    const index = sortedEtapes.findIndex(etape => etape.id === titreEtapeId)
-    etapesAvant.push(...toMachineEtapes(sortedEtapes.slice(0, index)))
-    etapesApres.push(...toMachineEtapes(sortedEtapes.slice(index + 1)))
-  } else {
-    // TODO 2022-07-12: Il faudrait mieux gérer les étapes à la même date que l'étape qu'on veut rajouter
-    // elles ne sont ni avant, ni après, mais potentiellement au milieu de toutes ces étapes
-    //
 
-    etapesAvant.push(...toMachineEtapes(sortedEtapes.filter(etape => etape.date <= date)))
-    etapesApres.push(...toMachineEtapes(sortedEtapes.slice(etapesAvant.length)))
-  }
+  // TODO 2022-07-12: Il faudrait mieux gérer les étapes à la même date que l'étape qu'on veut rajouter
+  // elles ne sont ni avant, ni après, mais potentiellement au milieu de toutes ces étapes
+  // UPDATE 2025-03-31: il n'y en a pas en prod
+  etapesAvant.push(...toMachineEtapes(sortedEtapes.filter(etape => etape.date <= date)))
+  etapesApres.push(...toMachineEtapes(sortedEtapes.slice(etapesAvant.length)))
 
   const etapesPossiblesRaw = machine.possibleNextEtapes(etapesAvant, date)
   const etapesPossibles = []