{
  "name": "Monitor and report OKR variance from Monday.com and Jira via Slack and Email",
  "nodes": [
    {
      "id": "c13ed242-024f-40c5-ba72-488ebbd23236",
      "name": "Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2240,
        -16
      ],
      "parameters": {
        "width": 386.39887445887445,
        "height": 464.8876404494382,
        "content": "## 🎯 OKR Sync & Variance Tracking System\n\nThis workflow automates the synchronization of OKRs (Objectives and Key Results) between Monday.com and Jira, calculating progress variance and sending automa"
      }
    },
    {
      "id": "c403d5d0-9c79-43f4-affc-bee172972745",
      "name": "Note: Schedule Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1808,
        -128
      ],
      "parameters": {
        "width": 313,
        "height": 297,
        "content": "## ⏰ Schedule Configuration\n\n**Setup Steps:**\n1. Click on this node\n2. Set your desired interval (daily/weekly)\n3. Choose optimal run time (e.g., 9 AM daily)\n4. Consider timezone settings\n\n**Best Prac"
      }
    },
    {
      "id": "bb79b478-58ce-407c-ae29-1f8139aa5129",
      "name": "Daily OKR Sync Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1600,
        208
      ]
    },
    {
      "id": "3ebd5103-a47b-4b06-8786-9cf757e0b149",
      "name": "Note: Monday Board Config",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1472,
        -224
      ],
      "parameters": {
        "width": 330,
        "height": 416,
        "content": "## 📋 Monday.com Board Setup\n\n**Required Columns:**\n- Objective Name (text)\n- Jira Epic Keys (text, comma-separated)\n- Target Progress (number, %)\n- Current Progress (number, %)\n- Threshold (number, %)"
      }
    },
    {
      "id": "966a0ad7-2f85-44bc-9c69-40fdf833473a",
      "name": "Fetch OKRs from Monday.com",
      "type": "n8n-nodes-base.mondayCom",
      "position": [
        -1376,
        208
      ]
    },
    {
      "id": "dbde1957-fd81-496f-884c-7e72a54c95b3",
      "name": "Note: Field Mapping Logic",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1264,
        384
      ],
      "parameters": {
        "width": 329.4096385542169,
        "height": 294.3975903614458,
        "content": "## 🔄 Field Mapping\n\nThis node extracts and standardizes Monday.com column data into a consistent schema.\n\n**What it does:**\n- Maps column indices to readable field names\n- Prepares data for downstream"
      }
    },
    {
      "id": "f37d5fa2-af93-48ea-b087-b8b21ee268f9",
      "name": "Map Monday Fields → Standard KR Schema",
      "type": "n8n-nodes-base.set",
      "position": [
        -1152,
        208
      ]
    },
    {
      "id": "51ce7b43-0b86-413e-80c7-e5762a33ab46",
      "name": "Note: Epic Splitting",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1024,
        -96
      ],
      "parameters": {
        "width": 324.2168674698795,
        "height": 294.3975903614458,
        "content": "## 🔀 Epic Splitting Logic\n\nEach KR can track multiple Jira epics (comma-separated). This node creates one item per epic-KR pair.\n\n**Example:**\n- Input: KR-123 → EPIC-1, EPIC-2\n- Output: 2 items (KR-12"
      }
    },
    {
      "id": "263d82ad-50d6-4632-877a-034975d5729b",
      "name": "Split KR → Epics Mapper",
      "type": "n8n-nodes-base.code",
      "position": [
        -928,
        208
      ]
    },
    {
      "id": "c07d2061-b07c-4a1c-868b-edc013cacf90",
      "name": "Note: Jira Epic Fetching",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        416
      ],
      "parameters": {
        "width": 324.2168674698795,
        "height": 280,
        "content": "## 🔗 Jira Integration\n\n**Setup:**\n1. Connect your Jira credentials\n2. Ensure the Jira account has read access to all linked epics\n3. Test with a single epic key first\n\n**Rate Limits:** Jira Cloud allo"
      }
    },
    {
      "id": "0411be4a-6381-4f13-9808-57a2f7b07644",
      "name": "Fetch Jira Epic Details",
      "type": "n8n-nodes-base.jira",
      "position": [
        -704,
        272
      ]
    },
    {
      "id": "4992f272-d055-41d4-958c-b9691e3ebb96",
      "name": "Note: Jira Response Cleanup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        400
      ],
      "parameters": {
        "width": 324.2168674698795,
        "height": 280,
        "content": "## 🧹 Response Normalization\n\nJira API returns nested complex objects. This node flattens and extracts only the fields needed for progress calculation:\n\n- Issue key\n- Summary (name)\n- Status (for progr"
      }
    },
    {
      "id": "9de61cfd-ba27-4023-8528-3ba279502d8f",
      "name": "Normalize Jira Response",
      "type": "n8n-nodes-base.code",
      "position": [
        -480,
        272
      ]
    },
    {
      "id": "d0de1271-2a54-4a4c-9650-b84e1c3193ac",
      "name": "Note: Data Merging",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        -80
      ],
      "parameters": {
        "width": 324.2168674698795,
        "height": 280,
        "content": "## 🔗 SQL Merge Strategy\n\nThis node performs a LEFT JOIN to combine:\n- Input 1: KR metadata (from Monday)\n- Input 2: Epic details (from Jira)\n\n**Result:** Each KR-Epic pair with complete context for va"
      }
    },
    {
      "id": "ba395420-aa63-4277-8d7d-fb02c9d978b2",
      "name": "Join KR + Epic Data (SQL Merge)",
      "type": "n8n-nodes-base.merge",
      "position": [
        -256,
        208
      ]
    },
    {
      "id": "5316f900-d4b5-4543-b407-449434ea15d3",
      "name": "Note: Variance Calculation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        -96
      ],
      "parameters": {
        "width": 324.2168674698795,
        "height": 320,
        "content": "## 📊 Progress Calculation Logic\n\n**Status Weights:**\n- To Do = 0%\n- In Progress = 50%\n- Done = 100%\n\n**Formula:**\n- Actual Progress = Average of all epic weights\n- Variance = Actual - Target\n- Status "
      }
    },
    {
      "id": "1a5c998f-e607-412f-baa0-361c223260a5",
      "name": "Compute KR Progress & Variance",
      "type": "n8n-nodes-base.code",
      "position": [
        -32,
        208
      ]
    },
    {
      "id": "e2e5308f-5ba4-4eab-a565-fb2e23dc5c6e",
      "name": "Note: Monday Board Update",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        288,
        -96
      ],
      "parameters": {
        "width": 324.2168674698795,
        "height": 300,
        "content": "## ✍️ Monday.com Update\n\n**Configuration Needed:**\n1. Replace column IDs with your actual Monday board column IDs:\n   - MONDAY_COL_ACTUAL_PROGRESS → Actual Progress column\n   - MONDAY_COL_VARIANCE → V"
      }
    },
    {
      "id": "6c262e7a-b86e-48f0-80bb-419a55d98e73",
      "name": "Update KR Status on Monday",
      "type": "n8n-nodes-base.mondayCom",
      "position": [
        208,
        96
      ]
    },
    {
      "id": "f961b9b2-5ea4-4566-ad39-db01faa85c1a",
      "name": "Note: Data Aggregation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        464
      ],
      "parameters": {
        "width": 324.2168674698795,
        "height": 260,
        "content": "## 📦 Aggregation for Reporting\n\nCombines all KR variance data into a single payload for reporting nodes.\n\n**Output:** Array of all KRs with their computed metrics, ready for Slack/Email formatting"
      }
    },
    {
      "id": "f312abe7-993b-42ee-8a4b-7c30073209b0",
      "name": "Aggregate Final Results for Reporting",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        208,
        304
      ]
    },
    {
      "id": "fafc7791-2e28-4a61-a692-37f29b01efd1",
      "name": "Note: Slack Configuration",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        592,
        224
      ],
      "parameters": {
        "width": 324.2168674698795,
        "height": 280,
        "content": "## 💬 Slack Notification\n\n**Setup:**\n1. Replace channelId with your Slack channel ID\n2. Or use environment variable: SLACK_CHANNEL_ID\n3. Customize message formatting as needed\n\n**Tip:** Use Slack's Blo"
      }
    },
    {
      "id": "48a17cb4-e54e-4120-8df9-f196598d4dca",
      "name": "Post Slack Variance Report",
      "type": "n8n-nodes-base.slack",
      "position": [
        432,
        208
      ]
    },
    {
      "id": "0e5a6aae-6537-49d7-80de-cf62d6913eed",
      "name": "Note: Email Configuration",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        592
      ],
      "parameters": {
        "width": 324.2168674698795,
        "height": 280,
        "content": "## 📧 Email Notification\n\n**Setup:**\n1. Replace hardcoded email with: REPORT_RECIPIENT_EMAIL env variable\n2. Or use dynamic owner emails from data\n3. Customize HTML template as needed\n\n**Note:** Ensure"
      }
    },
    {
      "id": "550a77ca-7e03-454e-8fa0-76902b6215fe",
      "name": "Email Variance Digest (Outlook)",
      "type": "n8n-nodes-base.microsoftOutlook",
      "position": [
        432,
        400
      ]
    }
  ],
  "connections": {
    "Daily OKR Sync Trigger": {
      "main": [
        [
          {
            "node": "Fetch OKRs from Monday.com",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Jira Epic Details": {
      "main": [
        [
          {
            "node": "Normalize Jira Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Jira Response": {
      "main": [
        [
          {
            "node": "Join KR + Epic Data (SQL Merge)",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Split KR → Epics Mapper": {
      "main": [
        [
          {
            "node": "Join KR + Epic Data (SQL Merge)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Jira Epic Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch OKRs from Monday.com": {
      "main": [
        [
          {
            "node": "Map Monday Fields → Standard KR Schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compute KR Progress & Variance": {
      "main": [
        [
          {
            "node": "Update KR Status on Monday",
            "type": "main",
            "index": 0
          },
          {
            "node": "Aggregate Final Results for Reporting",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Join KR + Epic Data (SQL Merge)": {
      "main": [
        [
          {
            "node": "Compute KR Progress & Variance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Final Results for Reporting": {
      "main": [
        [
          {
            "node": "Post Slack Variance Report",
            "type": "main",
            "index": 0
          },
          {
            "node": "Email Variance Digest (Outlook)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Monday Fields → Standard KR Schema": {
      "main": [
        [
          {
            "node": "Split KR → Epics Mapper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}