{
  "name": "SOP Document Creator & Updater",
  "nodes": [
    {
      "parameters": {
        "content": "## \ud83d\udccb SOP Document Processor\n\n### What this workflow does\n1. Watches Google Drive for new SOP documents\n2. Downloads and extracts SOP information\n3. Parses procedures, safety items, checkpoints\n4. Generates quick checklist from procedures\n5. Logs SOP details to Google Sheets\n6. Sends summary to Slack with checklist\n\n### Setup steps\n1. Get PDF Vector API key from pdfvector.com/api-keys\n2. Create Google Drive folder for SOP documents\n3. Create Google Sheet with columns:\n   SOP Number, Title, Version, Department, Effective Date, Author, Approver, Procedure Steps, Safety Items, Quality Checkpoints, Document Link, Last Updated\n4. Update folder ID and spreadsheet ID in nodes\n5. Connect Slack for notifications\n\n### Perfect for\n- Operations managers\n- Quality assurance teams\n- Compliance officers\n- Training departments",
        "height": 560,
        "width": 380,
        "color": 5
      },
      "id": "sticky-main",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -120,
        40
      ]
    },
    {
      "parameters": {
        "content": "## \u2705 SOP Elements Extracted\n\n- Purpose/Scope\n- Responsibilities\n- Step-by-step procedures\n- Safety warnings\n- Required equipment\n- Quality checkpoints\n- Revision history",
        "height": 220,
        "width": 220
      },
      "id": "sticky-elements",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1080,
        40
      ]
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "value": "YOUR_SOP_FOLDER_ID",
          "mode": "list",
          "cachedResultName": "SOP Documents"
        },
        "event": "fileCreated",
        "options": {}
      },
      "id": "gdrive-trigger",
      "name": "New SOP Document",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        300,
        300
      ]
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $json.id }}",
          "mode": "id"
        },
        "options": {}
      },
      "id": "gdrive-download",
      "name": "Download SOP",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        500,
        300
      ]
    },
    {
      "parameters": {
        "operation": "extract",
        "inputType": "file",
        "prompt": "Extract SOP (Standard Operating Procedure) as flat fields. title, sopNumber, version, effectiveDate (YYYY-MM-DD), author, approver, department, purpose, scope, responsibilitiesList (semicolon-separated formatted as: role: duties), equipmentList (semicolon-separated required equipment/materials), safetyPrecautionsList (semicolon-separated safety warnings), proceduresList (semicolon-separated steps formatted as: stepNumber. action - details), qualityCheckpointsList (semicolon-separated formatted as: checkpoint: criteria), revisionHistory (semicolon-separated formatted as: version date changes), procedureCount (number), safetyCount (number), checkpointCount (number).",
        "schema": "{\"type\": \"object\", \"properties\": {\"title\": {\"type\": \"string\"}, \"sopNumber\": {\"type\": \"string\"}, \"version\": {\"type\": \"string\"}, \"effectiveDate\": {\"type\": \"string\"}, \"author\": {\"type\": \"string\"}, \"approver\": {\"type\": \"string\"}, \"department\": {\"type\": \"string\"}, \"purpose\": {\"type\": \"string\"}, \"scope\": {\"type\": \"string\"}, \"responsibilitiesList\": {\"type\": \"string\"}, \"equipmentList\": {\"type\": \"string\"}, \"safetyPrecautionsList\": {\"type\": \"string\"}, \"proceduresList\": {\"type\": \"string\"}, \"qualityCheckpointsList\": {\"type\": \"string\"}, \"revisionHistory\": {\"type\": \"string\"}, \"procedureCount\": {\"type\": \"number\"}, \"safetyCount\": {\"type\": \"number\"}, \"checkpointCount\": {\"type\": \"number\"}}, \"additionalProperties\": false}"
      },
      "id": "pdfvector-extract",
      "name": "PDF Vector Extract",
      "type": "n8n-nodes-pdfvector.pdfVector",
      "typeVersion": 2,
      "position": [
        700,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const data = ($input.first().json?.data || $input.first().json) || {};\nconst fileName = $('New SOP Document').item.json.name;\nconst fileId   = $('New SOP Document').item.json.id;\n\nconst procedures = (data.proceduresList || '').split(';').filter(p => p.trim());\nconst safety     = (data.safetyPrecautionsList || '').split(';').filter(s => s.trim());\nconst checkpoints= (data.qualityCheckpointsList || '').split(';').filter(c => c.trim());\n\nconst checklistItems = procedures.map(p => `\u2610 ${p.trim()}`).join('\\n') || 'No procedures found';\nconst safetyList     = safety.map(s => `\u26a0\ufe0f ${s.trim()}`).join('\\n')     || 'None specified';\nconst checkpointList = checkpoints.map(c => `\u2713 ${c.trim()}`).join('\\n') || 'None specified';\n\nreturn [{ json: {\n  title:           data.title          || 'Untitled SOP',\n  sopNumber:       data.sopNumber      || 'N/A',\n  version:         data.version        || '1.0',\n  effectiveDate:   data.effectiveDate  || 'N/A',\n  author:          data.author         || 'N/A',\n  approver:        data.approver       || 'N/A',\n  department:      data.department     || 'N/A',\n  purpose:         data.purpose        || 'N/A',\n  scope:           data.scope          || 'N/A',\n  checklistItems, safetyList, checkpointList,\n  procedureCount:  parseInt(data.procedureCount)  || procedures.length,\n  safetyCount:     parseInt(data.safetyCount)     || safety.length,\n  checkpointCount: parseInt(data.checkpointCount) || checkpoints.length,\n  fileName, fileId,\n  processedAt: new Date().toISOString()\n}}];"
      },
      "id": "process-sop",
      "name": "Process SOP",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "list",
          "cachedResultName": "SOP Library"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "SOPs"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "SOP Number": "={{ $json.sopNumber }}",
            "Title": "={{ $json.title }}",
            "Version": "={{ $json.version }}",
            "Department": "={{ $json.department }}",
            "Effective Date": "={{ $json.effectiveDate }}",
            "Author": "={{ $json.author }}",
            "Approver": "={{ $json.approver }}",
            "Procedure Steps": "={{ $json.procedureCount }}",
            "Safety Items": "={{ $json.safetyCount }}",
            "Quality Checkpoints": "={{ $json.checkpointCount }}",
            "Document Link": "=https://drive.google.com/file/d/{{ $json.fileId }}/view",
            "Last Updated": "={{ $json.processedAt.split('T')[0] }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "SOP Number",
              "displayName": "SOP Number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Title",
              "displayName": "Title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Version",
              "displayName": "Version",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Department",
              "displayName": "Department",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Effective Date",
              "displayName": "Effective Date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Author",
              "displayName": "Author",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Approver",
              "displayName": "Approver",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Procedure Steps",
              "displayName": "Procedure Steps",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Safety Items",
              "displayName": "Safety Items",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Quality Checkpoints",
              "displayName": "Quality Checkpoints",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Document Link",
              "displayName": "Document Link",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Updated",
              "displayName": "Last Updated",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {}
      },
      "id": "sheets-log",
      "name": "Log to SOP Library",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.4,
      "position": [
        1100,
        300
      ]
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "YOUR_SLACK_CHANNEL_ID",
          "mode": "list",
          "cachedResultName": "ops-team"
        },
        "text": "=\ud83d\udccb *SOP Document Processed*\n\n*Title:* {{ $('Process SOP').item.json.title }}\n*SOP #:* {{ $('Process SOP').item.json.sopNumber }}\n*Version:* {{ $('Process SOP').item.json.version }}\n*Department:* {{ $('Process SOP').item.json.department }}\n\n\ud83d\udcca *Summary:*\n\u2022 Procedure Steps: {{ $('Process SOP').item.json.procedureCount }}\n\u2022 Safety Items: {{ $('Process SOP').item.json.safetyCount }}\n\u2022 Quality Checkpoints: {{ $('Process SOP').item.json.checkpointCount }}\n\n\ud83d\udcdd *Quick Checklist:*\n{{ $('Process SOP').item.json.checklistItems }}\n\n\ud83d\udd17 <https://drive.google.com/file/d/{{ $('Process SOP').item.json.fileId }}/view|View Full SOP>",
        "options": {}
      },
      "id": "slack-notify",
      "name": "Send to Slack",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        1300,
        300
      ]
    }
  ],
  "connections": {
    "New SOP Document": {
      "main": [
        [
          {
            "node": "Download SOP",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download SOP": {
      "main": [
        [
          {
            "node": "PDF Vector Extract",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PDF Vector Extract": {
      "main": [
        [
          {
            "node": "Process SOP",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process SOP": {
      "main": [
        [
          {
            "node": "Log to SOP Library",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to SOP Library": {
      "main": [
        [
          {
            "node": "Send to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}