Gestion du cycle de vie des contrats d'entreprise et analyse des risques avec l'IA
Ceci est unDocument Extraction, AI Summarizationworkflow d'automatisation du domainecontenant 20 nœuds.Utilise principalement des nœuds comme If, Code, Merge, Slack, Postgres. Gestion du cycle de vie des contrats d'entreprise avec analyse des risques IA
- •Token Bot Slack ou URL Webhook
- •Informations de connexion à la base de données PostgreSQL
- •Informations d'identification OAuth Salesforce
- •Informations d'identification Google Drive API
Nœuds utilisés (20)
Catégorie
{
"meta": {
"instanceId": "placeholder"
},
"nodes": [
{
"id": "workflow-overview",
"name": "Vue d'Ensemble du Workflow",
"type": "n8n-nodes-base.stickyNote",
"position": [
100,
50
],
"parameters": {
"width": 320,
"height": 180,
"content": "## Enterprise Contract Lifecycle Management\n\nThis workflow orchestrates:\n- Multi-channel contract intake\n- AI-powered extraction & analysis\n- Risk scoring & compliance checks\n- Approval routing & notifications\n- CRM integration & analytics\n- Obligation tracking & alerts"
},
"typeVersion": 1
},
{
"id": "email-trigger",
"name": "Surveiller les Emails de Contrat",
"type": "n8n-nodes-base.emailReadImap",
"notes": "Monitor email for contracts",
"position": [
250,
200
],
"parameters": {
"mailbox": "INBOX",
"options": {
"customEmailConfig": "contractreview@company.com"
},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
}
},
"typeVersion": 2
},
{
"id": "drive-trigger",
"name": "Surveiller le Drive Google",
"type": "n8n-nodes-base.googleDriveTrigger",
"notes": "Watch for new contracts",
"position": [
250,
350
],
"parameters": {
"events": [
"file:created",
"file:updated"
],
"folderID": "contracts-intake"
},
"typeVersion": 1
},
{
"id": "schedule-trigger",
"name": "Vérification CRM Horaire",
"type": "n8n-nodes-base.scheduleTrigger",
"notes": "Check CRM for contracts",
"position": [
250,
500
],
"parameters": {
"unit": "hours",
"value": 1,
"events": [
"workflowActivate"
]
},
"typeVersion": 1
},
{
"id": "salesforce-check",
"name": "Vérifier Salesforce",
"type": "n8n-nodes-base.salesforce",
"notes": "Get contracts from CRM",
"position": [
450,
500
],
"parameters": {
"filters": {
"stage": "Contract Review",
"lastModified": "={{ $now.minus({hours: 1}).toISO() }}"
},
"resource": "opportunity",
"operation": "getAll"
},
"typeVersion": 2
},
{
"id": "merge-sources",
"name": "Fusionner les Sources de Contrats",
"type": "n8n-nodes-base.merge",
"position": [
650,
350
],
"parameters": {
"mode": "multiplex",
"options": {}
},
"typeVersion": 2.1
},
{
"id": "check-duplicate",
"name": "Vérifier les Doublons",
"type": "n8n-nodes-base.postgres",
"notes": "Prevent reprocessing",
"position": [
850,
350
],
"parameters": {
"query": "SELECT contract_id FROM contracts WHERE hash = '{{ $json.fileHash }}' LIMIT 1",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "is-new-contract",
"name": "Nouveau Contrat ?",
"type": "n8n-nodes-base.if",
"position": [
1050,
350
],
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.contract_id }}",
"operation": "isEmpty"
}
]
}
},
"typeVersion": 1
},
{
"id": "extract-contract",
"name": "PDF Vector - Extraire Toutes les Données",
"type": "n8n-nodes-pdfvector.pdfVector",
"notes": "AI extraction of 50+ fields",
"position": [
1250,
350
],
"parameters": {
"prompt": "Extract comprehensive contract information including all parties (with roles, addresses, registration numbers), contract metadata (type, value, currency, effective/expiration dates), payment terms (amounts, schedules, penalties), deliverables and milestones, obligations for each party, termination conditions, liability caps, indemnification clauses, intellectual property provisions, confidentiality terms, force majeure, governing law, dispute resolution, and any special conditions. Also identify if this is a master agreement with SOWs.",
"schema": "{\"type\":\"object\",\"properties\":{\"contractId\":{\"type\":\"string\"},\"contractType\":{\"type\":\"string\"},\"masterAgreement\":{\"type\":\"boolean\"},\"parties\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"role\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"address\":{\"type\":\"string\"},\"registrationNumber\":{\"type\":\"string\"},\"signatory\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"email\":{\"type\":\"string\"}}}}}},\"contractValue\":{\"type\":\"object\",\"properties\":{\"total\":{\"type\":\"number\"},\"currency\":{\"type\":\"string\"},\"paymentStructure\":{\"type\":\"string\"}}},\"term\":{\"type\":\"object\",\"properties\":{\"effectiveDate\":{\"type\":\"string\"},\"expirationDate\":{\"type\":\"string\"},\"autoRenewal\":{\"type\":\"boolean\"},\"renewalNotice\":{\"type\":\"number\"}}},\"paymentTerms\":{\"type\":\"object\",\"properties\":{\"schedule\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"amount\":{\"type\":\"number\"},\"dueDate\":{\"type\":\"string\"},\"milestone\":{\"type\":\"string\"}}}},\"lateFees\":{\"type\":\"string\"},\"earlyPaymentDiscount\":{\"type\":\"string\"}}},\"deliverables\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"description\":{\"type\":\"string\"},\"dueDate\":{\"type\":\"string\"},\"acceptanceCriteria\":{\"type\":\"string\"},\"party\":{\"type\":\"string\"}}}},\"obligations\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"party\":{\"type\":\"string\"},\"obligation\":{\"type\":\"string\"},\"frequency\":{\"type\":\"string\"},\"deadline\":{\"type\":\"string\"}}}},\"termination\":{\"type\":\"object\",\"properties\":{\"forConvenience\":{\"type\":\"boolean\"},\"notice\":{\"type\":\"number\"},\"penaltiesForEarlyTermination\":{\"type\":\"string\"},\"terminationTriggers\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}},\"liability\":{\"type\":\"object\",\"properties\":{\"limitationOfLiability\":{\"type\":\"string\"},\"indemnification\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"insurance\":{\"type\":\"string\"}}},\"intellectualProperty\":{\"type\":\"object\",\"properties\":{\"ownership\":{\"type\":\"string\"},\"licenses\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"workForHire\":{\"type\":\"boolean\"}}},\"confidentiality\":{\"type\":\"object\",\"properties\":{\"duration\":{\"type\":\"string\"},\"exceptions\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}},\"disputeResolution\":{\"type\":\"string\"},\"governingLaw\":{\"type\":\"string\"},\"specialClauses\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}},\"required\":[\"contractType\",\"parties\"],\"additionalProperties\":false}",
"resource": "document",
"inputType": "file",
"operation": "extract",
"binaryPropertyName": "data"
},
"typeVersion": 1
},
{
"id": "risk-analysis",
"name": "PDF Vector - Analyse des Risques",
"type": "n8n-nodes-pdfvector.pdfVector",
"notes": "Multi-dimensional risk scoring",
"position": [
1450,
350
],
"parameters": {
"prompt": "Perform comprehensive risk analysis on this contract considering: 1) Legal risks (unusual terms, missing standard clauses, jurisdiction issues), 2) Financial risks (payment terms, penalties, uncapped liabilities), 3) Operational risks (unrealistic deadlines, resource requirements, dependencies), 4) Compliance risks (regulatory requirements, data protection, export controls), 5) Relationship risks (one-sided terms, termination difficulties). Provide risk scores (1-10) for each category and an overall risk rating with specific concerns.",
"resource": "document",
"inputType": "file",
"operation": "ask",
"binaryPropertyName": "data"
},
"typeVersion": 1
},
{
"id": "get-template",
"name": "Obtenir le Modèle de Contrat",
"type": "n8n-nodes-base.postgres",
"notes": "Retrieve standard template",
"position": [
1650,
250
],
"parameters": {
"query": "SELECT template_id, clauses FROM contract_templates WHERE contract_type = '{{ $json.contractType }}' AND active = true",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "analyze-score",
"name": "Analyser et Noter le Contrat",
"type": "n8n-nodes-base.code",
"notes": "Comprehensive analysis engine",
"position": [
1850,
350
],
"parameters": {
"jsCode": "// Advanced contract analysis and scoring\nconst extracted = $node['PDF Vector - Extract All Data'].json.data;\nconst riskAnalysis = JSON.parse($node['PDF Vector - Risk Analysis'].json.answer);\nconst template = $node['Get Contract Template'].json;\nconst crmData = $node['Check Salesforce'].json;\n\n// Calculate comprehensive risk score\nlet riskFactors = [];\nlet totalRiskScore = 0;\n\n// Financial risk scoring\nconst contractValue = extracted.contractValue?.total || 0;\nconst annualRevenue = crmData.account?.annualRevenue || 1000000;\nconst dealSizeRisk = (contractValue / annualRevenue) > 0.1 ? 8 : 3;\nriskFactors.push({category: 'Deal Size', score: dealSizeRisk});\n\n// Check for missing standard clauses\nconst missingClauses = [];\nif (!extracted.liability?.limitationOfLiability) {\n missingClauses.push('Limitation of Liability');\n riskFactors.push({category: 'Missing LoL', score: 9});\n}\nif (!extracted.termination?.forConvenience) {\n missingClauses.push('Termination for Convenience');\n riskFactors.push({category: 'No Exit Clause', score: 7});\n}\n\n// Payment term risks\nif (extracted.paymentTerms?.schedule?.[0]?.dueDate) {\n const firstPayment = new Date(extracted.paymentTerms.schedule[0].dueDate);\n const daysToPay = (firstPayment - new Date()) / (1000 * 60 * 60 * 24);\n if (daysToPay > 60) {\n riskFactors.push({category: 'Extended Payment Terms', score: 6});\n }\n}\n\n// Auto-renewal risk\nif (extracted.term?.autoRenewal && extracted.term?.renewalNotice < 30) {\n riskFactors.push({category: 'Short Renewal Notice', score: 7});\n}\n\n// Calculate weighted risk score\ntotalRiskScore = riskFactors.reduce((sum, risk) => sum + risk.score, 0) / riskFactors.length;\n\n// Determine approval level\nlet approvalLevel = 'Manager';\nif (totalRiskScore > 7 || contractValue > 1000000) approvalLevel = 'Director';\nif (totalRiskScore > 8 || contractValue > 5000000) approvalLevel = 'VP';\nif (missingClauses.includes('Limitation of Liability')) approvalLevel = 'Legal';\n\n// Calculate key dates and alerts\nconst alerts = [];\nconst today = new Date();\n\n// Contract expiration alert\nif (extracted.term?.expirationDate) {\n const expDate = new Date(extracted.term.expirationDate);\n const daysToExpire = (expDate - today) / (1000 * 60 * 60 * 24);\n if (daysToExpire < 90) {\n alerts.push({\n type: 'Contract Expiration',\n date: extracted.term.expirationDate,\n daysRemaining: Math.floor(daysToExpire),\n severity: daysToExpire < 30 ? 'High' : 'Medium'\n });\n }\n}\n\n// Deliverable alerts\nif (extracted.deliverables) {\n extracted.deliverables.forEach(deliverable => {\n const dueDate = new Date(deliverable.dueDate);\n const daysToDue = (dueDate - today) / (1000 * 60 * 60 * 24);\n if (daysToDue > 0 && daysToDue < 30) {\n alerts.push({\n type: 'Upcoming Deliverable',\n description: deliverable.description,\n date: deliverable.dueDate,\n daysRemaining: Math.floor(daysToDue),\n severity: daysToDue < 7 ? 'High' : 'Medium'\n });\n }\n });\n}\n\nreturn [{\n json: {\n contractAnalysis: {\n contractId: extracted.contractId || `AUTO-${Date.now()}`,\n type: extracted.contractType,\n parties: extracted.parties,\n value: contractValue,\n currency: extracted.contractValue?.currency || 'USD',\n effectiveDate: extracted.term?.effectiveDate,\n expirationDate: extracted.term?.expirationDate\n },\n riskAssessment: {\n overallScore: totalRiskScore,\n riskLevel: totalRiskScore > 7 ? 'High' : totalRiskScore > 4 ? 'Medium' : 'Low',\n riskFactors: riskFactors,\n missingClauses: missingClauses,\n aiRiskAnalysis: riskAnalysis\n },\n approvalRouting: {\n level: approvalLevel,\n reason: riskFactors.filter(r => r.score > 6).map(r => r.category).join(', ')\n },\n alerts: alerts,\n crmAlignment: {\n opportunityId: crmData.id,\n accountName: crmData.account?.name,\n dealSize: crmData.amount,\n stage: crmData.stage\n },\n metadata: {\n sourceChannel: $input.first().json.sourceChannel || 'Unknown',\n receivedDate: new Date().toISOString(),\n fileHash: $json.fileHash\n },\n fullExtraction: extracted\n }\n}];"
},
"typeVersion": 2
},
{
"id": "save-contract",
"name": "Sauvegarder dans le Dépôt de Contrats",
"type": "n8n-nodes-base.postgres",
"notes": "Central contract database",
"position": [
2050,
350
],
"parameters": {
"table": "contracts",
"values": "={{ $json.contractAnalysis.contractId }},={{ $json.contractAnalysis.type }},={{ JSON.stringify($json.contractAnalysis.parties) }},={{ $json.contractAnalysis.value }},={{ $json.contractAnalysis.effectiveDate }},={{ $json.contractAnalysis.expirationDate }},={{ $json.riskAssessment.overallScore }},={{ $json.riskAssessment.riskLevel }},={{ $json.approvalRouting.level }},={{ JSON.stringify($json.fullExtraction) }},={{ JSON.stringify($json.riskAssessment) }},={{ JSON.stringify($json.alerts) }},={{ JSON.stringify($json.crmAlignment) }},={{ $now.toISO() }},pending_approval",
"columns": "contract_id,type,parties,value,effective_date,expiration_date,risk_score,risk_level,approval_level,extracted_data,risk_analysis,alerts,crm_data,created_at,status",
"operation": "insert"
},
"typeVersion": 2.4
},
{
"id": "needs-legal",
"name": "Nécessite une Revue Juridique ?",
"type": "n8n-nodes-base.if",
"position": [
2250,
350
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.riskAssessment.riskLevel }}",
"value2": "High",
"operation": "equals"
}
],
"boolean": [
{
"value1": "={{ $json.riskAssessment.missingClauses.length > 0 }}",
"value2": true
}
]
},
"combineOperation": "any"
},
"typeVersion": 1
},
{
"id": "notify-legal",
"name": "Notifier l'Équipe Juridique",
"type": "n8n-nodes-base.slack",
"notes": "High risk alert",
"position": [
2450,
450
],
"parameters": {
"text": "⚠️ High Risk Contract Requires Review",
"channel": "#legal-contracts",
"attachments": [
{
"ts": "={{ Date.now() / 1000 }}",
"color": "#ff0000",
"title": "{{ $json.contractAnalysis.type }} - {{ $json.contractAnalysis.parties[0].name }}",
"fields": {
"item": [
{
"short": true,
"title": "Contract Value",
"value": "{{ $json.contractAnalysis.currency }} {{ $json.contractAnalysis.value.toLocaleString() }}"
},
{
"short": true,
"title": "Risk Score",
"value": "{{ $json.riskAssessment.overallScore }}/10"
},
{
"short": false,
"title": "Risk Factors",
"value": "{{ $json.riskAssessment.riskFactors.filter(r => r.score > 6).map(r => r.category).join('\\n') }}"
},
{
"short": false,
"title": "Missing Clauses",
"value": "{{ $json.riskAssessment.missingClauses.join('\\n') || 'None' }}"
}
]
},
"footer": "Contract Review System",
"title_link": "https://contracts.company.com/review/{{ $json.contractAnalysis.contractId }}"
}
]
},
"typeVersion": 2.1
},
{
"id": "update-salesforce",
"name": "Mettre à Jour Salesforce",
"type": "n8n-nodes-base.salesforce",
"notes": "Sync with CRM",
"position": [
2450,
250
],
"parameters": {
"resource": "opportunity",
"operation": "update",
"updateFields": {
"customFields": {
"Contract_ID__c": "={{ $json.contractAnalysis.contractId }}",
"Contract_Status__c": "Under Review",
"Contract_Expiration__c": "={{ $json.contractAnalysis.expirationDate }}",
"Contract_Risk_Score__c": "={{ $json.riskAssessment.overallScore }}"
}
},
"opportunityId": "={{ $json.crmAlignment.opportunityId }}"
},
"typeVersion": 2
},
{
"id": "daily-alerts",
"name": "Vérification Quotidienne des Alertes",
"type": "n8n-nodes-base.scheduleTrigger",
"notes": "Check for upcoming deadlines",
"position": [
250,
650
],
"parameters": {
"unit": "days",
"value": 1,
"events": [
"workflowActivate"
]
},
"typeVersion": 1
},
{
"id": "get-alerts",
"name": "Obtenir les Alertes à Venir",
"type": "n8n-nodes-base.postgres",
"notes": "Find contracts with deadlines",
"position": [
450,
650
],
"parameters": {
"query": "SELECT c.*, json_array_elements(c.alerts) as alert FROM contracts c WHERE c.status = 'active' AND (alert->>'date')::date BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL '30 days'",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "send-daily-summary",
"name": "Envoyer le Résumé Quotidien",
"type": "n8n-nodes-base.slack",
"notes": "Daily deadline digest",
"position": [
650,
650
],
"parameters": {
"text": "=📅 Daily Contract Alert Summary\\n\\nYou have {{ $items.length }} upcoming contract deadlines:\\n\\n{{ $items.map(item => `• ${item.json.alert.type}: ${item.json.alert.description || item.json.contract_id} - Due ${item.json.alert.date} (${item.json.alert.daysRemaining} days)`).join('\\n') }}",
"select": "channel",
"channelId": {
"__rl": true,
"value": "contract-alerts"
},
"authentication": "oAuth2"
},
"typeVersion": 2.1
},
{
"id": "analytics-note",
"name": "Tableau de Bord Analytique",
"type": "n8n-nodes-base.stickyNote",
"position": [
2650,
350
],
"parameters": {
"width": 300,
"height": 200,
"content": "=Contract Analytics Dashboard\\n\\nTotal Contracts: {{ $json.totalContracts }}\\nTotal Value: ${{ $json.totalValue.toLocaleString() }}\\nHigh Risk: {{ $json.highRisk }}\\nExpiring Soon: {{ $json.expiringSoon }}\\n\\nView full dashboard: https://analytics.company.com/contracts"
},
"typeVersion": 1
}
],
"connections": {
"is-new-contract": {
"main": [
[
{
"node": "extract-contract",
"type": "main",
"index": 0
}
],
[]
]
},
"check-duplicate": {
"main": [
[
{
"node": "is-new-contract",
"type": "main",
"index": 0
}
]
]
},
"salesforce-check": {
"main": [
[
{
"node": "merge-sources",
"type": "main",
"index": 0
}
]
]
},
"schedule-trigger": {
"main": [
[
{
"node": "salesforce-check",
"type": "main",
"index": 0
}
]
]
},
"daily-alerts": {
"main": [
[
{
"node": "get-alerts",
"type": "main",
"index": 0
}
]
]
},
"get-alerts": {
"main": [
[
{
"node": "send-daily-summary",
"type": "main",
"index": 0
}
]
]
},
"needs-legal": {
"main": [
[
{
"node": "notify-legal",
"type": "main",
"index": 0
}
],
[]
]
},
"drive-trigger": {
"main": [
[
{
"node": "merge-sources",
"type": "main",
"index": 0
}
]
]
},
"get-template": {
"main": [
[
{
"node": "analyze-score",
"type": "main",
"index": 0
}
]
]
},
"merge-sources": {
"main": [
[
{
"node": "check-duplicate",
"type": "main",
"index": 0
}
]
]
},
"email-trigger": {
"main": [
[
{
"node": "merge-sources",
"type": "main",
"index": 0
}
]
]
},
"analyze-score": {
"main": [
[
{
"node": "save-contract",
"type": "main",
"index": 0
}
]
]
},
"risk-analysis": {
"main": [
[
{
"node": "analyze-score",
"type": "main",
"index": 0
}
]
]
},
"save-contract": {
"main": [
[
{
"node": "needs-legal",
"type": "main",
"index": 0
},
{
"node": "update-salesforce",
"type": "main",
"index": 0
}
]
]
},
"extract-contract": {
"main": [
[
{
"node": "risk-analysis",
"type": "main",
"index": 0
},
{
"node": "get-template",
"type": "main",
"index": 0
}
]
]
}
}
}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, Résumé IA
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.
Workflows recommandés
PDF Vector
@pdfvectorA fully featured PDF APIs for developers - Parse any PDF or Word document, extract structured data, and access millions of academic papers - all through simple APIs.
Partager ce workflow