{
  "name": "Student Progression Check",
  "nodes": [
    {
      "parameters": {
        "path": "assessment/progression-check",
        "httpMethod": "POST",
        "responseMode": "onReceived",
        "options": {}
      },
      "id": "0f3e6e8a-webhook-1",
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "{{$env.SJMS_API_URL}}/api/students/{{ $json.studentId }}/results",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SJMS_API_KEY }}"
            }
          ]
        },
        "options": {},
        "headerParametersJson": "{\"X-N8N-API-KEY\": \"={{$env.N8N_API_KEY}}\"}"
      },
      "id": "1a2b3c4d-http-1",
      "name": "Fetch Student Results",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        450,
        300
      ],
      "connections": {
        "0f3e6e8a-webhook-1": [
          [
            {
              "node": "1a2b3c4d-http-1",
              "type": "main",
              "index": 0
            }
          ]
        ]
      }
    },
    {
      "parameters": {
        "jsCode": "// Apply progression rules\nconst results = $json.body;\nconst totalCredits = results.modules.reduce((sum, m) => sum + (m.passed ? m.credits : 0), 0);\nconst avgMark = results.modules.reduce((sum, m) => sum + m.mark, 0) / results.modules.length;\n\nlet progressionDecision = 'PROGRESS';\nlet condonementEligible = false;\n\n// Check 120 credit minimum for UG\nif (results.level === 'UG' && totalCredits < 120) {\n  progressionDecision = 'REPEAT_YEAR';\n}\n\n// Check condonement eligibility (35-39 mark, overall avg >= 40)\nconst failedModules = results.modules.filter(m => m.mark < 40);\nconst condoneableCount = failedModules.filter(m => m.mark >= 35 && m.mark < 40).length;\nconst condoneableCredits = failedModules.filter(m => m.mark >= 35 && m.mark < 40).reduce((sum, m) => sum + m.credits, 0);\n\nif (condoneableCount > 0 && avgMark >= 40 && condoneableCredits <= 30) {\n  condonementEligible = true;\n  if (progressionDecision !== 'REPEAT_YEAR') {\n    progressionDecision = 'PROGRESS_CONDONED';\n  }\n}\n\nreturn {\n  studentId: results.studentId,\n  progressionDecision,\n  condonementEligible,\n  totalCredits,\n  avgMark: Math.round(avgMark * 100) / 100,\n  failedModules: failedModules.length,\n  condoneableModules: condoneableCount\n};"
      },
      "id": "2b3c4d5e-function-1",
      "name": "Apply Progression Rules",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        650,
        300
      ],
      "connections": {
        "1a2b3c4d-http-1": [
          [
            {
              "node": "2b3c4d5e-function-1",
              "type": "main",
              "index": 0
            }
          ]
        ]
      }
    },
    {
      "parameters": {
        "method": "PATCH",
        "url": "{{$env.SJMS_API_URL}}/api/students/{{ $json.studentId }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SJMS_API_KEY }}"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "progressionStatus",
              "value": "={{ $json.progressionDecision }}"
            },
            {
              "name": "progressionDate",
              "value": "={{ new Date().toISOString() }}"
            }
          ]
        },
        "options": {},
        "headerParametersJson": "{\"X-N8N-API-KEY\": \"={{$env.N8N_API_KEY}}\"}"
      },
      "id": "3c4d5e6f-http-2",
      "name": "Update Student Record",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        850,
        300
      ],
      "connections": {
        "2b3c4d5e-function-1": [
          [
            {
              "node": "3c4d5e6f-http-2",
              "type": "main",
              "index": 0
            }
          ]
        ]
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "{{$env.SJMS_API_URL}}/api/notifications/send",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SJMS_API_KEY }}"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "recipientId",
              "value": "={{ $json.studentId }}"
            },
            {
              "name": "type",
              "value": "PROGRESSION_DECISION"
            },
            {
              "name": "progressionStatus",
              "value": "={{ $json.progressionDecision }}"
            }
          ]
        },
        "options": {},
        "headerParametersJson": "{\"X-N8N-API-KEY\": \"={{$env.N8N_API_KEY}}\"}"
      },
      "id": "4d5e6f70-http-3",
      "name": "Notify Student",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1050,
        200
      ],
      "connections": {
        "3c4d5e6f-http-2": [
          [
            {
              "node": "4d5e6f70-http-3",
              "type": "main",
              "index": 0
            }
          ]
        ]
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "{{$env.SJMS_API_URL}}/api/notifications/send",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SJMS_API_KEY }}"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "recipientId",
              "value": "={{ $json.personalTutorId }}"
            },
            {
              "name": "type",
              "value": "PROGRESSION_NOTIFICATION"
            },
            {
              "name": "studentId",
              "value": "={{ $json.studentId }}"
            },
            {
              "name": "progressionStatus",
              "value": "={{ $json.progressionDecision }}"
            }
          ]
        },
        "options": {},
        "headerParametersJson": "{\"X-N8N-API-KEY\": \"={{$env.N8N_API_KEY}}\"}"
      },
      "id": "5e6f7081-http-4",
      "name": "Notify Personal Tutor",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1050,
        400
      ],
      "connections": {
        "3c4d5e6f-http-2": [
          [
            {
              "node": "5e6f7081-http-4",
              "type": "main",
              "index": 0
            }
          ]
        ]
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "{{$env.SJMS_API_URL}}/api/logs/errors",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SJMS_API_KEY }}"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "workflow",
              "value": "progression-check"
            },
            {
              "name": "error",
              "value": "={{ $json.errorMessage }}"
            },
            {
              "name": "timestamp",
              "value": "={{ new Date().toISOString() }}"
            }
          ]
        },
        "options": {},
        "headerParametersJson": "{\"X-N8N-API-KEY\": \"={{$env.N8N_API_KEY}}\"}"
      },
      "id": "7071829a-http-5",
      "name": "Log Error",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        450,
        500
      ],
      "connections": {
        "6f708192-errorTrigger-1": [
          [
            {
              "node": "7071829a-http-5",
              "type": "main",
              "index": 0
            }
          ]
        ]
      }
    }
  ],
  "connections": {
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Fetch Student Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Student Results": {
      "main": [
        [
          {
            "node": "Apply Progression Rules",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Apply Progression Rules": {
      "main": [
        [
          {
            "node": "Update Student Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Student Record": {
      "main": [
        [
          {
            "node": "Notify Student",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Student": {
      "main": [
        [
          {
            "node": "Notify Personal Tutor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Personal Tutor": {
      "main": [
        [
          {
            "node": "Log Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveExecutionProgress": true,
    "retry": {
      "enabled": true,
      "maxTries": 3,
      "waitBetweenRetries": 1000
    },
    "errorWorkflow": "global-error-workflow"
  }
}