{
  "info": {
    "_postman_id": "hr-management-api-v1",
    "name": "HR Management API",
    "description": "Production-ready Postman Collection for ASP.NET Core HR Management Web API with Azure DevOps authentication, role mapping, and complete HR modules: Leave Requests, Approvals, Admin Broadcasts, Attendance Tracking, and Payroll Configuration.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "1. Authentication & Identity",
      "item": [
        {
          "name": "Azure DevOps PAT Login (Token Exchange)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Response has success structure and token\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.isSuccess).to.eql(true);",
                  "    pm.expect(json.result.token).to.be.a('string');",
                  "    pm.expect(json.result.user).to.be.an('object');",
                  "    pm.environment.set(\"authToken\", json.result.token);",
                  "    pm.environment.set(\"testUserId\", json.result.user.id);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"azureDevOpsUrl\": \"{{azureDevOpsUrl}}\",\n  \"personalAccessToken\": \"{{personalAccessToken}}\",\n  \"domainUsername\": \"\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/auth/ado-login",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "auth",
                "ado-login"
              ]
            }
          }
        },
        {
          "name": "Get Current Profile & Mapped Roles",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Verify user roles exist\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.result.roles).to.be.an('array');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/auth/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "auth",
                "me"
              ]
            }
          }
        },
        {
          "name": "Negative Test: Missing PAT (400 Bad Request)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 400\", function () {",
                  "    pm.response.to.have.status(400);",
                  "});",
                  "pm.test(\"isSuccess is false\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.isSuccess).to.eql(false);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"azureDevOpsUrl\": \"{{azureDevOpsUrl}}\",\n  \"personalAccessToken\": \"\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/auth/ado-login",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "auth",
                "ado-login"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "2. Leave Requests Module",
      "item": [
        {
          "name": "Submit Leave Request (Positive)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 201\", function () {",
                  "    pm.response.to.have.status(201);",
                  "});",
                  "pm.test(\"Extract leaveId dynamically\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.result.id).to.be.a('string');",
                  "    pm.expect(json.result.status).to.eql('Pending');",
                  "    pm.environment.set(\"leaveId\", json.result.id);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"startDate\": \"2026-11-10T00:00:00Z\",\n  \"endDate\": \"2026-11-12T00:00:00Z\",\n  \"type\": \"Vacation\",\n  \"reason\": \"Annual family travel holiday\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/leaves",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "leaves"
              ]
            }
          }
        },
        {
          "name": "Validation Test: Invalid Date Range (400 Bad Request)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 400\", function () {",
                  "    pm.response.to.have.status(400);",
                  "});",
                  "pm.test(\"Error message indicates date mismatch\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.isSuccess).to.eql(false);",
                  "    pm.expect(json.message).to.include(\"Start date cannot be after end date\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"startDate\": \"2026-11-20T00:00:00Z\",\n  \"endDate\": \"2026-11-15T00:00:00Z\",\n  \"type\": \"Sick\",\n  \"reason\": \"Test invalid dates\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/leaves",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "leaves"
              ]
            }
          }
        },
        {
          "name": "Validation Test: Overlapping Request (400 Bad Request)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 400 for overlapping leave\", function () {",
                  "    pm.response.to.have.status(400);",
                  "});",
                  "pm.test(\"Message indicates overlap detected\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.message).to.include(\"overlapping\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"startDate\": \"2026-11-11T00:00:00Z\",\n  \"endDate\": \"2026-11-13T00:00:00Z\",\n  \"type\": \"Vacation\",\n  \"reason\": \"Duplicate overlapping request\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/leaves",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "leaves"
              ]
            }
          }
        },
        {
          "name": "Get User Leaves (Filtered)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Returns paged list\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.result.items).to.be.an('array');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/leaves?pageNumber=1&pageSize=10",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "leaves"
              ],
              "query": [
                {
                  "key": "pageNumber",
                  "value": "1"
                },
                {
                  "key": "pageSize",
                  "value": "10"
                }
              ]
            }
          }
        },
        {
          "name": "Get Leave Balances",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Balance fields exist\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.result.vacationDaysTotal).to.be.a('number');",
                  "    pm.expect(json.result.sickDaysTotal).to.be.a('number');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/leaves/balance",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "leaves",
                "balance"
              ]
            }
          }
        },
        {
          "name": "Cancel Leave Request",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "url": {
              "raw": "{{baseUrl}}/api/leaves/{{leaveId}}/cancel",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "leaves",
                "{{leaveId}}",
                "cancel"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "3. Leave Approvals Module (Role-Based)",
      "item": [
        {
          "name": "View Pending Approvals (Approver/HR)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200 or 403 based on role\", function () {",
                  "    pm.expect([200, 403]).to.include(pm.response.code);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/approvals/pending?pageNumber=1&pageSize=10",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "approvals",
                "pending"
              ]
            }
          }
        },
        {
          "name": "Approve Leave Request",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200 or 404/403\", function () {",
                  "    pm.expect([200, 400, 403, 404]).to.include(pm.response.code);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"Approved\",\n  \"comments\": \"Approved by manager\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/approvals/{{leaveId}}/action",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "approvals",
                "{{leaveId}}",
                "action"
              ]
            }
          }
        },
        {
          "name": "Reject Leave Request (With Rejection Reason)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"Rejected\",\n  \"rejectionReason\": \"Project deadline during requested period\",\n  \"comments\": \"Please re-schedule after sprint deployment\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/approvals/{{leaveId}}/action",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "approvals",
                "{{leaveId}}",
                "action"
              ]
            }
          }
        },
        {
          "name": "View Leave Approval History",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/approvals/{{leaveId}}/history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "approvals",
                "{{leaveId}}",
                "history"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "4. Admin Broadcast Module",
      "item": [
        {
          "name": "Create Announcement (HR/Admin)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "if (pm.response.code === 201) {",
                  "    var json = pm.response.json();",
                  "    pm.environment.set(\"announcementId\", json.result.id);",
                  "}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"title\": \"Q4 All Hands & HR Policy Update\",\n  \"content\": \"Please review the updated holiday calendar and benefits enrollment for next month.\",\n  \"type\": \"info\",\n  \"priority\": \"High\",\n  \"targetAudience\": \"All\",\n  \"expiryDate\": \"2026-12-31T23:59:59Z\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/broadcasts",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "broadcasts"
              ]
            }
          }
        },
        {
          "name": "Get Active Announcements (Employee Feed)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/broadcasts/active",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "broadcasts",
                "active"
              ]
            }
          }
        },
        {
          "name": "Mark Announcement As Read",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "url": {
              "raw": "{{baseUrl}}/api/broadcasts/{{announcementId}}/read",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "broadcasts",
                "{{announcementId}}",
                "read"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "5. Attendance Module",
      "item": [
        {
          "name": "Employee Clock-In",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Clock in status 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"location\": \"DevHub Headquarters, Level 3\",\n  \"notes\": \"Regular office check-in\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/attendance/clock-in",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "attendance",
                "clock-in"
              ]
            }
          }
        },
        {
          "name": "Break Session (Take Break)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "url": {
              "raw": "{{baseUrl}}/api/attendance/break?action=break",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "attendance",
                "break"
              ],
              "query": [
                {
                  "key": "action",
                  "value": "break"
                }
              ]
            }
          }
        },
        {
          "name": "Break Session (Resume Work)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "url": {
              "raw": "{{baseUrl}}/api/attendance/break?action=resume",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "attendance",
                "break"
              ],
              "query": [
                {
                  "key": "action",
                  "value": "resume"
                }
              ]
            }
          }
        },
        {
          "name": "Get Real-Time Session Status",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/attendance/session",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "attendance",
                "session"
              ]
            }
          }
        },
        {
          "name": "Employee Clock-Out",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"location\": \"DevHub Headquarters, Level 3\",\n  \"notes\": \"Daily shift completed\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/attendance/clock-out",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "attendance",
                "clock-out"
              ]
            }
          }
        },
        {
          "name": "Get Monthly Attendance Summary",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/attendance/summary?month=2026-10",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "attendance",
                "summary"
              ],
              "query": [
                {
                  "key": "month",
                  "value": "2026-10"
                }
              ]
            }
          }
        },
        {
          "name": "Submit Attendance Regularization Request",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "if (pm.response.code === 201) {",
                  "    var json = pm.response.json();",
                  "    pm.environment.set(\"regularizationId\", json.result.id);",
                  "}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"attendanceDate\": \"2026-10-19T00:00:00Z\",\n  \"requestedClockIn\": \"2026-10-19T09:00:00Z\",\n  \"requestedClockOut\": \"2026-10-19T18:00:00Z\",\n  \"reason\": \"Biometric system offline on Monday morning\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/attendance/regularize",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "attendance",
                "regularize"
              ]
            }
          }
        },
        {
          "name": "Approve Attendance Regularization",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"Approved\",\n  \"comments\": \"Verified with security gate logs\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/attendance/regularize/{{regularizationId}}/action",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "attendance",
                "regularize",
                "{{regularizationId}}",
                "action"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "6. Payroll Configuration & Processing",
      "item": [
        {
          "name": "Get Salary Components",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/payroll/components",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "payroll",
                "components"
              ]
            }
          }
        },
        {
          "name": "Add Salary Component (Allowance/Deduction)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"code\": \"REMOTE_STIPEND\",\n  \"name\": \"Remote Work Broadband & Utility Stipend\",\n  \"type\": \"Earning\",\n  \"isTaxable\": false,\n  \"isPercentage\": false,\n  \"defaultAmount\": 150.0\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/payroll/components",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "payroll",
                "components"
              ]
            }
          }
        },
        {
          "name": "Configure Employee Salary Profile",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"userId\": \"{{testUserId}}\",\n  \"calculationType\": \"Monthly\",\n  \"baseRate\": 6500.00,\n  \"currency\": \"USD\",\n  \"standardHoursPerDay\": 8,\n  \"standardDaysPerWeek\": 5,\n  \"components\": [\n    {\n      \"salaryComponentId\": \"comp-hra\",\n      \"amountOrPercentage\": 1000.0\n    },\n    {\n      \"salaryComponentId\": \"comp-med\",\n      \"amountOrPercentage\": 250.0\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/payroll/employee",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "payroll",
                "employee"
              ]
            }
          }
        },
        {
          "name": "Create Financial Period",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "if (pm.response.code === 201) {",
                  "    var json = pm.response.json();",
                  "    pm.environment.set(\"payrollPeriodId\", json.result.id);",
                  "}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"2026-10\",\n  \"startDate\": \"2026-10-01T00:00:00Z\",\n  \"endDate\": \"2026-10-31T23:59:59Z\",\n  \"currency\": \"USD\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/payroll/periods",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "payroll",
                "periods"
              ]
            }
          }
        },
        {
          "name": "Calculate Payroll Run for Period",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "url": {
              "raw": "{{baseUrl}}/api/payroll/periods/{{payrollPeriodId}}/calculate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "payroll",
                "periods",
                "{{payrollPeriodId}}",
                "calculate"
              ]
            }
          }
        },
        {
          "name": "Get Employee Payslip",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{authToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/payroll/periods/{{payrollPeriodId}}/payslip",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "payroll",
                "periods",
                "{{payrollPeriodId}}",
                "payslip"
              ]
            }
          }
        },
        {
          "name": "Role-Based Test: Unauthorized Access Without Payroll Role (403 Forbidden)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJlbXBsb3llZS0wMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6IkVtcGxveWVlIn0.invalid",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/payroll/components",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "payroll",
                "components"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "7. Daily Reports & 7 PM EOD Reminder",
      "description": "Daily work reporting with multi-task updates, strictly enforced present-day validation (back-dating rejected with HTTP 400), 7:00 PM End-of-Day submission reminder indicator, and automatic linkage with Employee Attendance / Clock-in records.",
      "auth": {
        "type": "bearer",
        "bearer": [
          {
            "key": "token",
            "value": "{{authToken}}",
            "type": "string"
          }
        ]
      },
      "item": [
        {
          "name": "Submit / Update Daily Report (Present Day)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200 (Success)\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Submission succeeded and linked attendance\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.isSuccess).to.eql(true);",
                  "    pm.expect(json.result.totalTasks).to.eql(1);",
                  "    pm.expect(json.result.totalHoursWorked).to.eql(5);",
                  "    pm.expect(json.result.reportDate).to.be.a('string');",
                  "    if (json.result && json.result.id) {",
                  "        pm.environment.set(\"reportId\", json.result.id);",
                  "    }",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "X-Timezone-Offset",
                "value": "+05:30"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reportDate\": \"2026-10-21\",\n  \"developerName\": \"Developer Name\",\n  \"projectName\": \"Mobile Application\",\n  \"tasks\": [\n    {\n      \"azureTaskId\": 12345,\n      \"taskTitle\": \"Implement User Registration Logic\",\n      \"workItemType\": \"Task\",\n      \"moduleName\": \"User Registration\",\n      \"startDateTime\": \"2026-10-21T09:30:00+05:30\",\n      \"endDateTime\": \"2026-10-21T14:30:00+05:30\",\n      \"durationMinutes\": 300,\n      \"durationHours\": 5,\n      \"workDescription\": \"Implemented registration logic based on the isRegistered API response.\",\n      \"workStatus\": \"In Progress\",\n      \"priority\": \"High\",\n      \"originalEstimateHours\": 8,\n      \"completedWorkHours\": 5,\n      \"remainingWorkHours\": 3,\n      \"progressPercentage\": 70,\n      \"completedActivities\": [\n        \"Updated Home screen logic\",\n        \"Implemented masked mobile number display\",\n        \"Updated Search screen registration logic\"\n      ],\n      \"pendingActivities\": [\n        \"Complete subscription validation\",\n        \"Verify registered user profile functionality\"\n      ],\n      \"testingStatus\": \"In Progress\",\n      \"blockers\": [],\n      \"azureWorkItemUpdated\": true,\n      \"tomorrowPlan\": [\n        \"Complete integration testing\",\n        \"Fix identified bugs\"\n      ],\n      \"remarks\": \"Development is in progress.\"\n    }\n  ],\n  \"totalTasks\": 1,\n  \"completedTasks\": 0,\n  \"inProgressTasks\": 1,\n  \"blockedTasks\": 0,\n  \"totalHoursWorked\": 5\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/daily-reports",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "daily-reports"
              ]
            },
            "description": "Submits or updates multi-task daily report for today. Back-dates and future dates are strictly rejected."
          }
        },
        {
          "name": "Validation Test: Back-Date Rejection (Strict 400 Bad Request)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 400 (Bad Request)\", function () {",
                  "    pm.response.to.have.status(400);",
                  "});",
                  "pm.test(\"Back-dated report strictly rejected\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.isSuccess).to.eql(false);",
                  "    pm.expect(json.statusCode).to.eql(400);",
                  "    pm.expect(json.message).to.include(\"Back-dated\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "X-Timezone-Offset",
                "value": "+05:30"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reportDate\": \"2026-10-20\",\n  \"developerName\": \"Developer Name\",\n  \"projectName\": \"Mobile Application\",\n  \"tasks\": [\n    {\n      \"azureTaskId\": 12345,\n      \"taskTitle\": \"Yesterday Task\",\n      \"workItemType\": \"Task\",\n      \"moduleName\": \"User Registration\",\n      \"durationHours\": 4,\n      \"workDescription\": \"Test back-date rejection\",\n      \"workStatus\": \"Done\"\n    }\n  ],\n  \"totalTasks\": 1,\n  \"completedTasks\": 1,\n  \"inProgressTasks\": 0,\n  \"blockedTasks\": 0,\n  \"totalHoursWorked\": 4\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/daily-reports",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "daily-reports"
              ]
            },
            "description": "Tests strict back-date rejection. Returns HTTP 400 Bad Request."
          }
        },
        {
          "name": "Get 7:00 PM End-of-Day (EOD) Status & Reminder",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"7:00 PM threshold and submission status verified\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.isSuccess).to.eql(true);",
                  "    pm.expect(json.result.eodThresholdTime).to.include(\"19:00:00\");",
                  "    pm.expect(json.result).to.have.property(\"isEodReached\");",
                  "    pm.expect(json.result).to.have.property(\"indicatorMessage\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-Timezone-Offset",
                "value": "+05:30"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/daily-reports/eod-status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "daily-reports",
                "eod-status"
              ]
            },
            "description": "Checks whether 7:00 PM EOD has arrived, reminder message, and whether user has submitted today and clocked in."
          }
        },
        {
          "name": "Get Today Daily Report",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Today report retrieved\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.isSuccess).to.eql(true);",
                  "    pm.expect(json.result.tasks).to.be.an('array');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-Timezone-Offset",
                "value": "+05:30"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/daily-reports/today",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "daily-reports",
                "today"
              ]
            },
            "description": "Retrieves the authenticated developer daily report submitted for today."
          }
        },
        {
          "name": "Get Daily Report by ID",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Report details retrieved\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.isSuccess).to.eql(true);",
                  "    pm.expect(json.result.id).to.eql(pm.environment.get(\"reportId\"));",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/daily-reports/{{reportId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "daily-reports",
                "{{reportId}}"
              ]
            },
            "description": "Retrieves single daily report by ID."
          }
        },
        {
          "name": "Get Daily Reports History (Paged & Filtered)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Paged history retrieved\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.isSuccess).to.eql(true);",
                  "    pm.expect(json.result.items).to.be.an('array');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/daily-reports?pageNumber=1&pageSize=20",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "daily-reports"
              ],
              "query": [
                {
                  "key": "pageNumber",
                  "value": "1"
                },
                {
                  "key": "pageSize",
                  "value": "20"
                }
              ]
            },
            "description": "Fetches paginated list of historic daily reports."
          }
        }
      ]
    }
  ]
}