{
  "name": "WorkFlow 05.03",
  "nodes": [
    {
      "parameters": {},
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        592,
        656
      ],
      "id": "1847b70d-1106-40dc-b859-61bfa22a009f",
      "name": "Merge1"
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "_lastNode",
              "value": "={{ ($workflow.name || 'Unknown Workflow') + \" - \" + ($json._log?.actions?.find(action => !action.ok)?.node || Object.keys($json._log?.failedNodes || {})[0] || 'UnknownNode') }}"
            },
            {
              "name": "_hadError",
              "value": "={{ $json.error !== undefined }}"
            },
            {
              "name": "_errMsg",
              "value": "={{ $json.error?.message || ''}}"
            }
          ]
        },
        "options": {}
      },
      "id": "75cc615f-7cb7-4297-b9b0-613063b4d65f",
      "name": "Log Snapshot3",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        1216,
        400
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "functionCode": "return items.map(i => {\n  const log = i.json._log || {};\n  \n  // LIGNE 5 CORRIG\u00c9E\n  const nodeName = i.json._lastNode || 'UnknownNode';\n  \n  const failed = !!i.json._hadError || !!i.json.error;\n  \n  // Message adaptatif\n  const msg = i.json.error?.message || \n              i.json._errMsg || \n              (failed ? 'Erreur d\u00e9tect\u00e9e' : 'Succ\u00e8s');\n  \n  (log.actions ||= []).push({ node: nodeName, ok: !failed, msg });\n  \n  if (failed) {\n    log.ko = (log.ko || 0) + 1;\n    log.failedNodes = log.failedNodes || {};\n    log.failedNodes[nodeName] = true;\n  } else {\n    log.ok = (log.ok || 0) + 1;\n  }\n  \n  i.json._log = log;\n  return i;\n});"
      },
      "id": "70b04787-d937-4683-961f-a71afc182e2b",
      "name": "Update Log2",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        -1952,
        688
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "_lastNode",
              "value": "={{ ($workflow.name || 'Unknown Workflow') + \" - \" + ($json._log?.actions?.find(action => !action.ok)?.node || Object.keys($json._log?.failedNodes || {})[0] || 'UnknownNode') }}"
            },
            {
              "name": "_hadError",
              "value": "={{ $json.error !== undefined }}"
            },
            {
              "name": "_errMsg",
              "value": "={{ $json.error?.message || ''}}"
            }
          ]
        },
        "options": {}
      },
      "id": "44e6ba1d-a8f3-4d5e-a203-07712dc94359",
      "name": "Log Snapshot1",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        -2144,
        688
      ]
    },
    {
      "parameters": {
        "resource": "block",
        "operation": "getAll",
        "blockId": {
          "__rl": true,
          "value": "={{ $('Workflow 05.03').item.json[\"T\u00e2cheid\"] }}",
          "mode": "id"
        },
        "returnAll": true,
        "fetchNestedBlocks": true,
        "simplifyOutput": false
      },
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        -1552,
        224
      ],
      "id": "80aa3d8f-8629-4209-80d4-a2960a1b8b26",
      "name": "Get many child blocks",
      "alwaysOutputData": true,
      "executeOnce": true,
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "jsCode": "/**\n * Format 1 bloc \u2014 \u00e0 placer dans la Loop (Split in Batches = 1)\n * Entr\u00e9e : { top, childrenMap, dest_id, root }\n * Sortie : [{\n *   dest_id,\n *   children_payload: { children: [ formattedWithChildren ] },\n *   debug: {...}\n * }]\n */\n\nconst original = $json.top;\nconst childrenMap = $json.childrenMap || {};\nconst destId = $json.dest_id;\nconst rootInfo = $json.root || null;\n\nfunction detectType(block) {\n  if (typeof block?.type === 'string' && block[block.type]) return block.type;\n  const KNOWN = ['paragraph','heading_1','heading_2','heading_3','bulleted_list_item','numbered_list_item','to_do','toggle','quote','code','callout','divider','table_of_contents','link_to_page','synced_block','bookmark','image','video','pdf','file','column_list','column','table','table_row','equation'];\n  for (const k of KNOWN) if (block && block[k]) return k;\n  if (block?.unsupported) return 'unsupported';\n  return null;\n}\n\nfunction rt(node) {\n  if (!node) return [{ type:'text', text:{ content:'' }, annotations:{ bold:false, italic:false, strikethrough:false, underline:false, code:false, color:'default' }, plain_text:'', href:null }];\n  if (Array.isArray(node.text)) return node.text;\n  if (Array.isArray(node.rich_text)) return node.rich_text;\n  return [{ type:'text', text:{ content:'' }, annotations:{ bold:false, italic:false, strikethrough:false, underline:false, code:false, color:'default' }, plain_text:'', href:null }];\n}\n\nfunction getChildrenOf(id) {\n  const arr = childrenMap[id];\n  return Array.isArray(arr) ? arr : [];\n}\n\nfunction formatOne(b) {\n  const t = detectType(b) || 'paragraph';\n  let out = { object:'block', type:t };\n\n  switch (t) {\n    case 'paragraph':\n      out.paragraph = { rich_text: rt(b.paragraph), color: b.paragraph?.color || 'default' };\n      break;\n    case 'heading_1':\n      out.heading_1 = { rich_text: rt(b.heading_1), color: b.heading_1?.color || 'default', is_toggleable: false };\n      break;\n    case 'heading_2':\n      out.heading_2 = { rich_text: rt(b.heading_2), color: b.heading_2?.color || 'default', is_toggleable: false };\n      break;\n    case 'heading_3':\n      out.heading_3 = { rich_text: rt(b.heading_3), color: b.heading_3?.color || 'default', is_toggleable: false };\n      break;\n    case 'bulleted_list_item':\n      out.bulleted_list_item = { rich_text: rt(b.bulleted_list_item), color: b.bulleted_list_item?.color || 'default' };\n      break;\n    case 'numbered_list_item':\n      out.numbered_list_item = { rich_text: rt(b.numbered_list_item), color: b.numbered_list_item?.color || 'default' };\n      break;\n    case 'to_do':\n      out.to_do = { rich_text: rt(b.to_do), checked: b.to_do?.checked || false, color: b.to_do?.color || 'default' };\n      break;\n    case 'quote':\n      out.quote = { rich_text: rt(b.quote), color: b.quote?.color || 'default' };\n      break;\n    case 'code':\n      out.code = { rich_text: rt(b.code), language: b.code?.language || 'plain text', caption: Array.isArray(b.code?.caption)? b.code.caption : [] };\n      break;\n    case 'divider':\n      out.divider = {}; break;\n    case 'callout':\n      out.callout = { rich_text: rt(b.callout), icon: b.callout?.icon ?? { emoji:'\ud83d\udca1' }, color: b.callout?.color || 'default' };\n      break;\n    case 'toggle':\n      out.toggle = { rich_text: rt(b.toggle), color: b.toggle?.color || 'default' };\n      break;\n    default:\n      out.type = 'paragraph';\n      out.paragraph = { rich_text: [{ type:'text', text:{ content:'[Bloc converti]' }, annotations:{ bold:false, italic:false, strikethrough:false, underline:false, code:false, color:'default' }, plain_text:'[Bloc converti]', href:null }], color: 'default' };\n      break;\n  }\n\n  const kids = getChildrenOf(b.id);\n  if (kids.length > 0) {\n    out.children = kids.map(ch => formatOne(ch));\n    if (t === 'heading_1' && out.heading_1) out.heading_1.is_toggleable = true;\n    if (t === 'heading_2' && out.heading_2) out.heading_2.is_toggleable = true;\n    if (t === 'heading_3' && out.heading_3) out.heading_3.is_toggleable = true;\n  }\n  return out;\n}\n\nconst formatted = formatOne(original);\nconst payload = { children: [ formatted ] };\n\nreturn [{\n  json: {\n    dest_id: destId,\n    children_payload: payload,\n    debug: {\n      root: rootInfo,\n      source_block_id: original.id,\n      children_count: (childrenMap[original.id]?.length || 0)\n    }\n  }\n \n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        224
      ],
      "id": "f500494a-c0a9-4d99-99bf-ca876a823242",
      "name": "Code",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        -944,
        208
      ],
      "id": "23c1a35e-b19f-4cda-bac9-b31407b7ab0c",
      "name": "Loop Over Items1"
    },
    {
      "parameters": {
        "method": "PATCH",
        "url": "=https://api.notion.com/v1/blocks/{{ $json.parentId }}/children",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "notionApi",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({ children: [ $json.block ] }) }}",
        "options": {
          "batching": {
            "batch": {}
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -176,
        224
      ],
      "id": "04b5e6c6-a988-4ca3-b4ad-439dd8cb39f7",
      "name": "HTTP Request",
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        },
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "jsCode": "/**\n * Index Children \u2014 MULTI-PAGE\n * - Construit childrenMap (parent_block_id -> [children])\n * - D\u00e9tecte TOUTES les pages sources pr\u00e9sentes dans l'input\n * - \u00c9met un item par bloc top-level POUR CHAQUE page\n * - Supporte un mapping optionnel source_page_id -> dest_id\n *\n * Entr\u00e9e: items (top-level + sous-blocs) de plusieurs pages possibles\n * Sortie: [{ json: { top, childrenMap, dest_id, root:{type:'page', id:'...'} } }, ...]\n */\n\nfunction normId(s){ return (s||'').toString().replace(/-/g,'').toLowerCase(); }\n\n// 1) Tous les blocs\nconst all = $input.all().map(i => i.json);\n\n// 2) Destination par d\u00e9faut (optionnelle)\nlet defaultDestId;\ntry { defaultDestId = $('Set Destination').first().json.destination_id; } catch (e) {}\nif (!defaultDestId) { try { defaultDestId = $('Create Archive Equipement').first().json.id; } catch (e) {} }\n\n// 3) Mapping source_page_id -> dest_id (OPTIONNEL)\n//   Cr\u00e9e un node \"Set Destinations\" en amont qui renvoie plusieurs lignes {source_page_id, dest_id}\nconst destMap = {};\ntry {\n  const rows = $('Set Destinations').all().map(n => n.json);\n  for (const r of rows) {\n    if (r?.source_page_id && r?.dest_id) destMap[normId(r.source_page_id)] = String(r.dest_id);\n  }\n} catch (e) { /* mapping absent = OK */ }\n\n// 4) Roots explicites ? (si tu gardes un \u201cSet Root\u201d, on ne traite QUE celle-ci)\nlet explicitRoot = null;\ntry {\n  const r = $('Set Root').first().json;\n  if (r?.root_id) explicitRoot = { type: String(r.root_type || 'page'), id: String(r.root_id) };\n} catch (e) {}\n\n// 5) Construire childrenMap global (OK multi-pages, ids Notion sont uniques)\nconst childrenMap = {}; // { [blockId]: Block[] }\nfor (const b of all) {\n  if (b?.parent?.type === 'block_id' && b.parent.block_id) {\n    const pid = b.parent.block_id;\n    if (!childrenMap[pid]) childrenMap[pid] = [];\n    childrenMap[pid].push(b);\n  }\n}\n\n// 6) Lister les pages pr\u00e9sentes dans l'input\nconst pagesSeen = new Map(); // normPageId -> rawPageId\nfor (const b of all) {\n  if (b?.parent?.type === 'page_id' && b.parent.page_id) {\n    const nid = normId(b.parent.page_id);\n    if (!pagesSeen.has(nid)) pagesSeen.set(nid, b.parent.page_id);\n  }\n}\n\n// 7) D\u00e9terminer les roots \u00e0 traiter\nlet roots = [];\nif (explicitRoot?.type === 'page' && explicitRoot.id) {\n  roots = [ explicitRoot ];\n} else {\n  // traite TOUTES les pages rencontr\u00e9es\n  roots = [...pagesSeen.entries()].map(([nid, raw]) => ({ type: 'page', id: raw }));\n  // fallback : s\u2019il n\u2019y a aucune page vue (rare), tente une heuristique\n  if (roots.length === 0) {\n    const firstTop = all.find(x => x?.parent?.type==='page_id' && x.parent.page_id);\n    if (firstTop) roots = [{ type:'page', id:firstTop.parent.page_id }];\n  }\n}\n\n// 8) Construire la sortie : tous les top-level de chaque page, avec dest_id d\u00e9di\u00e9\nconst out = [];\nfor (const root of roots) {\n  const rid = normId(root.id);\n  const topLevel = all.filter(b => b?.parent?.type === 'page_id' && normId(b.parent.page_id) === rid);\n\n  // destination pour CETTE page : mapping > d\u00e9faut > undefined (on laisse HTTP \u00e9chouer proprement si vide)\n  const destForThisPage = destMap[rid] || defaultDestId || undefined;\n\n  for (const b of topLevel) {\n    out.push({\n      json: { top: b, childrenMap, dest_id: destForThisPage, root }\n    });\n  }\n}\n\nreturn out;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1360,
        208
      ],
      "id": "f075e0ab-a40a-44dd-93db-c535150ecc33",
      "name": "Index Children",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "/**\n * Build Cascade Queue \u2014 retire `children` du parent et seed la file\n */\nconst destId = $json.dest_id;\nconst parent = ($json.children_payload?.children || [])[0];\n\nif (!destId || !parent) {\n  return [{ json: { error: 'missing_dest_or_parent' } }];\n}\n\n// strip children au parent\nconst kids = Array.isArray(parent.children) ? parent.children : [];\nconst parentNoKids = { ...parent };\ndelete parentNoKids.children;\n\n// initialise la file avec 1 t\u00e2che \"cr\u00e9er le parent sous destId\"\nconst queue = [{\n  parentId: destId,\n  block: parentNoKids,\n  children: kids\n}];\n\nreturn [{ json: { queue } }];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -544,
        224
      ],
      "id": "ca93897c-56c5-4f0a-9d32-982651fde855",
      "name": "Build case Q",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "/**\n * Pop Task \u2014 sort la prochaine t\u00e2che de la file\n */\nconst q = Array.isArray($json.queue) ? $json.queue : [];\nif (q.length === 0) {\n  return [{ json: { done: true, queue: [] } }];\n}\n\nconst task = q.shift();\nreturn [{\n  json: {\n    done: false,\n    queue: q,                     // \u2190 gard\u00e9 pour Merge/After\n    parentId: task.parentId,      // \u2190 utilis\u00e9 par HTTP URL\n    block: task.block,            // \u2190 utilis\u00e9 par HTTP body (sans children !)\n    children: task.children || [] // \u2190 gard\u00e9 pour After Append\n  }\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -352,
        224
      ],
      "id": "da19a709-a836-4634-bbf0-19c050f8cc3d",
      "name": "pop task",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "/**\n * After Append \u2014 version \"apr\u00e8s Merge (Pass Through)\"\n * Entr\u00e9e (depuis Merge):\n *  - champs de Pop Task: queue[], children[], parentId, block\n *  - r\u00e9ponse HTTP Notion: results[0].id, etc.\n * Sortie:\n *  - { queue: [...prochaines t\u00e2ches...] }\n */\n\n// 1) Lire la r\u00e9ponse Notion (c\u00f4t\u00e9 HTTP)\nconst resp = $json; // Merge a copi\u00e9 la r\u00e9ponse HTTP dans le m\u00eame objet\nconst results = resp.results || resp.data?.results || [];\nconst newId = results[0]?.id;\n\n// 2) Lire la file et les enfants venant de Pop Task (conserv\u00e9s par le Merge)\nlet q = Array.isArray($json.queue) ? $json.queue : [];\nconst kids = Array.isArray($json.children) ? $json.children : [];\n\n// 3) Si l'API n'a pas renvoy\u00e9 d'ID, on log et on continue (ou tu peux throw si tu veux stopper)\nif (!newId) {\n  return [{\n    json: { error: 'append_failed_no_id', queue: q, debug: { resp_has_results: results.length } }\n  }];\n}\n\n// 4) Chaque enfant devient une t\u00e2che sous newId (strip de ses propres children)\nfunction strip(b) {\n  const copy = { ...b };\n  const k = Array.isArray(b.children) ? b.children : [];\n  delete copy.children;\n  return { copy, k };\n}\n\nfor (const child of kids) {\n  const { copy, k } = strip(child);\n  q.push({ parentId: newId, block: copy, children: k });\n}\n\n// 5) Retourner la nouvelle queue\nreturn [{ json: { queue: q } }];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        64,
        384
      ],
      "id": "622a0370-bf32-47fb-b50a-7776be9cb419",
      "name": "After Append Block",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "3c57946b-89b4-4b4e-b158-c3962400c2c5",
              "leftValue": "={{ Array.isArray($json.queue) && $json.queue.length > 0 }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        288,
        384
      ],
      "id": "d8faaf57-73e7-4530-99ef-48089cb11047",
      "name": "If",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        -160,
        384
      ],
      "id": "bcef57b4-e2e8-4428-98a5-5516059c8cf4",
      "name": "Merge",
      "alwaysOutputData": true,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "archive",
        "pageId": {
          "__rl": true,
          "value": "={{ $('Workflow 05.03').item.json[\"T\u00e2cheid\"] }}",
          "mode": "id"
        }
      },
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        64,
        16
      ],
      "id": "f89fa886-dbfc-4e9f-a565-de82a3bd3582",
      "name": "Archive page",
      "executeOnce": true,
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "functionCode": "return items.map(i => {\n  const log = i.json._log || {};\n  \n  // LIGNE 5 CORRIG\u00c9E\n  const nodeName = i.json._lastNode || 'UnknownNode';\n  \n  const failed = !!i.json._hadError || !!i.json.error;\n  \n  // Message adaptatif\n  const msg = i.json.error?.message || \n              i.json._errMsg || \n              (failed ? 'Erreur d\u00e9tect\u00e9e' : 'Succ\u00e8s');\n  \n  (log.actions ||= []).push({ node: nodeName, ok: !failed, msg });\n  \n  if (failed) {\n    log.ko = (log.ko || 0) + 1;\n    log.failedNodes = log.failedNodes || {};\n    log.failedNodes[nodeName] = true;\n  } else {\n    log.ok = (log.ok || 0) + 1;\n  }\n  \n  i.json._log = log;\n  return i;\n});"
      },
      "id": "1018457a-0e12-4b88-9105-569564c00b92",
      "name": "Update Log",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        288,
        240
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "_lastNode",
              "value": "={{ ($workflow.name || 'Unknown Workflow') + \" - \" + ($json._log?.actions?.find(action => !action.ok)?.node || Object.keys($json._log?.failedNodes || {})[0] || 'UnknownNode') }}"
            },
            {
              "name": "_hadError",
              "value": "={{ $json.error !== undefined }}"
            },
            {
              "name": "_errMsg",
              "value": "={{ $json.error?.message || ''}}"
            }
          ]
        },
        "options": {}
      },
      "id": "d5493120-6695-454a-9be1-e98a74278e0a",
      "name": "Log Snapshot",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        64,
        240
      ]
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        976,
        400
      ],
      "id": "f240cf85-d3e8-4005-a555-b2075f339753",
      "name": "Merge3"
    },
    {
      "parameters": {
        "functionCode": "return items.map(i => {\n  const log = i.json._log || {};\n  \n  // LIGNE 5 CORRIG\u00c9E\n  const nodeName = i.json._lastNode || 'UnknownNode';\n  \n  const failed = !!i.json._hadError || !!i.json.error;\n  \n  // Message adaptatif\n  const msg = i.json.error?.message || \n              i.json._errMsg || \n              (failed ? 'Erreur d\u00e9tect\u00e9e' : 'Succ\u00e8s');\n  \n  (log.actions ||= []).push({ node: nodeName, ok: !failed, msg });\n  \n  if (failed) {\n    log.ko = (log.ko || 0) + 1;\n    log.failedNodes = log.failedNodes || {};\n    log.failedNodes[nodeName] = true;\n  } else {\n    log.ok = (log.ok || 0) + 1;\n  }\n  \n  i.json._log = log;\n  return i;\n});"
      },
      "id": "562d89db-7efc-4a25-8c3a-09ce51494322",
      "name": "Update Log3",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        -1168,
        208
      ]
    },
    {
      "parameters": {
        "functionCode": "return items.map(i => {\n  const log = i.json._log || {};\n  \n  // LIGNE 5 CORRIG\u00c9E\n  const nodeName = i.json._lastNode || 'UnknownNode';\n  \n  const failed = !!i.json._hadError || !!i.json.error;\n  \n  // Message adaptatif\n  const msg = i.json.error?.message || \n              i.json._errMsg || \n              (failed ? 'Erreur d\u00e9tect\u00e9e' : 'Succ\u00e8s');\n  \n  (log.actions ||= []).push({ node: nodeName, ok: !failed, msg });\n  \n  if (failed) {\n    log.ko = (log.ko || 0) + 1;\n    log.failedNodes = log.failedNodes || {};\n    log.failedNodes[nodeName] = true;\n  } else {\n    log.ok = (log.ok || 0) + 1;\n  }\n  \n  i.json._log = log;\n  return i;\n});"
      },
      "id": "1276708d-a0b4-4c68-8d41-a486dea9ead6",
      "name": "Update Log4",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        -176,
        16
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "acd45495-b47b-40d5-8ada-6d4129baaf98",
              "name": "ResponsableID",
              "value": "={{ $('Workflow 05.03').item.json.ResponsableID }}",
              "type": "string"
            },
            {
              "id": "be122791-58bf-4682-9263-8219b7d9bdcb",
              "name": "\u00c9quipeID",
              "value": "={{ $('Workflow 05.03').item.json[\"\u00c9quipeID\"] }}",
              "type": "string"
            },
            {
              "id": "65c4a217-dde3-43a3-9fab-7114f59eda05",
              "name": "Departement",
              "value": "={{ $('Workflow 05.03').item.json.Departement }}",
              "type": "string"
            },
            {
              "id": "20f4be72-54de-4cac-886a-92a7e71d81c1",
              "name": "id",
              "value": "={{ $json.id }}",
              "type": "string"
            },
            {
              "id": "16d1c080-158c-465e-86aa-a04a2e92204b",
              "name": "T\u00e2cheid",
              "value": "={{ $('Workflow 05.03').item.json[\"T\u00e2cheid\"] }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -1952,
        208
      ],
      "id": "c18abfe6-4002-410f-8339-7c013ed3e355",
      "name": "Edit Equipement Participant"
    },
    {
      "parameters": {
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "value": "{{NOTION_DB_ID_ARCHIVES_CONTROLES_DES_EQUIPEMENTS}}",
          "mode": "list",
          "cachedResultName": "Archives Contr\u00f4les des \u00c9quipements ",
          "cachedResultUrl": "https://www.notion.so/{{NOTION_DB_ID_ARCHIVES_CONTROLES_DES_EQUIPEMENTS}}"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Nom|title",
              "title": "={{ $json[\"T\u00e2che\"] }}"
            },
            {
              "key": "Date de planification|date",
              "includeTime": false,
              "date": "={{ $json[\"Date de planification\"].date.start }}"
            },
            {
              "key": "Dead line|date",
              "includeTime": false,
              "date": "={{ $json[\"Dead line\"].date.start }}"
            },
            {
              "key": "Date compl\u00e9t\u00e9|date",
              "includeTime": false,
              "date": "={{ $json[\"Date compl\u00e9t\u00e9\"].date.start }}"
            },
            {
              "key": "Types de tache|rich_text",
              "textContent": "={{ $json[\"Type de t\u00e2che\"] || \"\" }}"
            },
            {
              "key": "\u00c9tat|rich_text",
              "textContent": "={{ $json[\"\u00c9tat\"] || \"\" }}"
            },
            {
              "key": "Cr\u00e9ateur|rich_text",
              "textContent": "={{ $json[\"Cr\u00e9ateur\"] || \"\" }}"
            },
            {
              "key": "Priorit\u00e9|rich_text",
              "textContent": "={{ $json[\"Priorit\u00e9\"] || \"\" }}"
            },
            {
              "key": "Note|rich_text",
              "textContent": "={{ $json.Note }}"
            },
            {
              "key": "Ticket|number",
              "numberValue": "={{ $json.Ticket || \"\" }}"
            },
            {
              "key": "Nom Responssable|rich_text",
              "textContent": "={{ $json.Approbateur || \"\" }}"
            },
            {
              "key": "Mention|rich_text",
              "textContent": "={{ $json.Mention || \"\" }}"
            },
            {
              "key": "Approuv\u00e9e|rich_text",
              "textContent": "={{ $json.Verification || \"\" }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        -2176,
        224
      ],
      "id": "2887664f-7749-4ddd-81ef-a780453197af",
      "name": "Create Archive Equipement",
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput",
      "notes": "Archives Qualit\u00e9 : {{NOTION_DB_ID_ARCHIVES_QUALITE}}"
    },
    {
      "parameters": {
        "inputSource": "passthrough"
      },
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1.1,
      "position": [
        -2384,
        224
      ],
      "id": "49e8f739-394a-42cc-94b0-d397542f7439",
      "name": "Workflow 05.03",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const allLogs = $input.all();\n\nconst consolidated = {\n  workflow: allLogs[0].json._log?.workflow,\n  startedAt: allLogs[0].json._log?.startedAt,\n  finishedAt: new Date().toISOString(),\n  ok: allLogs.reduce((sum, item) => sum + (item.json._log?.ok || 0), 0),\n  ko: allLogs.reduce((sum, item) => sum + (item.json._log?.ko || 0), 0),\n  \n  // R\u00e9cup\u00e9ration des nodes en \u00e9chec (inchang\u00e9)\n  failedNodes: allLogs.reduce((acc, item) => {\n    if (item.json._hadError || item.json.error) {\n      const nodeName = item.json._lastNode || item.json.error?.name || 'UnknownNode';\n      acc[nodeName] = {\n        error: true,\n        message: item.json.error?.message || item.json._errMsg || 'Erreur inconnue'\n      };\n    }\n    return acc;\n  }, {}),\n  \n  // CORRECTION : R\u00e9cup\u00e9rer les vraies actions depuis _log.actions\n  actions: allLogs.reduce((acc, item) => {\n    // R\u00e9cup\u00e9rer les actions existantes dans _log.actions\n    const existingActions = item.json._log?.actions || [];\n    \n    // Ajouter les actions existantes\n    acc.push(...existingActions);\n    \n    // Si il y a une erreur globale sur cet item, ajouter une action d'erreur\n    if (item.json._hadError || item.json.error) {\n      const nodeName = item.json._lastNode || item.json.error?.name || 'UnknownNode';\n      acc.push({\n        node: nodeName,\n        ok: false,\n        msg: item.json.error?.message || item.json._errMsg || 'Erreur'\n      });\n    }\n    \n    return acc;\n  }, [])\n};\n\nreturn [{ json: { _log: consolidated } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1408,
        400
      ],
      "id": "e4e11b85-111b-4846-9aeb-06cbbcf6a482",
      "name": "Returns item"
    },
    {
      "parameters": {
        "mode": "chooseBranch"
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        -736,
        16
      ],
      "id": "7b1bbca8-c885-4550-a06a-ec31dedb6ed9",
      "name": "Merge4",
      "executeOnce": true
    },
    {
      "parameters": {
        "method": "PATCH",
        "url": "=https://api.notion.com/v1/pages/{{ $json.id }}",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "notionApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ \n  JSON.stringify((() => {\n    // Relation fixe\n    const Departement = $json.Departement;\n    const responsableId = $json.ResponsableID;\n    \n    // CORRECTION: Parser la string avec virgules en array\n    const equipeString = $json[\"\u00c9quipeID\"] || \"\";\n    let operateursIDs = [];\n    \n    if (equipeString) {\n      // Split par virgule + nettoyage + suppression doublons\n      operateursIDs = Array.from(\n        new Set(\n          equipeString\n            .split(',')                    // Split par virgule\n            .map(id => id.trim())          // Enlever espaces\n            .filter(id => id && id.length > 0)  // Enlever vides\n        )\n      ).map(id => ({ id }));              // Format Notion\n    }\n    \n    // Validation s\u00e9curit\u00e9\n    if (!Departement || !responsableId) {\n      console.log(\"Erreur: D\u00e9partement ou Responsable manquant\");\n      return null;\n    }\n    \n    // Payload PATCH\n    return {\n      properties: {\n        'ehl{': { relation: operateursIDs },\n        'pXDv': { relation: [{ id: responsableId }] },\n        'VuU{': { relation: [{ id: Departement }] }\n      }\n    };\n  })())\n}}",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1760,
        224
      ],
      "id": "24844f12-6a9b-4cba-9ff7-e7fde9039308",
      "name": "HTTP Participant Equipement",
      "alwaysOutputData": false,
      "retryOnFail": true,
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    }
  ],
  "connections": {
    "Merge1": {
      "main": [
        [
          {
            "node": "Merge3",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Log Snapshot3": {
      "main": [
        [
          {
            "node": "Returns item",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Log2": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Log Snapshot1": {
      "main": [
        [
          {
            "node": "Update Log2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many child blocks": {
      "main": [
        [
          {
            "node": "Index Children",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Snapshot1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "Build case Q",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items1": {
      "main": [
        [
          {
            "node": "Merge4",
            "type": "main",
            "index": 1
          }
        ],
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Snapshot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Index Children": {
      "main": [
        [
          {
            "node": "Update Log3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build case Q": {
      "main": [
        [
          {
            "node": "pop task",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "pop task": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "After Append Block": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If": {
      "main": [
        [
          {
            "node": "pop task",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "After Append Block",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Archive page": {
      "main": [
        [
          {
            "node": "Merge3",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Snapshot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Log": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Snapshot": {
      "main": [
        [
          {
            "node": "Update Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge3": {
      "main": [
        [
          {
            "node": "Log Snapshot3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Log3": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Log4": {
      "main": [
        [
          {
            "node": "Archive page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Equipement Participant": {
      "main": [
        [
          {
            "node": "HTTP Participant Equipement",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Archive Equipement": {
      "main": [
        [
          {
            "node": "Edit Equipement Participant",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Snapshot1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow 05.03": {
      "main": [
        [
          {
            "node": "Create Archive Equipement",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge4": {
      "main": [
        [
          {
            "node": "Update Log4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Participant Equipement": {
      "main": [
        [
          {
            "node": "Get many child blocks",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Snapshot1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "074cdce0-f931-4eb9-9cde-9d2edc760de2",
  "id": "dBMan0heaFJKNe7B",
  "tags": [
    {
      "createdAt": "2025-08-26T22:10:40.037Z",
      "updatedAt": "2025-08-26T22:10:40.037Z",
      "id": "41B38HIWO9KNrCRH",
      "name": "Archivage"
    },
    {
      "createdAt": "2025-09-05T22:01:52.313Z",
      "updatedAt": "2025-09-05T22:01:52.313Z",
      "id": "kzz5iXs8VyxT50fO",
      "name": "Archive Equipement"
    }
  ]
}