{
  "info": {
    "name": "Dynamic Audit Report (Form 04-2a)",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": "Run the folders in order. Set the variables first (base_url, emails, password, row_id, standard_id)."
  },
  "item": [
    {
      "name": "0. Login",
      "item": [
        {
          "name": "Login as AUDITOR (lead auditor of the audit)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/auth/login",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "auth",
                "login"
              ]
            },
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"{{auditor_email}}\",\n  \"password\": \"{{password}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "pm.test('login ok', () => pm.response.to.have.status(201).or.status(200));",
                  "pm.collectionVariables.set('auditor_token', j.access_token);",
                  "console.log('user id', j.user.id, 'scheme', j.user.primary_scheme);"
                ]
              }
            }
          ]
        },
        {
          "name": "Login as SCHEME approver",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/auth/login",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "auth",
                "login"
              ]
            },
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"{{scheme_email}}\",\n  \"password\": \"{{password}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "pm.test('login ok', () => pm.response.to.have.status(201).or.status(200));",
                  "pm.collectionVariables.set('scheme_token', j.access_token);",
                  "console.log('user id', j.user.id, 'scheme', j.user.primary_scheme);"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "1. One-time setup",
      "item": [
        {
          "name": "Seed ISO 9001 clause library (scheme)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{scheme_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/clause-library/seed/iso9001",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "clause-library",
                "seed",
                "iso9001"
              ]
            },
            "description": "Run once per standard. Returns {inserted, skipped}. Safe to run again.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"standard_id\": \"{{standard_id}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('seeded or already there', () => pm.response.to.have.status(201));",
                  "console.log(pm.response.json());"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "2. Create the report",
      "item": [
        {
          "name": "Audit context (stage guess + booked standards)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/context/{{row_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "context",
                "{{row_id}}"
              ]
            },
            "description": ""
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "pm.test('stage guessed', () => pm.expect(j.suggested_stage_type).to.be.a('string'));",
                  "console.log('stage:', j.suggested_stage_type, 'standards:', j.standards.map(s => s.id + ' ' + s.name).join(', '));"
                ]
              }
            }
          ]
        },
        {
          "name": "Create report from the audit row",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports"
              ]
            },
            "description": "Pulls company, certificate, team, date and attendance from the CRM. Calling it again returns the same report.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"audit_schedule_row_id\": \"{{row_id}}\",\n  \"standard_id\": \"{{standard_id}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "pm.test('created', () => pm.expect(j.report.id).to.be.a('number'));",
                  "pm.collectionVariables.set('report_id', j.report.id);",
                  "console.log(j.report.report_no, j.report.stage_label, 'clauses:', j.clauses.length);"
                ]
              }
            }
          ]
        },
        {
          "name": "Open editor model (everything the screen needs)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}"
              ]
            },
            "description": ""
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "pm.collectionVariables.set('clause_id_1', j.clauses[0].id);",
                  "pm.collectionVariables.set('clause_id_nc', j.clauses[2].id);",
                  "// body for the 'save all clauses' request: every row = C with a short evidence line",
                  "const items = j.clauses.map(c => ({id: c.id, status: 'C', evidence_text: c.evidence_text || 'Procedure and records reviewed; found conforming.'}));",
                  "pm.collectionVariables.set('clauses_json', JSON.stringify(items));",
                  "console.log('prefilled fields', j.fields);"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "3. Auditor fills the report",
      "item": [
        {
          "name": "Header: employees, man-days, conclusion, ticks",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/header",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "header"
              ]
            },
            "description": "conclusion is used by Stage 2 / Surveillance / Recert; recommendation by Stage 1. Send both, the report uses the one that applies.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"fields\": {\n    \"employees\": \"16\",\n    \"multisite\": \"no\",\n    \"man_days\": \"2\",\n    \"technical_expert\": \"N/A\"\n  },\n  \"conclusion\": \"complies\",\n  \"recommendation\": \"proceed\",\n  \"next_audit_date\": \"2026-11-20\",\n  \"extras\": {\n    \"declarations\": [\n      \"d1\",\n      \"d2\",\n      \"d3\"\n    ],\n    \"attachments\": [\n      \"a1\"\n    ],\n    \"mark_use\": \"m1\",\n    \"improvement\": \"none\",\n    \"change_detail\": {\n      \"man_days_adequate\": \"yes\",\n      \"employee_change\": {\n        \"value\": \"none\"\n      },\n      \"scope_change\": {\n        \"value\": \"none\"\n      }\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('saved', () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Save ALL clause rows (status + evidence)",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/clauses",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "clauses"
              ]
            },
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"items\": {{clauses_json}}\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('saved', () => pm.response.to.have.status(200));",
                  "console.log(pm.response.json());"
                ]
              }
            }
          ]
        },
        {
          "name": "Save ONE clause row as NC",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/clauses/{{clause_id_nc}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "clauses",
                "{{clause_id_nc}}"
              ]
            },
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"NC\",\n  \"evidence_text\": \"Quality policy is not signed by top management.\",\n  \"docs_reviewed\": [\n    \"Quality Manual.pdf\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('saved', () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Raise NC from that clause (creates the NC record)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/clauses/{{clause_id_nc}}/raise-nc",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "clauses",
                "{{clause_id_nc}}",
                "raise-nc"
              ]
            },
            "description": "Uses the existing NC module. Second call on the same row returns 409.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"nc_type\": \"Minor\",\n  \"corrective_action\": \"Sign and issue the policy.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "pm.test('NC created', () => pm.expect(j.nc_id).to.exist);",
                  "console.log('nc_id', j.nc_id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Text section: brief about the organization",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/sections/org_brief",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "sections",
                "org_brief"
              ]
            },
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"body\": \"The organization provides logistics and warehousing services from its head office.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('saved', () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Attendance sheet",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/attendance",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "attendance"
              ]
            },
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"attendees\": [\n    {\n      \"name\": \"Usha\",\n      \"designation\": \"Manager\"\n    },\n    {\n      \"name\": \"Rahul\",\n      \"designation\": \"QA Officer\"\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('saved', () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Refresh CRM data (keeps auditor edits)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/refresh",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "refresh"
              ]
            },
            "description": ""
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "console.log(pm.response.json());"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "4. See the report",
      "item": [
        {
          "name": "HTML preview (open in browser tab or Postman Preview)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/preview",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "preview"
              ]
            }
          },
          "event": []
        },
        {
          "name": "PDF (draft until approved) - use Send and Download",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/pdf",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "pdf"
              ]
            }
          },
          "event": []
        }
      ]
    },
    {
      "name": "5. Review and approval",
      "item": [
        {
          "name": "Submit for review (auditor)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/submit",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "submit"
              ]
            },
            "description": "400 with a 'problems' list if a clause has no status, an NC/OFI has no evidence, or the conclusion/recommendation is missing."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('submitted', () => pm.response.to.have.status(201));",
                  "console.log(pm.response.json());"
                ]
              }
            }
          ]
        },
        {
          "name": "Return to auditor (scheme)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{scheme_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/return",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "return"
              ]
            },
            "description": "Optional. Status goes to returned; the auditor edits and submits again.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reason\": \"Please add the man-days.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "console.log(pm.response.json());"
                ]
              }
            }
          ]
        },
        {
          "name": "APPROVE (scheme) - freezes data, makes the final PDF",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{scheme_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/approve",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "approve"
              ]
            },
            "description": "Writes the PDF with the existing report storage, sets stg1_audit_report (Stage 1) or stg2_audit_report (all others) on the audit row and marks it QAQC approved."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "pm.test('approved', () => pm.expect(j.status).to.eql('approved'));",
                  "console.log('stored at', j.pdf_path, 'audit column', j.audit_row_column);"
                ]
              }
            }
          ]
        },
        {
          "name": "Download FINAL PDF (no DRAFT watermark)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/pdf",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "pdf"
              ]
            }
          },
          "event": []
        },
        {
          "name": "Tracker view: reports of this audit",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{auditor_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/by-audit/{{row_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "by-audit",
                "{{row_id}}"
              ]
            },
            "description": ""
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "console.log(pm.response.json());"
                ]
              }
            }
          ]
        },
        {
          "name": "List reports",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{scheme_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports?status=approved",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports?status=approved"
              ]
            },
            "description": ""
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "console.log(pm.response.json().total);"
                ]
              }
            }
          ]
        },
        {
          "name": "Reopen an approved report (scheme) - version + 1",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{scheme_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/audit-reports/{{report_id}}/reopen",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "audit-reports",
                "{{report_id}}",
                "reopen"
              ]
            },
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reason\": \"Typo in scope\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "console.log(pm.response.json());"
                ]
              }
            }
          ]
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "base_url",
      "value": "http://localhost:3008"
    },
    {
      "key": "auditor_email",
      "value": "auditor@qrs.ae"
    },
    {
      "key": "scheme_email",
      "value": "coordinator3@qrs.ae"
    },
    {
      "key": "password",
      "value": ""
    },
    {
      "key": "row_id",
      "value": "545"
    },
    {
      "key": "standard_id",
      "value": "4"
    },
    {
      "key": "report_id",
      "value": ""
    },
    {
      "key": "clause_id_1",
      "value": ""
    },
    {
      "key": "clause_id_nc",
      "value": ""
    },
    {
      "key": "clauses_json",
      "value": "[]"
    },
    {
      "key": "auditor_token",
      "value": ""
    },
    {
      "key": "scheme_token",
      "value": ""
    }
  ]
}