Files
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
3.8 KiB
JSON

{"repo": "boubouw/saas-n8n", "files": {"backend/src/controllers/aiController.js": {"ddf3bc0019b4203838a8212ae38a1c5f3eed77ec": {"t": 1786068264.4901175, "n": 3494, "h": "4476b1fccbf1a34f", "c": "import axios from 'axios';\n\nconst DEEPSEEK_API_KEY = process.env.DEEPSEEK_API_KEY;\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\n\nexport const createWorkflow = async (req, res) => {\n try {\n const { prompt } = req.body;\n const userId = req.user.id;\n\n if (!prompt) {\n return res.status(400).json({\n success: false,\n message: 'Prompt is required'\n });\n }\n\n if (!DEEPSEEK_API_KEY) {\n return res.status(500).json({\n success: false,\n message: 'DeepSeek API key not configured'\n });\n }\n\n // System prompt for N8N workflow generation\n const systemPrompt = `You are an expert N8N workflow automation assistant. Your task is to create valid N8N workflow JSON based on user requests.\n\nIMPORTANT RULES:\n1. Always return valid N8N workflow JSON format\n2. Include proper node connections\n3. Use realistic node types (webhook, http, email, etc.)\n4. Add proper coordinates for visual layout\n5. Include credentials placeholders\n6. Return ONLY the workflow JSON and a brief description\n\nResponse format:\n{\n \"description\": \"Brief description of what this workflow does\",\n \"workflow\": {\n \"name\": \"Workflow name\",\n \"nodes\": [...],\n \"connections\": {...},\n \"settings\": {\n \"executionOrder\": \"v1\"\n }\n }\n}\n\nExample N8N node structure:\n{\n \"parameters\": {},\n \"name\": \"Webhook\",\n \"type\": \"n8n-nodes-base.webhook\",\n \"typeVersion\": 1,\n \"position\": [250, 300],\n \"webhookId\": \"unique-id\"\n}`;\n\n // Call DeepSeek API\n const response = await axios.post(\n DEEPSEEK_API_URL,\n {\n model: 'deepseek-chat',\n messages: [\n {\n role: 'system',\n content: systemPrompt\n },\n {\n role: 'user',\n content: prompt\n }\n ],\n temperature: 0.7,\n max_tokens: 4000\n },\n {\n headers: {\n 'Authorization': `Bearer ${DEEPSEEK_API_KEY}`,\n 'Content-Type': 'application/json'\n }\n }\n );\n\n const aiResponse = response.data.choices[0].message.content;\n \n // Parse the AI response\n let workflowData;\n try {\n // Extract JSON from markdown code blocks if present\n const jsonMatch = aiResponse.match(/```(?:json)?\\s*(\\{[\\s\\S]*\\})\\s*```/) || \n aiResponse.match(/(\\{[\\s\\S]*\\})/);\n \n if (jsonMatch) {\n workflowData = JSON.parse(jsonMatch[1]);\n } else {\n workflowData = JSON.parse(aiResponse);\n }\n } catch (parseError) {\n console.error('Failed to parse AI response:', parseError);\n return res.status(500).json({\n success: false,\n message: 'Failed to parse workflow from AI response',\n rawResponse: aiResponse\n });\n }\n\n // Validate workflow structure\n if (!workflowData.workflow || !workflowData.workflow.nodes) {\n return res.status(500).json({\n success: false,\n message: 'Invalid workflow structure from AI'\n });\n }\n\n res.json({\n success: true,\n data: {\n description: workflowData.description || 'Workflow créé par IA',\n workflow: workflowData.workflow\n }\n });\n\n } catch (error) {\n console.error('Error creating workflow with AI:', error.response?.data || error.message);\n res.status(500).json({\n success: false,\n message: 'Error generating workflow',\n error: error.response?.data || error.message\n });\n }\n};\n\nexport default {\n createWorkflow\n};\n"}}}}