Flux de travail d'approbation et d'audit de documents à plusieurs niveaux

Avancé

Ceci est unDocument Extraction, Multimodal AIworkflow d'automatisation du domainecontenant 38 nœuds.Utilise principalement des nœuds comme If, Set, Form, Gmail, Crypto. Automatisation de l'approbation de documents pour les workflows multi-niveaux via Supabase et Gmail

Prérequis
  • Compte Google et informations d'identification Gmail API
  • Point de terminaison HTTP Webhook (généré automatiquement par n8n)
  • URL et Clé API Supabase
  • Peut nécessiter les informations d'identification d'authentification de l'API cible
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "id": "5myl9GWWVupDIebk",
  "meta": {
    "instanceId": "70273a2379644db63ce659827cfd8abac2d0b189210eafa02dd5376e3a62cd1d",
    "templateCredsSetupCompleted": true
  },
  "name": "Multi-Level Document Approval & Audit Workflow",
  "tags": [],
  "nodes": [
    {
      "id": "9e61af97-d649-4260-becd-ea8865bad9ff",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -560,
        1104
      ],
      "webhookId": "df187a3e-6f1c-4dc6-9821-47f3a043c43e",
      "parameters": {
        "path": "approve",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "cb8cc119-29a2-48e7-84bf-81f79d57c27e",
      "name": "Audit1",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -256,
        2032
      ],
      "parameters": {
        "tableId": "audit_logs",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "document_id",
              "fieldValue": "={{ $('get_approval_data').item.json.document_id }}"
            },
            {
              "fieldId": "action",
              "fieldValue": "approval_sent"
            },
            {
              "fieldId": "actor_email",
              "fieldValue": "system@workflow"
            },
            {
              "fieldId": "details",
              "fieldValue": "=Level {{ $('get_next_level').item.json.level_number }}  requests sent to role_id {{ $('generate_uuid').item.json.role_id}} "
            }
          ]
        }
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7dd27017-db27-40d2-ae81-1f5e8bd296b5",
      "name": "Mise à Jour Finale du Document",
      "type": "n8n-nodes-base.supabase",
      "position": [
        80,
        1808
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $('get_approval_data').item.json.document_id }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "documents",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "status",
              "fieldValue": "={{ $json.status }}"
            },
            {
              "fieldId": "updated_at",
              "fieldValue": "={{ new Date(Date.now()).toISOString() }}"
            }
          ]
        },
        "operation": "update"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "564ca96f-4b65-4f0b-b075-1a02eed98893",
      "name": "save_document",
      "type": "n8n-nodes-base.supabase",
      "position": [
        816,
        0
      ],
      "parameters": {
        "tableId": "documents",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "title",
              "fieldValue": "={{ $('start_approval_form').item.json.Title }}"
            },
            {
              "fieldId": "content",
              "fieldValue": "={{ $('start_approval_form').item.json.data[0].filename }}"
            },
            {
              "fieldId": "submitted_by",
              "fieldValue": "1"
            },
            {
              "fieldId": "status",
              "fieldValue": "Pending"
            }
          ]
        }
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "98fbb076-c588-4e88-8a62-b91c6adab3c2",
      "name": "get_workflow_level_one",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1184,
        0
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "level_number",
              "keyValue": "1"
            }
          ]
        },
        "tableId": "workflow_levels",
        "operation": "get"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "550fde74-26c2-4a04-bfcb-cc801f2bdf50",
      "name": "get_user_by_role",
      "type": "n8n-nodes-base.supabase",
      "position": [
        448,
        224
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "role_id",
              "keyValue": "={{ $json.role_id }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "users",
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d45ef572-ca77-4e3b-b040-933d14d54763",
      "name": "create_uuid_token",
      "type": "n8n-nodes-base.crypto",
      "position": [
        816,
        224
      ],
      "parameters": {
        "action": "generate"
      },
      "typeVersion": 1
    },
    {
      "id": "5b325046-052d-4f11-960c-f97a6ac79703",
      "name": "create_record_approvals",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1184,
        224
      ],
      "parameters": {
        "tableId": "approvals",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "document_id",
              "fieldValue": "={{ $('save_document').item.json.id }}"
            },
            {
              "fieldId": "level_id",
              "fieldValue": "={{ $('get_workflow_level_one').item.json.id }}"
            },
            {
              "fieldId": "approver_id",
              "fieldValue": "={{ $json.id }}"
            },
            {
              "fieldId": "token",
              "fieldValue": "={{ $json.data }}"
            },
            {
              "fieldId": "status",
              "fieldValue": "={{ $('save_document').item.json.status }}"
            },
            {
              "fieldId": "expiry_time",
              "fieldValue": "={{ new Date(Date.now() + 48 * 60 * 60 * 1000) }}"
            }
          ]
        }
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "cd4dc454-6893-44d7-89d5-b4703e1787d7",
      "name": "send_email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        816,
        464
      ],
      "webhookId": "7eb15f9c-c5a6-402b-8c53-ac0f1094602c",
      "parameters": {
        "sendTo": "={{ $('create_uuid_token').item.json.email }}",
        "message": "=<p>Please review: {{ $('save_document').item.json.title }}</p>\n<p>\n  <a href=\"http://localhost:5678/webhook-test/doc-approval/approve?token={{$json.token}}&decision=approved\">Approve</a> |\n  <a href=\"http://localhost:5678/webhook-test/doc-approvalapprove?token={{$json.token}}&decision=rejected\">Reject</a>\n</p>",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          }
        },
        "subject": "=Document Approval Request -  {{ $('save_document').item.json.title }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "nbxshtC1cYPiRV0b",
          "name": "Gmail account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "879f0811-789f-426e-8a09-caf7c326b3fc",
      "name": "audit_invites",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1200,
        464
      ],
      "parameters": {
        "tableId": "audit_logs",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "document_id",
              "fieldValue": "={{ $('save_document').item.json.id }}"
            },
            {
              "fieldId": "action",
              "fieldValue": "approval_sent"
            },
            {
              "fieldId": "actor_email",
              "fieldValue": "system@workflow"
            },
            {
              "fieldId": "details",
              "fieldValue": "=Level 1 requests sent to role_id {{ $('get_workflow_level_one').item.json.role_id}} "
            }
          ]
        }
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4c3db623-dc84-47cd-81c3-2d1553f0218b",
      "name": "start_approval_form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        128,
        0
      ],
      "webhookId": "f0834914-b1a9-4176-9910-9e67714b9495",
      "parameters": {
        "options": {
          "path": "approval-process-start",
          "ignoreBots": true,
          "buttonLabel": "Send for Approval",
          "appendAttribution": true,
          "useWorkflowTimezone": true
        },
        "formTitle": "Document Approval",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Title",
              "placeholder": "Give some Title of document ",
              "requiredField": true
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "Description",
              "placeholder": "Describe what document all about. "
            },
            {
              "fieldType": "file",
              "fieldLabel": "data",
              "requiredField": true,
              "acceptFileTypes": ".pdf"
            }
          ]
        },
        "formDescription": "Document Approval Workflow "
      },
      "typeVersion": 2.2,
      "alwaysOutputData": false
    },
    {
      "id": "3523cf77-050b-46f7-b06e-975ae91c606f",
      "name": "get_approval_data",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -272,
        1104
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "token",
              "keyValue": "={{ $json.query.token }}"
            }
          ]
        },
        "tableId": "approvals",
        "operation": "get"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "0047e141-6fe8-40b3-b998-874e2c3fa018",
      "name": "update_approval_data",
      "type": "n8n-nodes-base.supabase",
      "position": [
        416,
        1088
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "approver_id",
              "keyValue": "={{ $json.approver_id }}",
              "condition": "eq"
            },
            {
              "keyName": "status",
              "keyValue": "Pending",
              "condition": "eq"
            },
            {
              "keyName": "token",
              "keyValue": "={{ $json.token }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "approvals",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "status",
              "fieldValue": "={{ $('Webhook').item.json.query.decision }}"
            },
            {
              "fieldId": "acted_at",
              "fieldValue": "={{ new Date(Date.now()).toISOString() }}"
            }
          ]
        },
        "matchType": "allFilters",
        "operation": "update"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4f6b45fc-e8de-469d-a936-de70f9c890c0",
      "name": "check_reject_or_approve",
      "type": "n8n-nodes-base.if",
      "position": [
        800,
        1088
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "6222263f-cd22-457d-8446-b19f7e1b6ffb",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Webhook').item.json.query.decision }}",
              "rightValue": "approved"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6afc3654-1ac1-43a0-a800-2d60a676f336",
      "name": "get_level_details",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1168,
        1072
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $('get_approval_data').item.json.level_id }}"
            }
          ]
        },
        "tableId": "workflow_levels",
        "operation": "get"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e8913824-5efa-46f2-b95d-d065491b63b1",
      "name": "get_next_level",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1520,
        1072
      ],
      "parameters": {
        "limit": 1,
        "filters": {
          "conditions": [
            {
              "keyName": "level_number",
              "keyValue": "={{ $json.level_number }}",
              "condition": "gt"
            }
          ]
        },
        "tableId": "workflow_levels",
        "operation": "getAll"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "ced013ad-e2c4-42b0-9a4a-63198d442a21",
      "name": "is_last_level",
      "type": "n8n-nodes-base.if",
      "position": [
        -544,
        1456
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "fb67a0fe-ced5-47a8-8f08-805d4253d0cf",
              "operator": {
                "type": "object",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $('get_next_level').item.json }}",
              "rightValue": "={{ {} }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8ab1e933-546e-4f31-8e4b-f40e6fd24ccc",
      "name": "get_workflow_by_level",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -272,
        1440
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "level_number",
              "keyValue": "= {{ $json.level_number }}"
            }
          ]
        },
        "tableId": "workflow_levels",
        "operation": "get"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "68732d0b-c579-45dd-90b5-022bacccd8c3",
      "name": "get_user_by_role1",
      "type": "n8n-nodes-base.supabase",
      "position": [
        80,
        1440
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "role_id",
              "keyValue": "={{ $json.role_id }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "users",
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4075c718-7f9d-41ef-a8d9-aad892838493",
      "name": "generate_uuid",
      "type": "n8n-nodes-base.crypto",
      "position": [
        416,
        1440
      ],
      "parameters": {
        "action": "generate"
      },
      "typeVersion": 1
    },
    {
      "id": "4c8bac58-805f-4a43-92a0-ebfde03c5092",
      "name": "create_approval_record",
      "type": "n8n-nodes-base.supabase",
      "position": [
        800,
        1456
      ],
      "parameters": {
        "tableId": "approvals",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "document_id",
              "fieldValue": "={{ $('get_approval_data').item.json.document_id }}"
            },
            {
              "fieldId": "level_id",
              "fieldValue": "={{ $('get_next_level').item.json.id }}"
            },
            {
              "fieldId": "approver_id",
              "fieldValue": "={{ $json.id }}"
            },
            {
              "fieldId": "token",
              "fieldValue": "={{ $json.data }}"
            },
            {
              "fieldId": "status",
              "fieldValue": "=Pending"
            },
            {
              "fieldId": "expiry_time",
              "fieldValue": "={{ new Date(Date.now() + 48 * 60 * 60 * 1000) }}"
            }
          ]
        }
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ebd1975c-a8c6-4703-89a0-9eb062aae079",
      "name": "send_emai_by_level",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -560,
        2032
      ],
      "webhookId": "7eb15f9c-c5a6-402b-8c53-ac0f1094602c",
      "parameters": {
        "sendTo": "={{ $('generate_uuid').item.json.email }}",
        "message": "=<p>Please review:</p>\n<p>\n  <a href=\"http://localhost:5678/webhook-test/approve?token={{ $('generate_uuid').item.json.data }}&decision=approved\">Approve</a> |\n  <a href=\"http://localhost:5678/webhook-test/approve?token={{ $('generate_uuid').item.json.data }}&decision=rejected\">Reject</a>\n</p>",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          }
        },
        "subject": "=Document Approval Request - {{ $('get_document_details').item.json.title }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "nbxshtC1cYPiRV0b",
          "name": "Gmail account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "40dcfb0b-0c3f-4469-a3ba-c85793c1da1b",
      "name": "Note Adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1312,
        -240
      ],
      "parameters": {
        "width": 608,
        "height": 2528,
        "content": "## Multi-Level Document Approval & Audit Workflow\n\nThis workflow automates a **document approval process** using Supabase and Gmail.  \n\n---\n\n### Who it’s for\n- Teams that need structured multi-level document approvals.  \n- Companies managing policies, contracts, or proposals.  \n- Anyone using **Supabase** as a backend with approval/audit requirements.  \n\n---\n\n### How it works\n1. **Form Trigger** – A user submits a document via the form.  \n2. **Supabase Integration** – The document is saved in the `documents` table.  \n3. **Workflow Levels** – Fetches the correct approval level from `workflow_levels`.  \n4. **Assign Approvers** – Matches approvers by role from the `users` table.  \n5. **Approval Record** – Creates an `approvals` record with a unique token and expiry.  \n6. **Email Notification** – Sends an email with **Approve / Reject links**.  \n7. **Audit Logs** – Records every approval request in `audit_logs`.  \n\n---\n\n### How to set up\n- Configure your **Supabase credentials**.  \n- Update table IDs (`documents`, `workflow_levels`, `users`, `approvals`, `audit_logs`) to match your schema.  \n- Connect your **Gmail account**.  \n- Adjust approval expiry time (`48h` default).  \n- Deploy and test via the **Form Trigger**.  \n\n---\n\n### Requirements\n- A Supabase project with the listed tables.  \n- A Gmail account connected to n8n.  \n\n---\n\n### Customization\n- Add multiple approval levels by chaining `workflow_levels`.  \n- Replace Gmail with Slack, Teams, or another notification channel.  \n- Adjust audit logging for compliance needs.  \n- Update the endpoint - http://localhost:5678/webhook-test/ based on instance and env (remove test if you run in prod)\n- Handle error in each step pf db interaction.\n\n---\n\n### 1. **Webhook Entry Point**\n- Triggered when an approver clicks the **Approve** or **Reject** link in email.  \n- Captures query parameters:  \n  - `token` (approval token)  \n  - `decision` (approved/rejected)  \n\n---\n\n### 2. **Approval Data Retrieval & Update**\n- Fetch approval record from **Supabase (approvals)** using `token`.  \n- Update approval status:  \n  - `Approved` → moves to next workflow level or final approval.  \n  - `Rejected` → document marked as rejected immediately.  \n- Records `acted_at` timestamp.  \n\n---\n\n### 3. **Decision Check**\n- **IF Node** checks whether the decision is **approved** or **rejected**.  \n- **Reject Path** → Update document status to **Rejected** in `documents`.  \n- **Approve Path** → Continue workflow level progression.  \n\n---\n\n### 4. **Workflow Level Progression**\n- Fetch details of the current workflow level.  \n- Identify the **next level** (`workflow_levels`) based on `level_number`.  \n\n#### ✅ If Next Level Exists:\n- Retrieve approvers by `role_id`.  \n- Generate unique approval tokens.  \n- Create new approval records in `approvals`.  \n- Send **email notifications** with approval/reject links.  \n\n#### ❌ If No Next Level (Last Level):\n- Update document status to **Approved** in `documents`.  \n\n---\n\n### 5. **Audit Logging**\n- Every approval action is logged into `audit_logs` table:  \n  - `document_id`  \n  - `action` (e.g., `approval_sent`, `approved`, `rejected`)  \n  - `actor_email` (system/approver)  \n  - `details` (workflow level, role info, etc.)  \n\n---\n\n## 📨 Email Template\nApproval request email includes **decision links**:  \n\n```html\n<p>Please review the document:</p>\n<p>\n  <a href=\"http://localhost:5678/webhook-test/doc-approval?token={{$json.token}}&decision=approved\">✅ Approve</a> |\n  <a href=\"http://localhost:5678/webhook-test/doc-approval?token={{$json.token}}&decision=rejected\">❌ Reject</a>\n</p>'''\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7db49d0e-c7c5-4423-af60-17e63aa9fea1",
      "name": "Note Adhésive1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        -224
      ],
      "parameters": {
        "width": 720,
        "height": 1120,
        "content": "## Database Schema\n\n```sql\n-- 1. ROLES: Define roles like Manager, Finance, HR\nCREATE TABLE roles (\n    id SERIAL PRIMARY KEY,\n    name VARCHAR(100) NOT NULL UNIQUE,\n    description TEXT\n);\n\n-- 2. USERS: All approvers (internal + external flag)\nCREATE TABLE users (\n    id SERIAL PRIMARY KEY,\n    name VARCHAR(150) NOT NULL,\n    email VARCHAR(200) NOT NULL UNIQUE,\n    role_id INT REFERENCES roles(id) ON DELETE SET NULL,\n    is_external BOOLEAN DEFAULT FALSE,\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 3. DOCUMENTS: The items that need approval\nCREATE TABLE documents (\n    id SERIAL PRIMARY KEY,\n    title VARCHAR(255) NOT NULL,\n    content TEXT, -- could also just store metadata, file path, or S3 link\n    submitted_by INT REFERENCES users(id) ON DELETE SET NULL,\n    status VARCHAR(50) DEFAULT 'Pending', -- Pending / Approved / Rejected\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 4. WORKFLOW LEVELS: Configure levels & roles\nCREATE TABLE workflow_levels (\n    id SERIAL PRIMARY KEY,\n    level_number INT NOT NULL,\n    role_id INT REFERENCES roles(id) ON DELETE CASCADE,\n    approval_type VARCHAR(20) DEFAULT 'any', -- any / all\n    description TEXT\n);\n\n-- 5. APPROVALS: Tracks individual approval actions\nCREATE TABLE approvals (\n    id SERIAL PRIMARY KEY,\n    document_id INT REFERENCES documents(id) ON DELETE CASCADE,\n    level_id INT REFERENCES workflow_levels(id) ON DELETE CASCADE,\n    approver_id INT REFERENCES users(id) ON DELETE CASCADE,\n    token VARCHAR(255) NOT NULL UNIQUE, -- one-time token for secure link\n    status VARCHAR(20) DEFAULT 'Pending', -- Pending / Approved / Rejected\n    expiry_time TIMESTAMP,\n    acted_at TIMESTAMP\n);\n\n-- 6. AUDIT LOGS (optional, for tracking history)\nCREATE TABLE audit_logs (\n    id SERIAL PRIMARY KEY,\n    document_id INT REFERENCES documents(id) ON DELETE CASCADE,\n    action VARCHAR(50), -- submitted / approved / rejected / escalated\n    actor_email VARCHAR(200),\n    details TEXT,\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n```"
      },
      "typeVersion": 1
    },
    {
      "id": "25ef7fca-6462-4806-bf01-d0c552aabae7",
      "name": "Audit",
      "type": "n8n-nodes-base.supabase",
      "position": [
        416,
        1792
      ],
      "parameters": {
        "tableId": "audit_logs",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "document_id",
              "fieldValue": "={{ $('get_approval_data').item.json.document_id }}"
            },
            {
              "fieldId": "action",
              "fieldValue": "approval_sent"
            },
            {
              "fieldId": "actor_email",
              "fieldValue": "system@workflow"
            },
            {
              "fieldId": "details",
              "fieldValue": "=Level {{ $('get_next_level').item.json.level_number }}  requests sent to role_id {{ $('generate_uuid').item.json.role_id}} "
            }
          ]
        }
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "48036695-12b4-479a-a547-eb45eb9da598",
      "name": "Répondre au Webhook1",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1552,
        2016
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "=Workflow Competed - {{ $json.Response }}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "d2c8dca0-c040-4035-bbd2-5812e571e0b9",
      "name": "upload_to_supabase_storage",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        464,
        0
      ],
      "parameters": {
        "url": "=https://<your_project_id>.supabase.co/storage/v1/object/test-n8n/{{ $binary.data.fileName }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "binaryData",
        "authentication": "predefinedCredentialType",
        "inputDataFieldName": "data",
        "nodeCredentialType": "supabaseApi"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "86e2bbb7-44b6-43f7-bf31-28453caf3369",
      "name": "fetch_file_to_review",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        432,
        464
      ],
      "parameters": {
        "url": "=https://uptttiuxuaacxrdofqgm.supabase.co/storage/v1/object/{{ $('upload_to_supabase_storage').item.json.Key }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "supabaseApi"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c82dba30-479d-4045-af9d-635f1aea605b",
      "name": "get_document_details",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1168,
        1456
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.document_id }}"
            }
          ]
        },
        "tableId": "documents",
        "operation": "get"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "13d7e82a-f7b3-4cbd-b51f-bcc1e57a1602",
      "name": "fetch_file_to_review1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1536,
        1456
      ],
      "parameters": {
        "url": "=https://<your_project_id>.supabase.co/storage/v1/object/test-n8n/{{ $json.content }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "supabaseApi"
      },
      "credentials": {
        "supabaseApi": {
          "id": "UMM6kngXouHxEYn4",
          "name": "Supabase account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "db503b96-a362-4b14-a41b-aa87bf156392",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        80,
        1104
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "eff8437b-ef76-4bef-a6c2-9d65083ab8c5",
              "operator": {
                "type": "object",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "694b4cde-a457-4496-816f-02ba86b4eb9e",
      "name": "response_message",
      "type": "n8n-nodes-base.set",
      "position": [
        800,
        1296
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d6c443be-ca83-4708-b80b-9a5eefd11d60",
              "name": "Response",
              "type": "string",
              "value": "Not a value token"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "30cd5073-3d59-48ae-a572-57157ee5e6cb",
      "name": "response_message1",
      "type": "n8n-nodes-base.set",
      "position": [
        800,
        1792
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d6c443be-ca83-4708-b80b-9a5eefd11d60",
              "name": "Response",
              "type": "string",
              "value": "Rejected"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "17e8d16b-8c04-45de-90a0-1d8fc1711cd5",
      "name": "response_message2",
      "type": "n8n-nodes-base.set",
      "position": [
        128,
        2032
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d6c443be-ca83-4708-b80b-9a5eefd11d60",
              "name": "Response",
              "type": "string",
              "value": "Approved"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bb9fb0aa-d3a2-434b-a34a-047562654983",
      "name": "Note Adhésive2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        -128
      ],
      "parameters": {
        "width": 336,
        "height": 288,
        "content": "### Update url for supabase storage "
      },
      "typeVersion": 1
    },
    {
      "id": "d902be56-14a6-4071-ae13-7b0dddf4284a",
      "name": "end_form",
      "type": "n8n-nodes-base.form",
      "position": [
        1472,
        464
      ],
      "webhookId": "3af20380-25dd-4a07-970c-29929c8037e5",
      "parameters": {
        "options": {},
        "operation": "completion",
        "completionTitle": "Approval Workflow Started."
      },
      "typeVersion": 1
    },
    {
      "id": "edf83e23-536a-4a9d-a5be-f6401690ab2a",
      "name": "Note Adhésive3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        112,
        -208
      ],
      "parameters": {
        "color": 4,
        "width": 1664,
        "height": 1120,
        "content": "## Form Submit flow"
      },
      "typeVersion": 1
    },
    {
      "id": "5109e9e9-b938-44be-8154-7dd287030589",
      "name": "Note Adhésive4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        992
      ],
      "parameters": {
        "color": 4,
        "width": 2448,
        "height": 1264,
        "content": "## Next Level Approval"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "de5c52a4-7369-4d59-a8c1-b7e4e1aa5636",
  "connections": {
    "db503b96-a362-4b14-a41b-aa87bf156392": {
      "main": [
        [
          {
            "node": "0047e141-6fe8-40b3-b998-874e2c3fa018",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "694b4cde-a457-4496-816f-02ba86b4eb9e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "25ef7fca-6462-4806-bf01-d0c552aabae7": {
      "main": [
        [
          {
            "node": "30cd5073-3d59-48ae-a572-57157ee5e6cb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cb8cc119-29a2-48e7-84bf-81f79d57c27e": {
      "main": [
        [
          {
            "node": "17e8d16b-8c04-45de-90a0-1d8fc1711cd5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9e61af97-d649-4260-becd-ea8865bad9ff": {
      "main": [
        [
          {
            "node": "3523cf77-050b-46f7-b06e-975ae91c606f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cd4dc454-6893-44d7-89d5-b4703e1787d7": {
      "main": [
        [
          {
            "node": "879f0811-789f-426e-8a09-caf7c326b3fc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "879f0811-789f-426e-8a09-caf7c326b3fc": {
      "main": [
        [
          {
            "node": "d902be56-14a6-4071-ae13-7b0dddf4284a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4075c718-7f9d-41ef-a8d9-aad892838493": {
      "main": [
        [
          {
            "node": "4c8bac58-805f-4a43-92a0-ebfde03c5092",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ced013ad-e2c4-42b0-9a4a-63198d442a21": {
      "main": [
        [
          {
            "node": "8ab1e933-546e-4f31-8e4b-f40e6fd24ccc",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "7dd27017-db27-40d2-ae81-1f5e8bd296b5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "564ca96f-4b65-4f0b-b075-1a02eed98893": {
      "main": [
        [
          {
            "node": "98fbb076-c588-4e88-8a62-b91c6adab3c2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e8913824-5efa-46f2-b95d-d065491b63b1": {
      "main": [
        [
          {
            "node": "ced013ad-e2c4-42b0-9a4a-63198d442a21",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "550fde74-26c2-4a04-bfcb-cc801f2bdf50": {
      "main": [
        [
          {
            "node": "d45ef572-ca77-4e3b-b040-933d14d54763",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "694b4cde-a457-4496-816f-02ba86b4eb9e": {
      "main": [
        [
          {
            "node": "48036695-12b4-479a-a547-eb45eb9da598",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d45ef572-ca77-4e3b-b040-933d14d54763": {
      "main": [
        [
          {
            "node": "5b325046-052d-4f11-960c-f97a6ac79703",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3523cf77-050b-46f7-b06e-975ae91c606f": {
      "main": [
        [
          {
            "node": "db503b96-a362-4b14-a41b-aa87bf156392",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6afc3654-1ac1-43a0-a800-2d60a676f336": {
      "main": [
        [
          {
            "node": "e8913824-5efa-46f2-b95d-d065491b63b1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "68732d0b-c579-45dd-90b5-022bacccd8c3": {
      "main": [
        [
          {
            "node": "4075c718-7f9d-41ef-a8d9-aad892838493",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "30cd5073-3d59-48ae-a572-57157ee5e6cb": {
      "main": [
        [
          {
            "node": "48036695-12b4-479a-a547-eb45eb9da598",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "17e8d16b-8c04-45de-90a0-1d8fc1711cd5": {
      "main": [
        [
          {
            "node": "48036695-12b4-479a-a547-eb45eb9da598",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ebd1975c-a8c6-4703-89a0-9eb062aae079": {
      "main": [
        [
          {
            "node": "cb8cc119-29a2-48e7-84bf-81f79d57c27e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4c3db623-dc84-47cd-81c3-2d1553f0218b": {
      "main": [
        [
          {
            "node": "d2c8dca0-c040-4035-bbd2-5812e571e0b9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "86e2bbb7-44b6-43f7-bf31-28453caf3369": {
      "main": [
        [
          {
            "node": "cd4dc454-6893-44d7-89d5-b4703e1787d7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c82dba30-479d-4045-af9d-635f1aea605b": {
      "main": [
        [
          {
            "node": "13d7e82a-f7b3-4cbd-b51f-bcc1e57a1602",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0047e141-6fe8-40b3-b998-874e2c3fa018": {
      "main": [
        [
          {
            "node": "4f6b45fc-e8de-469d-a936-de70f9c890c0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7dd27017-db27-40d2-ae81-1f5e8bd296b5": {
      "main": [
        [
          {
            "node": "25ef7fca-6462-4806-bf01-d0c552aabae7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "13d7e82a-f7b3-4cbd-b51f-bcc1e57a1602": {
      "main": [
        [
          {
            "node": "ebd1975c-a8c6-4703-89a0-9eb062aae079",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8ab1e933-546e-4f31-8e4b-f40e6fd24ccc": {
      "main": [
        [
          {
            "node": "68732d0b-c579-45dd-90b5-022bacccd8c3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4c8bac58-805f-4a43-92a0-ebfde03c5092": {
      "main": [
        [
          {
            "node": "c82dba30-479d-4045-af9d-635f1aea605b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "98fbb076-c588-4e88-8a62-b91c6adab3c2": {
      "main": [
        [
          {
            "node": "550fde74-26c2-4a04-bfcb-cc801f2bdf50",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4f6b45fc-e8de-469d-a936-de70f9c890c0": {
      "main": [
        [
          {
            "node": "6afc3654-1ac1-43a0-a800-2d60a676f336",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "7dd27017-db27-40d2-ae81-1f5e8bd296b5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5b325046-052d-4f11-960c-f97a6ac79703": {
      "main": [
        [
          {
            "node": "86e2bbb7-44b6-43f7-bf31-28453caf3369",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d2c8dca0-c040-4035-bbd2-5812e571e0b9": {
      "main": [
        [
          {
            "node": "564ca96f-4b65-4f0b-b075-1a02eed98893",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - Extraction de documents, IA Multimodale

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds38
Catégorie2
Types de nœuds11
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Auteur
Alok Kumar

Alok Kumar

@alokkumar

I am a Principal Software Engineer based in Ireland with a deep passion for AI and emerging technologies. With extensive experience in designing and implementing scalable software solutions, I focus on leveraging artificial intelligence to solve real-world problems. I enjoy exploring innovative applications of AI, from intelligent automation to data-driven insights, and I’m dedicated to building systems that are both efficient and impactful.

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34