{
  "name": "Quantra - Weekly Reports Generator",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtDay": 1,
              "triggerAtHour": 7,
              "triggerAtMinute": 0
            }
          ]
        }
      },
      "id": "weekly-trigger",
      "name": "Every Monday at 7 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "// Calculate date range for last week\nconst now = new Date();\nconst lastMonday = new Date(now);\nlastMonday.setDate(now.getDate() - 7);\nlastMonday.setHours(0, 0, 0, 0);\n\nconst lastSunday = new Date(lastMonday);\nlastSunday.setDate(lastMonday.getDate() + 6);\nlastSunday.setHours(23, 59, 59, 999);\n\nreturn [{\n  json: {\n    start_date: lastMonday.toISOString().split('T')[0],\n    end_date: lastSunday.toISOString().split('T')[0],\n    start_datetime: lastMonday.toISOString(),\n    end_datetime: lastSunday.toISOString()\n  }\n}];"
      },
      "id": "calc-date-range",
      "name": "Calculate Date Range",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        220,
        0
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/time_entries",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            }
          ]
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "clock_in",
              "value": "=gte.{{ $json.start_datetime }}"
            },
            {
              "name": "clock_in",
              "value": "=lt.{{ $json.end_datetime }}"
            },
            {
              "name": "select",
              "value": "id,employee_id,clock_in,clock_out,regular_minutes,overtime_minutes,total_minutes,status"
            }
          ]
        }
      },
      "id": "get-time-entries",
      "name": "Get Week's Time Entries",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        440,
        -200
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/expense_reports",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            }
          ]
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "submitted_at",
              "value": "=gte.{{ $('Calculate Date Range').first().json.start_datetime }}"
            },
            {
              "name": "submitted_at",
              "value": "=lt.{{ $('Calculate Date Range').first().json.end_datetime }}"
            },
            {
              "name": "select",
              "value": "id,employee_id,amount,category,status"
            }
          ]
        }
      },
      "id": "get-expenses",
      "name": "Get Week's Expenses",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        440,
        0
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/time_off_requests",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            }
          ]
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "created_at",
              "value": "=gte.{{ $('Calculate Date Range').first().json.start_datetime }}"
            },
            {
              "name": "created_at",
              "value": "=lt.{{ $('Calculate Date Range').first().json.end_datetime }}"
            },
            {
              "name": "select",
              "value": "id,employee_id,request_type,status,hours_requested"
            }
          ]
        }
      },
      "id": "get-time-off",
      "name": "Get Week's Time Off",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        440,
        200
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/tasks",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            }
          ]
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "created_at",
              "value": "=gte.{{ $('Calculate Date Range').first().json.start_datetime }}"
            },
            {
              "name": "created_at",
              "value": "=lt.{{ $('Calculate Date Range').first().json.end_datetime }}"
            },
            {
              "name": "select",
              "value": "id,status,priority"
            }
          ]
        }
      },
      "id": "get-tasks",
      "name": "Get Week's Tasks",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        440,
        400
      ]
    },
    {
      "parameters": {
        "jsCode": "// Compile weekly report\nconst dateRange = $('Calculate Date Range').first().json;\nconst timeEntries = $('Get Week\\'s Time Entries').first().json || [];\nconst expenses = $('Get Week\\'s Expenses').first().json || [];\nconst timeOff = $('Get Week\\'s Time Off').first().json || [];\nconst tasks = $('Get Week\\'s Tasks').first().json || [];\n\n// Time tracking stats (convert minutes to hours)\nconst totalHours = timeEntries.reduce((sum, e) => sum + ((e.regular_minutes || 0) + (e.overtime_minutes || 0)) / 60, 0);\nconst overtimeHours = timeEntries.reduce((sum, e) => sum + (e.overtime_minutes || 0) / 60, 0);\nconst uniqueEmployeesWorked = [...new Set(timeEntries.map(e => e.employee_id))].length;\n\n// Expense stats\nconst totalExpenses = expenses.reduce((sum, e) => sum + (e.amount || 0), 0);\nconst approvedExpenses = expenses.filter(e => e.status === 'approved').reduce((sum, e) => sum + (e.amount || 0), 0);\nconst pendingExpenses = expenses.filter(e => e.status === 'pending').reduce((sum, e) => sum + (e.amount || 0), 0);\n\n// Time off stats\nconst totalTimeOffRequests = timeOff.length;\nconst approvedTimeOff = timeOff.filter(t => t.status === 'approved').length;\nconst pendingTimeOff = timeOff.filter(t => t.status === 'pending').length;\n\n// Task stats\nconst totalTasks = tasks.length;\nconst completedTasks = tasks.filter(t => t.status === 'completed').length;\nconst inProgressTasks = tasks.filter(t => t.status === 'in_progress').length;\n\nconst report = {\n  report_type: 'weekly_summary',\n  period: {\n    start_date: dateRange.start_date,\n    end_date: dateRange.end_date\n  },\n  time_tracking: {\n    total_hours: Math.round(totalHours * 100) / 100,\n    overtime_hours: Math.round(overtimeHours * 100) / 100,\n    employees_worked: uniqueEmployeesWorked,\n    entries_count: timeEntries.length\n  },\n  expenses: {\n    total_submitted: Math.round(totalExpenses * 100) / 100,\n    total_approved: Math.round(approvedExpenses * 100) / 100,\n    pending_amount: Math.round(pendingExpenses * 100) / 100,\n    count: expenses.length\n  },\n  time_off: {\n    total_requests: totalTimeOffRequests,\n    approved: approvedTimeOff,\n    pending: pendingTimeOff\n  },\n  tasks: {\n    total: totalTasks,\n    completed: completedTasks,\n    in_progress: inProgressTasks,\n    completion_rate: totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0\n  },\n  generated_at: new Date().toISOString()\n};\n\nreturn [{ json: report }];"
      },
      "id": "compile-report",
      "name": "Compile Weekly Report",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        100
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/reports",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=representation"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"type\": \"weekly_summary\",\n  \"period_start\": \"{{ $json.period.start_date }}\",\n  \"period_end\": \"{{ $json.period.end_date }}\",\n  \"data\": {{ JSON.stringify($json) }},\n  \"generated_at\": \"{{ $json.generated_at }}\",\n  \"generated_by\": \"ai_worker\"\n}"
      },
      "id": "save-report",
      "name": "Save Report to DB",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1100,
        100
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/employees",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            }
          ]
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "role",
              "value": "=in.(admin,owner)"
            },
            {
              "name": "status",
              "value": "=eq.active"
            },
            {
              "name": "select",
              "value": "id,email,first_name"
            }
          ]
        }
      },
      "id": "get-admins",
      "name": "Get Admin Users",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1320,
        100
      ]
    },
    {
      "parameters": {
        "jsCode": "// Create notification for each admin\nconst admins = $input.first().json || [];\nconst report = $('Compile Weekly Report').first().json;\n\nconst notifications = admins.map(admin => ({\n  employee_id: admin.id,\n  title: '\ud83d\udcca Weekly Report Ready',\n  body: `Week of ${report.period.start_date}: ${report.time_tracking.total_hours}h worked, $${report.expenses.total_submitted.toFixed(2)} expenses`,\n  data: {\n    type: 'weekly_report',\n    report_id: $('Save Report to DB').first().json?.id,\n    period_start: report.period.start_date,\n    period_end: report.period.end_date\n  }\n}));\n\nreturn notifications.map(n => ({ json: n }));"
      },
      "id": "prepare-notifications",
      "name": "Prepare Admin Notifications",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1540,
        100
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $env.N8N_WEBHOOK_URL }}/webhook/push-notification",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"type\": \"weekly_report\",\n  \"employee_id\": \"{{ $json.employee_id }}\",\n  \"title\": \"{{ $json.title }}\",\n  \"body\": \"{{ $json.body }}\",\n  \"data\": {{ JSON.stringify($json.data) }}\n}"
      },
      "id": "send-notification",
      "name": "Send Admin Notification",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1760,
        100
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/quantra_actions",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"action_type\": \"report_generation\",\n  \"action_category\": \"automation\",\n  \"target_type\": \"report\",\n  \"decision\": \"completed\",\n  \"reasoning\": \"Generated weekly summary report for {{ $('Compile Weekly Report').first().json.period.start_date }} to {{ $('Compile Weekly Report').first().json.period.end_date }} - {{ $('Compile Weekly Report').first().json.time_tracking.total_hours }} hours, ${{ $('Compile Weekly Report').first().json.expenses.total_submitted }} expenses\",\n  \"confidence_score\": 100,\n  \"status\": \"completed\",\n  \"executed_at\": \"{{ new Date().toISOString() }}\"\n}"
      },
      "id": "log-activity",
      "name": "Log AI Activity",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1980,
        100
      ]
    }
  ],
  "connections": {
    "Every Monday at 7 AM": {
      "main": [
        [
          {
            "node": "Calculate Date Range",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Date Range": {
      "main": [
        [
          {
            "node": "Get Week's Time Entries",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Week's Expenses",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Week's Time Off",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Week's Tasks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Week's Time Entries": {
      "main": [
        [
          {
            "node": "Compile Weekly Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Week's Expenses": {
      "main": [
        [
          {
            "node": "Compile Weekly Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Week's Time Off": {
      "main": [
        [
          {
            "node": "Compile Weekly Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Week's Tasks": {
      "main": [
        [
          {
            "node": "Compile Weekly Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compile Weekly Report": {
      "main": [
        [
          {
            "node": "Save Report to DB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Report to DB": {
      "main": [
        [
          {
            "node": "Get Admin Users",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Admin Users": {
      "main": [
        [
          {
            "node": "Prepare Admin Notifications",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Admin Notifications": {
      "main": [
        [
          {
            "node": "Send Admin Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Admin Notification": {
      "main": [
        [
          {
            "node": "Log AI Activity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [
    {
      "name": "quantra-core"
    },
    {
      "name": "reports"
    }
  ],
  "triggerCount": 1
}