{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "13859f9a-981b-471a-995f-a5c71ceca530",
      "name": "Find Shared Holidays",
      "type": "n8n-nodes-base.code",
      "position": [
        1824,
        2144
      ],
      "parameters": {
        "jsCode": "// Get results from all loop iterations\nconst allItems = $('Filter Upcoming').all().map(i => i.json);\nconst dateMap = {};\n\n// 1. Group countries by Date\nfor (const item of allItems) {\n  // Ensure strictly YYYY-MM-DD (remove time if present)\n  // This ensures Notion treats it as \"All Day\"\n  let dateStr = item.date;\n  if (dateStr.includes('T')) {\n     dateStr = dateStr.split('T')[0];\n  }\n  // Write back clean date\n  item.date = dateStr;\n\n  if (!dateMap[dateStr]) dateMap[dateStr] = [];\n  \n  // Avoid duplicates\n  if (!dateMap[dateStr].includes(item.countryCode)) {\n    dateMap[dateStr].push(item.countryCode);\n  }\n}\n\n// 2. Add \"sharedWith\" info\nconst enrichedItems = allItems.map(item => {\n  const dateStr = item.date;\n  // Find countries sharing this date, excluding current one\n  const shared = dateMap[dateStr].filter(c => c !== item.countryCode);\n  \n  // For Notion (String list)\n  item.sharedWith = shared.length ? shared.join(', ') : '';\n  \n  // For Slack (Formatted message)\n  item.sharedMsg = shared.length ? ` (Also in: ${shared.join(', ')})` : '';\n  \n  return { json: item };\n});\n\nreturn enrichedItems;"
      },
      "executeOnce": true,
      "typeVersion": 2
    },
    {
      "id": "81a9c2ce-55ae-4fd5-974b-e09b1a4f6a46",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1312,
        1952
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 352,
        "content": "## 3. Fetch & Filter\nQueries the API for holidays and filters the results to keep only those falling within the \"lookahead\" window."
      },
      "typeVersion": 1
    },
    {
      "id": "031d2784-7939-4353-8e44-34e91502c7e8",
      "name": "Notify Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        2256,
        2144
      ],
      "parameters": {
        "text": "=\ud83d\udea2 *Team Alert:* \nNext {{ $json.countryCode }} Holiday: *{{ $json.name }}* is on {{ $json.date }}.{{ $json.sharedMsg }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "otherOptions": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "6a40d30c-8be1-4ef5-a788-a7f0c9108f68",
      "name": "Add to Notion",
      "type": "n8n-nodes-base.notion",
      "position": [
        2032,
        2144
      ],
      "parameters": {
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "2be13e5b-3669-80c7-a7de-c0b9f5c0748e",
          "cachedResultUrl": "https://www.notion.so/2be13e5b366980c7a7dec0b9f5c0748e",
          "cachedResultName": "nn"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Name|title",
              "title": "={{ $json.name }} ({{ $json.countryCode }})"
            },
            {
              "key": "Date|date",
              "date": "={{ $json.date }}"
            },
            {
              "key": "Shared Countries|rich_text",
              "textContent": "={{ $json.sharedWith }}"
            }
          ]
        }
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "efc05b71-b31d-4d9e-b47f-da5d1bfdf93f",
      "name": "Filter Upcoming",
      "type": "n8n-nodes-base.code",
      "position": [
        1584,
        2144
      ],
      "parameters": {
        "jsCode": "const daysAhead = $('Define Days to Lookahead').first().json.Days;\n\nconst items = $input.all();\nconst today = new Date();\nconst futureDate = new Date();\nfutureDate.setDate(today.getDate() + daysAhead);\n\nconst upcomingHolidays = items.filter(item => {\n  const holidayDate = new Date(item.json.date);\n  return holidayDate >= today && holidayDate <= futureDate;\n});\n\nreturn upcomingHolidays;"
      },
      "typeVersion": 2
    },
    {
      "id": "b0280f18-8055-4564-934d-2b9b2d614545",
      "name": "Get Public Holidays",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1376,
        2144
      ],
      "parameters": {
        "url": "=https://date.nager.at/api/v3/publicholidays/{{ $json.year }}/{{ $json.countryCode }}",
        "options": {}
      },
      "typeVersion": 4.1
    },
    {
      "id": "d0a73365-b3a3-49c8-ac67-dc1f392476bb",
      "name": "Define Days to Lookahead",
      "type": "n8n-nodes-base.set",
      "position": [
        736,
        2144
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d6aaefad-0c24-4324-b4d4-9bb184cc7c61",
              "name": "Days",
              "type": "number",
              "value": 50
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f21ada48-96e8-44c9-92c3-170c56e4a209",
      "name": "Define Team Countries",
      "type": "n8n-nodes-base.set",
      "position": [
        528,
        2144
      ],
      "parameters": {
        "fields": {
          "values": [
            {
              "name": "countries",
              "type": "arrayValue",
              "arrayValue": "['KR', 'MX', 'US']"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "9b9bc13c-eea5-47e3-9262-725cb1698df2",
      "name": "Weekly Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        288,
        2144
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "7ea579e1-b800-4315-8796-851528ca501b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "disabled": true,
      "position": [
        1760,
        1952
      ],
      "parameters": {
        "color": 7,
        "width": 852,
        "height": 350,
        "content": "## 3. Compare & Sync\nAggregates all results to identify shared holidays, formats the date (YYYY-MM-DD), and updates Notion/Slack."
      },
      "typeVersion": 1
    },
    {
      "id": "43375eb5-3ba6-44fa-833d-e1ccb206d49f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "disabled": true,
      "position": [
        912,
        1952
      ],
      "parameters": {
        "color": 7,
        "width": 340,
        "height": 360,
        "content": "## 2. Query Preparation\nPrepares a list of `Country + Year` combinations (Current & Next Year) to ensure holidays aren't missed during year-end transitions."
      },
      "typeVersion": 1
    },
    {
      "id": "186d23a6-fc63-4256-b006-b032829af4db",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "disabled": true,
      "position": [
        288,
        2048
      ],
      "parameters": {
        "color": 7,
        "width": 556,
        "height": 264,
        "content": "## 1. Schedule & Configuration\nThis section triggers the workflow every Monday and sets the configuration variables: the list of countries to track and the \"lookahead\" window (in days)."
      },
      "typeVersion": 1
    },
    {
      "id": "8bcab344-0da5-4dd4-85ed-4e528ffcb58c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "disabled": true,
      "position": [
        288,
        1616
      ],
      "parameters": {
        "width": 546,
        "height": 412,
        "content": "## \ud83c\udf0d Global Holiday Sync\n\n## How it works\nThis workflow prevents scheduling conflicts by tracking distributed team holidays. It fetches public holidays from the **Nager.Date API** for your specific regions (e.g., KR, US), filters for upcoming dates, and calculates if a holiday is **shared** across countries. Finally, it syncs the schedule to **Notion** and **Slack**.\n\n## Setup steps\n1. **Define Countries:** Update 'Define Team Countries' with 2-letter codes.\n2. **Set Range:** In 'Define Days to Lookahead', set the forecast window (e.g., 50 days).\n3. **Notion:** Create a DB with properties: `Name` (Title), `Date` (Date), and `Shared Countries` (Text).\n4. **Credentials:** Map your Notion Database and Slack Channel in the final nodes."
      },
      "typeVersion": 1
    },
    {
      "id": "3ab566e8-b1f1-415a-a981-2b8013a8e184",
      "name": "Prepare Queries",
      "type": "n8n-nodes-base.code",
      "position": [
        928,
        2144
      ],
      "parameters": {
        "jsCode": "const countries = $('Define Team Countries').first().json.countries;\nconst currentYear = new Date().getFullYear();\nconst nextYear = currentYear + 1;\n\nconst results = [];\n\n// Loop through each country and add both years\nfor (const code of countries) {\n  // Add Current Year\n  results.push({\n    json: {\n      countryCode: code,\n      year: currentYear\n    }\n  });\n  \n  // Add Next Year\n  results.push({\n    json: {\n      countryCode: code,\n      year: nextYear\n    }\n  });\n}\n\nreturn results;"
      },
      "typeVersion": 2
    }
  ],
  "connections": {
    "Add to Notion": {
      "main": [
        [
          {
            "node": "Notify Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Upcoming": {
      "main": [
        [
          {
            "node": "Find Shared Holidays",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Queries": {
      "main": [
        [
          {
            "node": "Get Public Holidays",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Schedule": {
      "main": [
        [
          {
            "node": "Define Team Countries",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Public Holidays": {
      "main": [
        [
          {
            "node": "Filter Upcoming",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Shared Holidays": {
      "main": [
        [
          {
            "node": "Add to Notion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Define Team Countries": {
      "main": [
        [
          {
            "node": "Define Days to Lookahead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Define Days to Lookahead": {
      "main": [
        [
          {
            "node": "Prepare Queries",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}