{
  "id": "rPl99EYLVHLCXg0B",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Performance Review Scheduler & Reminder",
  "tags": [],
  "nodes": [
    {
      "id": "ce6f4776-596d-498a-b3f6-2746d2e077ac",
      "name": "Daily Check at 8 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1568,
        160
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "4a46b397-1c45-4f1c-9fd2-03922787e2ea",
      "name": "Get Review Schedule",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1344,
        160
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "ReviewSchedule"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_REVIEW_SPREADSHEET_ID"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "427bb5c4-6675-4a32-b13d-acd17a748a57",
      "name": "Filter Upcoming Reviews",
      "type": "n8n-nodes-base.code",
      "position": [
        -1152,
        160
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst today = $now.toDate();\nconst threeDaysLater = new Date(today);\nthreeDaysLater.setDate(today.getDate() + 3);\n\nconst upcomingReviews = items.filter(item => {\n  const reviewDate = new Date(item.json.ReviewDate);\n  return reviewDate >= today && reviewDate <= threeDaysLater && item.json.Status !== 'Completed';\n});\n\nconst todayReviews = upcomingReviews.filter(item => {\n  const reviewDate = new Date(item.json.ReviewDate);\n  return reviewDate.toDateString() === today.toDateString();\n});\n\nconst reminderReviews = upcomingReviews.filter(item => {\n  const reviewDate = new Date(item.json.ReviewDate);\n  return reviewDate.toDateString() !== today.toDateString();\n});\n\nreturn {\n  upcomingReviews: upcomingReviews,\n  todayReviews: todayReviews,\n  reminderReviews: reminderReviews\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "86940cc8-365c-4045-b316-58a27f0ca209",
      "name": "Reviews Scheduled?",
      "type": "n8n-nodes-base.if",
      "position": [
        -944,
        160
      ],
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{$json.upcomingReviews.length}}",
              "operation": "larger"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f764fef2-2e57-4797-9252-edfee5648ec5",
      "name": "Split Into Items",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -752,
        160
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "upcomingReviews"
      },
      "typeVersion": 1
    },
    {
      "id": "3e05bca6-7db2-4153-858d-3843e805ee2c",
      "name": "Prepare Review Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -544,
        160
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "calendar_event",
              "name": "calendarEventId",
              "type": "string",
              "value": "={{$json.CalendarEventId}}"
            },
            {
              "id": "employee_name",
              "name": "employeeName",
              "type": "string",
              "value": "={{$json.EmployeeName}}"
            },
            {
              "id": "reviewer_name",
              "name": "reviewerName",
              "type": "string",
              "value": "={{$json.ReviewerName}}"
            },
            {
              "id": "review_date",
              "name": "reviewDate",
              "type": "string",
              "value": "={{$json.ReviewDate}}"
            },
            {
              "id": "review_type",
              "name": "reviewType",
              "type": "string",
              "value": "={{$json.ReviewType}}"
            },
            {
              "id": "employee_email",
              "name": "employeeEmail",
              "type": "string",
              "value": "={{$json.EmployeeEmail}}"
            },
            {
              "id": "reviewer_email",
              "name": "reviewerEmail",
              "type": "string",
              "value": "={{$json.ReviewerEmail}}"
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "629584ef-1552-4f7f-af54-93131d0f4ff6",
      "name": "Send Email Reminder",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        -352,
        64
      ],
      "parameters": {
        "options": {},
        "subject": "=\ud83c\udfaf Performance Review Reminder - {{$json.employeeName}}",
        "toEmail": "={{$json.employeeEmail}}, {{$json.reviewerEmail}}",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "1e20e938-b64e-4c9f-ba21-9aa768446064",
      "name": "Update Calendar Event",
      "type": "n8n-nodes-base.googleCalendar",
      "position": [
        -352,
        256
      ],
      "parameters": {
        "end": "2025-10-24T00:00:00",
        "start": "2025-10-16T00:00:00",
        "calendar": "primary",
        "additionalFields": {}
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "fe4e328e-f85e-400c-97c4-33610d3a0cfe",
      "name": "Notify HR on Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        -144,
        160
      ],
      "parameters": {
        "text": "=\ud83c\udfaf *Performance Review Reminder Sent*\n\n*Employee:* {{$json.employeeName}}\n*Reviewer:* {{$json.reviewerName}}\n*Review Type:* {{$json.reviewType}}\n*Scheduled Date:* {{$json.reviewDate}}\n\n\ud83d\udce7 Reminder emails sent to both parties\n\ud83d\udcc5 Calendar event updated",
        "user": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "select": "user",
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "ee18e67d-1af3-48e0-b614-95b80fc80da0",
      "name": "Update Review Status",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        64,
        160
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "ReviewSchedule"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_REVIEW_SPREADSHEET_ID"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "3a012941-6f69-44f8-ace3-2368a75d76c3",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1600,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 176,
        "height": 404,
        "content": "## Daily morning check\n\nRuns at 8 AM every day"
      },
      "typeVersion": 1
    },
    {
      "id": "46806887-42b2-438c-8b1a-1602abb5ed0d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1408,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 192,
        "height": 404,
        "content": "## Fetches review schedule\n\nRetrieves all planned reviews"
      },
      "typeVersion": 1
    },
    {
      "id": "d2559dee-a579-4173-ae68-d6cd86f20306",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1184,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 192,
        "height": 404,
        "content": "## Filters upcoming reviews\n\nChecks next 3 days"
      },
      "typeVersion": 1
    },
    {
      "id": "318eb680-fba0-4aff-bf42-bf3fbac19020",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -976,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 192,
        "height": 404,
        "content": "## Validates schedule\n\nEnsures reviews exist"
      },
      "typeVersion": 1
    },
    {
      "id": "dcfa2a1a-e180-4c48-b55e-259dc81c4bf6",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 320,
        "height": 404,
        "content": "## Processes each review\n\nSplits and prepares data"
      },
      "typeVersion": 1
    },
    {
      "id": "0c5a911d-494f-4097-a102-0dc421af21b6",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -368,
        -144
      ],
      "parameters": {
        "color": 4,
        "width": 540,
        "height": 580,
        "content": "## Multi-channel notifications & tracking\n\nSends reminders via email, updates calendar, notifies HR, and logs status"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "45f2da8b-5c9e-4979-83b5-fa12aa5a3087",
  "connections": {
    "Split Into Items": {
      "main": [
        [
          {
            "node": "Prepare Review Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify HR on Slack": {
      "main": [
        [
          {
            "node": "Update Review Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reviews Scheduled?": {
      "main": [
        [
          {
            "node": "Split Into Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Check at 8 AM": {
      "main": [
        [
          {
            "node": "Get Review Schedule",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Review Schedule": {
      "main": [
        [
          {
            "node": "Filter Upcoming Reviews",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Review Data": {
      "main": [
        [
          {
            "node": "Send Email Reminder",
            "type": "main",
            "index": 0
          },
          {
            "node": "Update Calendar Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Email Reminder": {
      "main": [
        [
          {
            "node": "Notify HR on Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Calendar Event": {
      "main": [
        [
          {
            "node": "Notify HR on Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Upcoming Reviews": {
      "main": [
        [
          {
            "node": "Reviews Scheduled?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}