diff --git a/tablero-cdc-migrar-legacy-sheet-a-supabase.json b/tablero-cdc-migrar-legacy-sheet-a-supabase.json new file mode 100644 index 0000000..d96c0c5 --- /dev/null +++ b/tablero-cdc-migrar-legacy-sheet-a-supabase.json @@ -0,0 +1,1069 @@ +{ + "updatedAt": "2026-06-11T01:42:10.458Z", + "createdAt": "2026-06-10T19:07:24.089Z", + "id": "IZLgEpGSfWhjj6Qy", + "name": "Tablero CDC - Migrar Legacy Sheet a Supabase", + "description": null, + "active": true, + "isArchived": false, + "nodes": [ + { + "parameters": { + "documentId": { + "__rl": true, + "value": "1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q", + "mode": "list", + "cachedResultName": "APROBACIONES PROYECTOS", + "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit?usp=drivesdk" + }, + "sheetName": { + "__rl": true, + "value": 1563472127, + "mode": "list", + "cachedResultName": "PROYECTOS 2026", + "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit#gid=1563472127" + }, + "options": { + "dataLocationOnSheet": { + "values": { + "rangeDefinition": "specifyRangeA1", + "range": "A3:N183" + } + } + } + }, + "type": "n8n-nodes-base.googleSheets", + "typeVersion": 4.7, + "position": [ + 160, + -16 + ], + "id": "c2e04d79-3014-49ec-b213-931cf57fa5f1", + "name": "Sheets - Leer legacy rows", + "credentials": { + "googleSheetsOAuth2Api": { + "id": "K0hDZh3a85MpOHCs", + "name": "Google Sheets account 2" + } + } + }, + { + "parameters": { + "jsCode": "const rows = $input.all();\n\nconst FIRST_DATA_ROW = 4;\n\n// PRUEBA SEGURA:\n// Solo migramos la fila 4 por ahora.\n// Cuando validemos, cambiamos esto a 183.\nconst LAST_LEGACY_ROW = 183;\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction createUuid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (char) {\n const random = Math.random() * 16 | 0;\n const value = char === 'x' ? random : (random & 0x3 | 0x8);\n return value.toString(16);\n });\n}\n\nfunction parseAmount(value) {\n const text = clean(value);\n if (!text) return null;\n\n const normalized = text\n .replace(/RD\\$/gi, '')\n .replace(/DOP/gi, '')\n .replace(/,/g, '')\n .trim();\n\n const number = Number(normalized);\n return Number.isFinite(number) ? number : null;\n}\n\nfunction extractRequestedBy(comments) {\n const text = clean(comments);\n const match = text.match(/^solicitado\\s+por\\s+(.+)$/i);\n return match ? match[1].trim() : '';\n}\n\nconst output = [];\n\nrows.forEach((item, index) => {\n const row = item.json;\n\n const sheetRowNumber = FIRST_DATA_ROW + index;\n\n if (sheetRowNumber < FIRST_DATA_ROW || sheetRowNumber > LAST_LEGACY_ROW) {\n return;\n }\n\n const existingProjectId = clean(row['Project ID']);\n if (existingProjectId) {\n return;\n }\n\n const title = clean(row['Tipo o nombre de proyecto']);\n const client = clean(row['Cliente']);\n const country = clean(row['BU Solicita']);\n const brand = clean(row['Marca']);\n const countryManager = clean(row['CM']);\n const status = clean(row['Status']) || 'Activo';\n const comments = clean(row['Comentarios']);\n const proposalLink = clean(row['Link de propuesta']);\n const internalAmount = parseAmount(row['$ Interno Cargado']);\n const briefLink = clean(row['Link del Brief']);\n const finalArtLink = clean(row['Link de artes finales']);\n const year = clean(row['Año']);\n const month = clean(row['Mes']);\n\n if (!title || !client || !country || !brand) {\n throw new Error(\n `Fila ${sheetRowNumber}: faltan campos mínimos. title=\"${title}\", client=\"${client}\", country=\"${country}\", brand=\"${brand}\"`\n );\n }\n\n const projectId = createUuid();\n\n const projectPayload = {\n id: projectId,\n title,\n client,\n brand,\n country,\n requested_by: extractRequestedBy(comments) || null,\n country_manager: countryManager || null,\n description: comments || null,\n status,\n internal_amount: internalAmount,\n currency: 'DOP',\n brief_link: briefLink || null,\n extra_data: {\n legacy_migration: true,\n legacy_source: 'PROYECTOS 2026',\n legacy_sheet_row_number: sheetRowNumber,\n legacy_year: year,\n legacy_month: month,\n migrated_at: new Date().toISOString(),\n },\n };\n\n const links = [];\n\n if (proposalLink) {\n links.push({\n project_id: projectId,\n link_type: 'proposal',\n url: proposalLink,\n label: 'Propuesta legacy',\n extra_data: {\n legacy_migration: true,\n legacy_sheet_row_number: sheetRowNumber,\n },\n });\n }\n\n if (finalArtLink) {\n links.push({\n project_id: projectId,\n link_type: 'final_art',\n url: finalArtLink,\n label: 'Artes finales legacy',\n extra_data: {\n legacy_migration: true,\n legacy_sheet_row_number: sheetRowNumber,\n },\n });\n }\n\n output.push({\n json: {\n sheet_row_number: sheetRowNumber,\n project_id: projectId,\n project_id_cell: `N${sheetRowNumber}`,\n title,\n project_payload: projectPayload,\n links,\n },\n });\n});\n\nreturn output;" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 416, + -16 + ], + "id": "0303074a-5370-4bab-9fb8-e06e265d17aa", + "name": "Code - Preparar migracion legacy" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/tablero_cdc_projects", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "TU_SERVICE_ROLE_KEY_REAL" + }, + { + "name": "Authorization", + "value": "Bearer TU_SERVICE_ROLE_KEY_REAL" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=minimal" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $json.project_payload }}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 624, + -16 + ], + "id": "6be4d8e1-13d5-4273-b5c5-d83b9ae28188", + "name": "Supabase - Insertar proyecto legacy" + }, + { + "parameters": { + "jsCode": "const preparedItems = $('Code - Preparar migracion legacy').all();\n\nconst output = [];\n\nfor (const item of preparedItems) {\n const links = item.json.links || [];\n\n for (const link of links) {\n output.push({\n json: link,\n });\n }\n}\n\nreturn output;" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 832, + -16 + ], + "id": "5c149992-85e2-4ade-a32f-e280131b0d5a", + "name": "Code - Preparar links legacy" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/tablero_cdc_project_links", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "TU_SERVICE_ROLE_KEY_REAL" + }, + { + "name": "Authorization", + "value": "Bearer TU_SERVICE_ROLE_KEY_REAL" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=minimal" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $json }}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 1040, + -16 + ], + "id": "5968b76f-2846-4c2f-a643-a52116e544a3", + "name": "Supabase - Insertar links legacy" + }, + { + "parameters": { + "jsCode": "const preparedItems = $('Code - Preparar migracion legacy').all();\n\nreturn preparedItems.map(item => {\n return {\n json: {\n row_number: item.json.sheet_row_number,\n project_id: item.json.project_id,\n title: item.json.title,\n project_id_cell: item.json.project_id_cell,\n },\n };\n});" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 1248, + -16 + ], + "id": "056908f7-3f2c-48d6-8613-90cd8eb3a3d3", + "name": "Code - Preparar Project IDs Sheet" + }, + { + "parameters": { + "operation": "update", + "documentId": { + "__rl": true, + "value": "1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q", + "mode": "list", + "cachedResultName": "APROBACIONES PROYECTOS", + "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit?usp=drivesdk" + }, + "sheetName": { + "__rl": true, + "value": 1563472127, + "mode": "list", + "cachedResultName": "PROYECTOS 2026", + "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit#gid=1563472127" + }, + "columns": { + "mappingMode": "defineBelow", + "value": { + "row_number": "={{ $json.row_number }}", + "Project ID": "={{ $json.project_id }}" + }, + "matchingColumns": [ + "row_number" + ], + "schema": [ + { + "id": "Año", + "displayName": "Año", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Mes", + "displayName": "Mes", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Tipo o nombre de proyecto", + "displayName": "Tipo o nombre de proyecto", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Cliente", + "displayName": "Cliente", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "BU Solicita", + "displayName": "BU Solicita", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Marca", + "displayName": "Marca", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "CM", + "displayName": "CM", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Status", + "displayName": "Status", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Comentarios", + "displayName": "Comentarios", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Link de propuesta", + "displayName": "Link de propuesta", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "$ Interno Cargado", + "displayName": "$ Interno Cargado", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Link del Brief", + "displayName": "Link del Brief", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Link de artes finales", + "displayName": "Link de artes finales", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Project ID", + "displayName": "Project ID", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": false + }, + { + "id": "row_number", + "displayName": "row_number", + "required": false, + "defaultMatch": false, + "display": true, + "type": "number", + "canBeUsedToMatch": true, + "readOnly": true, + "removed": false + } + ], + "attemptToConvertTypes": false, + "convertFieldsToString": false + }, + "options": { + "locationDefine": { + "values": { + "headerRow": 3, + "firstDataRow": 4 + } + } + } + }, + "type": "n8n-nodes-base.googleSheets", + "typeVersion": 4.7, + "position": [ + 1456, + -16 + ], + "id": "666a950b-cd80-4f0a-885b-80745e74bb0b", + "name": "Sheets - Escribir Project ID legacy", + "credentials": { + "googleSheetsOAuth2Api": { + "id": "K0hDZh3a85MpOHCs", + "name": "Google Sheets account 2" + } + } + }, + { + "parameters": { + "path": "tablero-cdc-migracion-legacy-archivada", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + -304, + 16 + ], + "id": "9ba81599-f14c-45c7-b273-2ee1f6d2e8da", + "name": "Webhook", + "webhookId": "ba3e5457-3806-4e55-ac0b-9e4d90d3735c" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "{\n \"ok\": true,\n \"status\": \"archived\",\n \"workflow\": \"Tablero CDC - Migrar Legacy Sheet a Supabase\",\n \"message\": \"Workflow archivado solo para respaldo en Gitea. No ejecuta migración.\"\n}", + "options": { + "responseCode": 200 + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + -48, + 16 + ], + "id": "aef53048-0059-46ce-9eb6-36be924d678b", + "name": "Respond - Workflow archivado" + }, + { + "parameters": { + "content": "Migrar los proyectos históricos del Sheet PROYECTOS 2026 a Supabase.\n\nEl Webhook publicado es solo para que el flujo de respaldo a Gitea pueda guardar este workflow.\n\n", + "height": 336, + "width": 2048, + "color": "#33801E" + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + -352, + -128 + ], + "id": "f45a8a78-a258-4934-b755-9f82792a6d69", + "name": "Sticky Note" + } + ], + "connections": { + "Sheets - Leer legacy rows": { + "main": [ + [ + { + "node": "Code - Preparar migracion legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code - Preparar migracion legacy": { + "main": [ + [ + { + "node": "Supabase - Insertar proyecto legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Supabase - Insertar proyecto legacy": { + "main": [ + [ + { + "node": "Code - Preparar links legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code - Preparar links legacy": { + "main": [ + [ + { + "node": "Supabase - Insertar links legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Supabase - Insertar links legacy": { + "main": [ + [ + { + "node": "Code - Preparar Project IDs Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code - Preparar Project IDs Sheet": { + "main": [ + [ + { + "node": "Sheets - Escribir Project ID legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Webhook": { + "main": [ + [ + { + "node": "Respond - Workflow archivado", + "type": "main", + "index": 0 + } + ] + ] + }, + "Respond - Workflow archivado": { + "main": [ + [ + { + "node": "Sheets - Leer legacy rows", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate" + }, + "staticData": null, + "meta": { + "templateCredsSetupCompleted": true + }, + "versionId": "d4d9f9d2-f620-4a21-b513-99978477813e", + "activeVersionId": "d4d9f9d2-f620-4a21-b513-99978477813e", + "versionCounter": 170, + "triggerCount": 1, + "shared": [ + { + "updatedAt": "2026-06-10T19:07:24.096Z", + "createdAt": "2026-06-10T19:07:24.096Z", + "role": "workflow:owner", + "workflowId": "IZLgEpGSfWhjj6Qy", + "projectId": "PJpTANzTXIFibWsW", + "project": { + "updatedAt": "2026-04-22T14:25:09.686Z", + "createdAt": "2026-04-22T14:22:54.790Z", + "id": "PJpTANzTXIFibWsW", + "name": "Isaac Aracena ", + "type": "personal", + "icon": null, + "description": null, + "creatorId": "0a88c0b1-928e-4412-896e-c5d1c99b2029" + } + } + ], + "tags": [], + "activeVersion": { + "updatedAt": "2026-06-11T01:42:12.000Z", + "createdAt": "2026-06-11T01:42:10.459Z", + "versionId": "d4d9f9d2-f620-4a21-b513-99978477813e", + "workflowId": "IZLgEpGSfWhjj6Qy", + "nodes": [ + { + "parameters": { + "documentId": { + "__rl": true, + "value": "1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q", + "mode": "list", + "cachedResultName": "APROBACIONES PROYECTOS", + "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit?usp=drivesdk" + }, + "sheetName": { + "__rl": true, + "value": 1563472127, + "mode": "list", + "cachedResultName": "PROYECTOS 2026", + "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit#gid=1563472127" + }, + "options": { + "dataLocationOnSheet": { + "values": { + "rangeDefinition": "specifyRangeA1", + "range": "A3:N183" + } + } + } + }, + "type": "n8n-nodes-base.googleSheets", + "typeVersion": 4.7, + "position": [ + 160, + -16 + ], + "id": "c2e04d79-3014-49ec-b213-931cf57fa5f1", + "name": "Sheets - Leer legacy rows", + "credentials": { + "googleSheetsOAuth2Api": { + "id": "K0hDZh3a85MpOHCs", + "name": "Google Sheets account 2" + } + } + }, + { + "parameters": { + "jsCode": "const rows = $input.all();\n\nconst FIRST_DATA_ROW = 4;\n\n// PRUEBA SEGURA:\n// Solo migramos la fila 4 por ahora.\n// Cuando validemos, cambiamos esto a 183.\nconst LAST_LEGACY_ROW = 183;\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction createUuid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (char) {\n const random = Math.random() * 16 | 0;\n const value = char === 'x' ? random : (random & 0x3 | 0x8);\n return value.toString(16);\n });\n}\n\nfunction parseAmount(value) {\n const text = clean(value);\n if (!text) return null;\n\n const normalized = text\n .replace(/RD\\$/gi, '')\n .replace(/DOP/gi, '')\n .replace(/,/g, '')\n .trim();\n\n const number = Number(normalized);\n return Number.isFinite(number) ? number : null;\n}\n\nfunction extractRequestedBy(comments) {\n const text = clean(comments);\n const match = text.match(/^solicitado\\s+por\\s+(.+)$/i);\n return match ? match[1].trim() : '';\n}\n\nconst output = [];\n\nrows.forEach((item, index) => {\n const row = item.json;\n\n const sheetRowNumber = FIRST_DATA_ROW + index;\n\n if (sheetRowNumber < FIRST_DATA_ROW || sheetRowNumber > LAST_LEGACY_ROW) {\n return;\n }\n\n const existingProjectId = clean(row['Project ID']);\n if (existingProjectId) {\n return;\n }\n\n const title = clean(row['Tipo o nombre de proyecto']);\n const client = clean(row['Cliente']);\n const country = clean(row['BU Solicita']);\n const brand = clean(row['Marca']);\n const countryManager = clean(row['CM']);\n const status = clean(row['Status']) || 'Activo';\n const comments = clean(row['Comentarios']);\n const proposalLink = clean(row['Link de propuesta']);\n const internalAmount = parseAmount(row['$ Interno Cargado']);\n const briefLink = clean(row['Link del Brief']);\n const finalArtLink = clean(row['Link de artes finales']);\n const year = clean(row['Año']);\n const month = clean(row['Mes']);\n\n if (!title || !client || !country || !brand) {\n throw new Error(\n `Fila ${sheetRowNumber}: faltan campos mínimos. title=\"${title}\", client=\"${client}\", country=\"${country}\", brand=\"${brand}\"`\n );\n }\n\n const projectId = createUuid();\n\n const projectPayload = {\n id: projectId,\n title,\n client,\n brand,\n country,\n requested_by: extractRequestedBy(comments) || null,\n country_manager: countryManager || null,\n description: comments || null,\n status,\n internal_amount: internalAmount,\n currency: 'DOP',\n brief_link: briefLink || null,\n extra_data: {\n legacy_migration: true,\n legacy_source: 'PROYECTOS 2026',\n legacy_sheet_row_number: sheetRowNumber,\n legacy_year: year,\n legacy_month: month,\n migrated_at: new Date().toISOString(),\n },\n };\n\n const links = [];\n\n if (proposalLink) {\n links.push({\n project_id: projectId,\n link_type: 'proposal',\n url: proposalLink,\n label: 'Propuesta legacy',\n extra_data: {\n legacy_migration: true,\n legacy_sheet_row_number: sheetRowNumber,\n },\n });\n }\n\n if (finalArtLink) {\n links.push({\n project_id: projectId,\n link_type: 'final_art',\n url: finalArtLink,\n label: 'Artes finales legacy',\n extra_data: {\n legacy_migration: true,\n legacy_sheet_row_number: sheetRowNumber,\n },\n });\n }\n\n output.push({\n json: {\n sheet_row_number: sheetRowNumber,\n project_id: projectId,\n project_id_cell: `N${sheetRowNumber}`,\n title,\n project_payload: projectPayload,\n links,\n },\n });\n});\n\nreturn output;" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 416, + -16 + ], + "id": "0303074a-5370-4bab-9fb8-e06e265d17aa", + "name": "Code - Preparar migracion legacy" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/tablero_cdc_projects", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "TU_SERVICE_ROLE_KEY_REAL" + }, + { + "name": "Authorization", + "value": "Bearer TU_SERVICE_ROLE_KEY_REAL" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=minimal" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $json.project_payload }}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 624, + -16 + ], + "id": "6be4d8e1-13d5-4273-b5c5-d83b9ae28188", + "name": "Supabase - Insertar proyecto legacy" + }, + { + "parameters": { + "jsCode": "const preparedItems = $('Code - Preparar migracion legacy').all();\n\nconst output = [];\n\nfor (const item of preparedItems) {\n const links = item.json.links || [];\n\n for (const link of links) {\n output.push({\n json: link,\n });\n }\n}\n\nreturn output;" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 832, + -16 + ], + "id": "5c149992-85e2-4ade-a32f-e280131b0d5a", + "name": "Code - Preparar links legacy" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/tablero_cdc_project_links", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "TU_SERVICE_ROLE_KEY_REAL" + }, + { + "name": "Authorization", + "value": "Bearer TU_SERVICE_ROLE_KEY_REAL" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=minimal" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $json }}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 1040, + -16 + ], + "id": "5968b76f-2846-4c2f-a643-a52116e544a3", + "name": "Supabase - Insertar links legacy" + }, + { + "parameters": { + "jsCode": "const preparedItems = $('Code - Preparar migracion legacy').all();\n\nreturn preparedItems.map(item => {\n return {\n json: {\n row_number: item.json.sheet_row_number,\n project_id: item.json.project_id,\n title: item.json.title,\n project_id_cell: item.json.project_id_cell,\n },\n };\n});" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 1248, + -16 + ], + "id": "056908f7-3f2c-48d6-8613-90cd8eb3a3d3", + "name": "Code - Preparar Project IDs Sheet" + }, + { + "parameters": { + "operation": "update", + "documentId": { + "__rl": true, + "value": "1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q", + "mode": "list", + "cachedResultName": "APROBACIONES PROYECTOS", + "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit?usp=drivesdk" + }, + "sheetName": { + "__rl": true, + "value": 1563472127, + "mode": "list", + "cachedResultName": "PROYECTOS 2026", + "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit#gid=1563472127" + }, + "columns": { + "mappingMode": "defineBelow", + "value": { + "row_number": "={{ $json.row_number }}", + "Project ID": "={{ $json.project_id }}" + }, + "matchingColumns": [ + "row_number" + ], + "schema": [ + { + "id": "Año", + "displayName": "Año", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Mes", + "displayName": "Mes", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Tipo o nombre de proyecto", + "displayName": "Tipo o nombre de proyecto", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Cliente", + "displayName": "Cliente", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "BU Solicita", + "displayName": "BU Solicita", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Marca", + "displayName": "Marca", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "CM", + "displayName": "CM", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Status", + "displayName": "Status", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Comentarios", + "displayName": "Comentarios", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Link de propuesta", + "displayName": "Link de propuesta", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "$ Interno Cargado", + "displayName": "$ Interno Cargado", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Link del Brief", + "displayName": "Link del Brief", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Link de artes finales", + "displayName": "Link de artes finales", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": true + }, + { + "id": "Project ID", + "displayName": "Project ID", + "required": false, + "defaultMatch": false, + "display": true, + "type": "string", + "canBeUsedToMatch": true, + "removed": false + }, + { + "id": "row_number", + "displayName": "row_number", + "required": false, + "defaultMatch": false, + "display": true, + "type": "number", + "canBeUsedToMatch": true, + "readOnly": true, + "removed": false + } + ], + "attemptToConvertTypes": false, + "convertFieldsToString": false + }, + "options": { + "locationDefine": { + "values": { + "headerRow": 3, + "firstDataRow": 4 + } + } + } + }, + "type": "n8n-nodes-base.googleSheets", + "typeVersion": 4.7, + "position": [ + 1456, + -16 + ], + "id": "666a950b-cd80-4f0a-885b-80745e74bb0b", + "name": "Sheets - Escribir Project ID legacy", + "credentials": { + "googleSheetsOAuth2Api": { + "id": "K0hDZh3a85MpOHCs", + "name": "Google Sheets account 2" + } + } + }, + { + "parameters": { + "path": "tablero-cdc-migracion-legacy-archivada", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + -304, + 16 + ], + "id": "9ba81599-f14c-45c7-b273-2ee1f6d2e8da", + "name": "Webhook", + "webhookId": "ba3e5457-3806-4e55-ac0b-9e4d90d3735c" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "{\n \"ok\": true,\n \"status\": \"archived\",\n \"workflow\": \"Tablero CDC - Migrar Legacy Sheet a Supabase\",\n \"message\": \"Workflow archivado solo para respaldo en Gitea. No ejecuta migración.\"\n}", + "options": { + "responseCode": 200 + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + -48, + 16 + ], + "id": "aef53048-0059-46ce-9eb6-36be924d678b", + "name": "Respond - Workflow archivado" + }, + { + "parameters": { + "content": "Migrar los proyectos históricos del Sheet PROYECTOS 2026 a Supabase.\n\nEl Webhook publicado es solo para que el flujo de respaldo a Gitea pueda guardar este workflow.\n\n", + "height": 336, + "width": 2048, + "color": "#33801E" + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + -352, + -128 + ], + "id": "f45a8a78-a258-4934-b755-9f82792a6d69", + "name": "Sticky Note" + } + ], + "connections": { + "Sheets - Leer legacy rows": { + "main": [ + [ + { + "node": "Code - Preparar migracion legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code - Preparar migracion legacy": { + "main": [ + [ + { + "node": "Supabase - Insertar proyecto legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Supabase - Insertar proyecto legacy": { + "main": [ + [ + { + "node": "Code - Preparar links legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code - Preparar links legacy": { + "main": [ + [ + { + "node": "Supabase - Insertar links legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Supabase - Insertar links legacy": { + "main": [ + [ + { + "node": "Code - Preparar Project IDs Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code - Preparar Project IDs Sheet": { + "main": [ + [ + { + "node": "Sheets - Escribir Project ID legacy", + "type": "main", + "index": 0 + } + ] + ] + }, + "Webhook": { + "main": [ + [ + { + "node": "Respond - Workflow archivado", + "type": "main", + "index": 0 + } + ] + ] + }, + "Respond - Workflow archivado": { + "main": [ + [ + { + "node": "Sheets - Leer legacy rows", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "authors": "Isaac Aracena", + "name": "Version d4d9f9d2", + "description": "", + "autosaved": true, + "workflowPublishHistory": [ + { + "createdAt": "2026-06-11T01:42:12.435Z", + "id": 1311, + "workflowId": "IZLgEpGSfWhjj6Qy", + "versionId": "d4d9f9d2-f620-4a21-b513-99978477813e", + "event": "activated", + "userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029" + } + ] + } +} \ No newline at end of file