{
  "name": "Vorlux AI | Content SEO Audit",
  "active": false,
  "nodes": [
    {
      "parameters": {
        "rule": { "interval": [{ "field": "weeks", "weeksInterval": 1 }] }
      },
      "id": "schedule-trigger",
      "name": "Weekly Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [220, 300]
    },
    {
      "parameters": {
        "url": "http://host.docker.internal:3010/api/blog/posts",
        "method": "GET",
        "qs": { "status": "published", "limit": 50 },
        "options": { "timeout": 15000 }
      },
      "id": "fetch-posts",
      "name": "Fetch Published Posts",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [460, 300]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const posts = $input.first().json.data || $input.first().json.posts || [];\n\nconst audits = posts.map(post => {\n  const issues = [];\n  let score = 100;\n  const title = post.title || '';\n  const content = post.content || post.body || '';\n  const meta = post.meta_description || post.description || '';\n\n  if (title.length < 30) { issues.push('Title too short (< 30 chars)'); score -= 15; }\n  if (title.length > 60) { issues.push('Title too long (> 60 chars)'); score -= 10; }\n  if (!meta || meta.length < 50) { issues.push('Meta description missing or too short'); score -= 20; }\n  if (meta && meta.length > 160) { issues.push('Meta description too long (> 160 chars)'); score -= 5; }\n  if (content.length < 300) { issues.push('Content too thin (< 300 chars)'); score -= 25; }\n  if (!post.featured_image && !post.thumbnail) { issues.push('No featured image'); score -= 10; }\n  if (!post.slug || post.slug.length > 75) { issues.push('Slug missing or too long'); score -= 10; }\n  const headings = (content.match(/<h[2-6]|##/g) || []).length;\n  if (headings < 2 && content.length > 500) { issues.push('Needs more headings for structure'); score -= 10; }\n\n  return { id: post.id, title, slug: post.slug, score: Math.max(0, score), issues, grade: score >= 90 ? 'A' : score >= 70 ? 'B' : score >= 50 ? 'C' : 'F' };\n});\n\nconst avgScore = Math.round(audits.reduce((s, a) => s + a.score, 0) / (audits.length || 1));\nconst needsFix = audits.filter(a => a.grade === 'F' || a.grade === 'C');\n\nreturn [{ json: { totalPosts: audits.length, avgScore, audits, needsFix: needsFix.length, generatedAt: new Date().toISOString() } }];"
      },
      "id": "audit-seo",
      "name": "Run SEO Audit",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [700, 300]
    },
    {
      "parameters": {
        "url": "http://host.docker.internal:3010/api/reports",
        "method": "POST",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ type: 'seo-audit', title: 'Weekly SEO Audit', data: $json }) }}",
        "options": { "timeout": 15000 }
      },
      "id": "save-report",
      "name": "Save Audit Report",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [960, 300]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{$env.DISCORD_CONTENT_WEBHOOK}}",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ content: '🔍 **Weekly SEO Audit**\\nPosts Audited: ' + $('Run SEO Audit').first().json.totalPosts + '\\nAvg Score: ' + $('Run SEO Audit').first().json.avgScore + '/100\\nNeeds Fix: ' + $('Run SEO Audit').first().json.needsFix + ' posts' }) }}"
      },
      "id": "discord-notify",
      "name": "Discord Notify",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [1200, 300]
    }
  ],
  "connections": {
    "Weekly Schedule": { "main": [[{ "node": "Fetch Published Posts", "type": "main", "index": 0 }]] },
    "Fetch Published Posts": { "main": [[{ "node": "Run SEO Audit", "type": "main", "index": 0 }]] },
    "Run SEO Audit": { "main": [[{ "node": "Save Audit Report", "type": "main", "index": 0 }]] },
    "Save Audit Report": { "main": [[{ "node": "Discord Notify", "type": "main", "index": 0 }]] }
  },
  "settings": { "executionOrder": "v1" }
}
