{
  "info": {
    "_postman_id": "7c13a042-8c9e-4c7b-b0e2-6d2c47402a11",
    "name": "SIPT Backend - Pelindo Security Hardening (Hotfix v1.6.5)",
    "description": "Postman Collection terdedikasi untuk pengujian QA dan UAT B2B Inbound Pelindo pada rute /pelindo/* (TASK-PELINDO-SECURITY-HARDENING). Mencakup skenario Happy Path operasional dan Negative Security Enforcement (401 Unauthorized, 413 Payload Too Large, 422 Strict & Malicious Input Validation).",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "1. Happy Path Scenarios",
      "item": [
        {
          "name": "1.1 GET /pelindo/getData - By Nomor PAB",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200 OK\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "",
                  "pm.test(\"Response code is 200 and data is array\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(200);",
                  "    pm.expect(json.data).to.be.an(\"array\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "insw-key",
                "value": "{{insw_key}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/pelindo/getData?nomor_pab=000001/PAB/TEST/2026",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "getData"
              ],
              "query": [
                {
                  "key": "nomor_pab",
                  "value": "000001/PAB/TEST/2026"
                }
              ]
            }
          }
        },
        {
          "name": "1.2 GET /pelindo/getData - By Time Range (Max 24h)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200 OK\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "",
                  "pm.test(\"Response code is 200 and data exists\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(200);",
                  "    pm.expect(json).to.have.property(\"data\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "insw-key",
                "value": "{{insw_key}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/pelindo/getData?start_time=2026-10-16 00:00:00&end_time=2026-10-16 12:00:00",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "getData"
              ],
              "query": [
                {
                  "key": "start_time",
                  "value": "2026-10-16 00:00:00"
                },
                {
                  "key": "end_time",
                  "value": "2026-10-16 12:00:00"
                }
              ]
            }
          }
        },
        {
          "name": "1.3 POST /pelindo/spmk - Batch SPMK Data",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200 OK\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "",
                  "pm.test(\"Batch results report success count\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(200);",
                  "    pm.expect(json).to.have.property(\"results\");",
                  "    pm.expect(json.results.success).to.be.at.least(1);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "insw-key",
                "value": "{{insw_key}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "[\n  {\n    \"NO_PAB\": [\"000001/PAB/TEST/2026\"],\n    \"ID_PELABUHAN\": \"IDJKT\",\n    \"TERMINAL\": \"TER3\",\n    \"NO_SPMK\": \"SPMK-12345\",\n    \"TANGGAL_TERBIT\": \"2026-10-16 10:00:00\",\n    \"VESSEL_CLOSE\": \"2026-10-17 12:00:00\"\n  }\n]"
            },
            "url": {
              "raw": "{{baseUrl}}/pelindo/spmk",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "spmk"
              ]
            }
          }
        },
        {
          "name": "1.4 POST /pelindo/gateInfo - Container Gate Event",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200 OK\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "",
                  "pm.test(\"Gate info response is valid\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(200);",
                  "    pm.expect(json).to.have.property(\"data\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "insw-key",
                "value": "{{insw_key}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"GATE_INFO\": [\n    {\n      \"NO_PAB\": [\"000001/PAB/TEST/2026\"],\n      \"REQUEST_DATE\": \"2026-10-16 13:00:00\",\n      \"GATEIN_DATE\": \"2026-10-16 13:17:00\",\n      \"GATEOUT_DATE\": \"2026-10-16 15:30:00\",\n      \"STATUS\": \"GATE_IN\",\n      \"TRUCK_NO\": \"B1234XYZ\",\n      \"NO_TRX_TOS\": \"TRX-998877\",\n      \"CONTAINER_NO\": \"TEMU1234567\",\n      \"ID_PELABUHAN\": \"IDJKT\",\n      \"TERMINAL\": \"TER3\"\n    }\n  ]\n}"
            },
            "url": {
              "raw": "{{baseUrl}}/pelindo/gateInfo",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "gateInfo"
              ]
            }
          }
        },
        {
          "name": "1.5 GET /pelindo/getDataKonsolidasi - By PAB Konsolidasi",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 200 OK\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "",
                  "pm.test(\"Data konsolidasi array returned\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(200);",
                  "    pm.expect(json.data).to.be.an(\"array\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "insw-key",
                "value": "{{insw_key}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/pelindo/getDataKonsolidasi?no_pab_konsolidasi=KON-2026-001",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "getDataKonsolidasi"
              ],
              "query": [
                {
                  "key": "no_pab_konsolidasi",
                  "value": "KON-2026-001"
                }
              ]
            }
          }
        }
      ]
    },
    {
      "name": "2. Negative & Security Enforcement Scenarios",
      "item": [
        {
          "name": "2.1 Negative - Missing / Invalid API Key (401 Unauthorized)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 401 Unauthorized\", function () {",
                  "    pm.response.to.have.status(401);",
                  "});",
                  "",
                  "pm.test(\"Error message indicates invalid or missing API Key\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(401);",
                  "    pm.expect(json.message).to.include(\"Akses ditolak\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "insw-key",
                "value": "invalid-probe-key-12345",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/pelindo/getData?nomor_pab=000001/PAB/TEST/2026",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "getData"
              ],
              "query": [
                {
                  "key": "nomor_pab",
                  "value": "000001/PAB/TEST/2026"
                }
              ]
            }
          }
        },
        {
          "name": "2.2 Negative - Payload Too Large > 500 KB (413 Payload Too Large)",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "exec": [
                  "// Generate dummy array exceeding 500 KB limit",
                  "var items = [];",
                  "for (var i = 0; i < 400; i++) {",
                  "    items.push({",
                  "        NO_PAB: [\"000001/PAB/TEST/2026/\" + i],",
                  "        ID_PELABUHAN: \"IDJKT\",",
                  "        TERMINAL: \"TER3_LONG_TERMINAL_NAME_PADDING_BUFFER_00000000000000000000000000000000\",",
                  "        NO_SPMK: \"SPMK-OVERSIZED-PADDING-DATA-\" + i + \"-\" + \"X\".repeat(1000),",
                  "        TANGGAL_TERBIT: \"2026-10-16 10:00:00\",",
                  "        VESSEL_CLOSE: \"2026-10-17 12:00:00\"",
                  "    });",
                  "}",
                  "pm.variables.set(\"oversizedPayload\", JSON.stringify(items));"
                ],
                "type": "text/javascript"
              }
            },
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 413 Payload Too Large\", function () {",
                  "    pm.response.to.have.status(413);",
                  "});",
                  "",
                  "pm.test(\"Error message specifies 500 KB limit\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(413);",
                  "    pm.expect(json.message).to.include(\"500 KB\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "insw-key",
                "value": "{{insw_key}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{{oversizedPayload}}"
            },
            "url": {
              "raw": "{{baseUrl}}/pelindo/spmk",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "spmk"
              ]
            }
          }
        },
        {
          "name": "2.3 Negative - Malicious Input URL & Data URI Injection (422 Unprocessable Entity)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 422 Unprocessable Entity\", function () {",
                  "    pm.response.to.have.status(422);",
                  "});",
                  "",
                  "pm.test(\"Validation error rejects URL or Data URI\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(422);",
                  "    var msg = JSON.stringify(json);",
                  "    pm.expect(msg).to.satisfy(function(m) {",
                  "        return m.includes(\"URL\") || m.includes(\"Data URI\") || m.includes(\"Base64\");",
                  "    });",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "insw-key",
                "value": "{{insw_key}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "[\n  {\n    \"NO_PAB\": [\"https://malicious-probe.attacker.internal/ssrf\"],\n    \"ID_PELABUHAN\": \"IDJKT\",\n    \"TERMINAL\": \"TER3\",\n    \"NO_SPMK\": \"data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==\",\n    \"TANGGAL_TERBIT\": \"2026-10-16 10:00:00\",\n    \"VESSEL_CLOSE\": \"2026-10-17 12:00:00\"\n  }\n]"
            },
            "url": {
              "raw": "{{baseUrl}}/pelindo/spmk",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "spmk"
              ]
            }
          }
        },
        {
          "name": "2.4 Negative - Strict Contract Violation Unknown Parameter (422 Unprocessable Entity)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 422 Unprocessable Entity\", function () {",
                  "    pm.response.to.have.status(422);",
                  "});",
                  "",
                  "pm.test(\"Strict validation rejects unrecognized key\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(422);",
                  "    var msg = JSON.stringify(json);",
                  "    pm.expect(msg).to.include(\"INJECTED_FIELD\");",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "insw-key",
                "value": "{{insw_key}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"GATE_INFO\": [\n    {\n      \"NO_PAB\": [\"000001/PAB/TEST/2026\"],\n      \"REQUEST_DATE\": \"2026-10-16 13:00:00\",\n      \"GATEIN_DATE\": \"2026-10-16 13:17:00\",\n      \"GATEOUT_DATE\": \"2026-10-16 15:30:00\",\n      \"STATUS\": \"GATE_IN\",\n      \"TRUCK_NO\": \"B1234XYZ\",\n      \"NO_TRX_TOS\": \"TRX-998877\",\n      \"CONTAINER_NO\": \"TEMU1234567\",\n      \"ID_PELABUHAN\": \"IDJKT\",\n      \"TERMINAL\": \"TER3\",\n      \"INJECTED_FIELD\": \"unauthorized_probe\"\n    }\n  ]\n}"
            },
            "url": {
              "raw": "{{baseUrl}}/pelindo/gateInfo",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "gateInfo"
              ]
            }
          }
        },
        {
          "name": "2.5 Negative - Time Range Exceeds 24 Hours on GET (422 Unprocessable Entity)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"Status code is 422 Unprocessable Entity\", function () {",
                  "    pm.response.to.have.status(422);",
                  "});",
                  "",
                  "pm.test(\"Error message indicates time range limitation\", function () {",
                  "    var json = pm.response.json();",
                  "    pm.expect(json.code).to.eql(422);",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "insw-key",
                "value": "{{insw_key}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/pelindo/getData?start_time=2026-10-10 00:00:00&end_time=2026-10-16 00:00:00",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "pelindo",
                "getData"
              ],
              "query": [
                {
                  "key": "start_time",
                  "value": "2026-10-10 00:00:00"
                },
                {
                  "key": "end_time",
                  "value": "2026-10-16 00:00:00"
                }
              ]
            }
          }
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://hotfix-backend.insw.go.id/v1-6-5-backend-pab",
      "type": "string"
    },
    {
      "key": "insw_key",
      "value": "MASUKKAN_KEY_DI_SINI",
      "type": "string"
    }
  ]
}
