{
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "const expired = (t) => {",
          "  if (!t) return true;",
          "  try {",
          "    const p = JSON.parse(atob(t.split('.')[1].replace(/-/g,'+').replace(/_/g,'/')));",
          "    return !p.exp || (p.exp * 1000) < (Date.now() + 60000);   // refresh a minute early",
          "  } catch (e) { return true; }",
          "};",
          "",
          "const logins = [",
          "  { v: 'token',      user: pm.collectionVariables.get('userName') },",
          "  { v: 'staffToken', user: pm.collectionVariables.get('staffUserName') },",
          "  { v: 'regToken',   user: pm.collectionVariables.get('regUserName') },",
          "];",
          "",
          "const need = logins.filter(l => l.user && expired(pm.collectionVariables.get(l.v)));",
          "if (need.length) {",
          "  need.forEach(l => {",
          "    pm.sendRequest({",
          "      url: pm.collectionVariables.get('baseUrl') + '/auth/login',",
          "      method: 'POST',",
          "      header: { 'Content-Type': 'application/json' },",
          "      body: { mode: 'raw', raw: JSON.stringify({ UserName: l.user, Password: pm.collectionVariables.get('password') || 'demo' }) },",
          "    }, (err, res) => {",
          "      if (err) { console.log('auto-login failed for ' + l.user, err); return; }",
          "      const j = res.json();",
          "      if (j.result !== 'Ok') { console.log('auto-login rejected for ' + l.user, j.details); return; }",
          "      const u = j.UserMainData || {};",
          "      pm.collectionVariables.set(l.v, (j.token && j.token.data) || '');",
          "      if (l.v === 'token') {",
          "        pm.collectionVariables.set('edStudId', u.ED_STUD_ID || '');",
          "        pm.collectionVariables.set('seUserId', u.SE_USER_ID || '');",
          "        pm.collectionVariables.set('seUserAccntId', u.SE_USER_ACCNT_ID || '');",
          "        pm.collectionVariables.set('facultyId', u.AS_FACULTY_INFO_ID || '');",
          "        pm.collectionVariables.set('acadYearId', u.ED_ACAD_YEAR_ID || '');",
          "        pm.collectionVariables.set('semesterId', u.ED_CODE_SEMESTER_ID || '');",
          "      } else if (l.v === 'regToken') {",
          "        pm.collectionVariables.set('regStudId', u.ED_STUD_ID || '');",
          "      } else {",
          "        pm.collectionVariables.set('staffId', u.SA_STAFF_MEMBER_ID || u.ED_STUD_ID || '');",
          "        pm.collectionVariables.set('staffSeUserId', u.SE_USER_ID || '');",
          "      }",
          "      console.log('auto-login ok: ' + l.user);",
          "    });",
          "  });",
          "}"
        ]
      }
    }
  ],
  "info": {
    "name": "خدمات الحرم الجامعي · Services Hub",
    "description": "# خدمات الحرم الجامعي — Services Hub\n\nصفحة تجميعية لكل الخدمات (14 خدمة) مقسّمة لمجموعات، مع بحث.\n\n---\n\n**إزاي تشغّله:** شغّل `0) Login` الأول — هيملأ التوكن وكل الـ ids لوحده، وبعدها كل الريكوستات تشتغل على طول.\n\n**الحالة:** 1 شغال · 0 شغال بدون داتا · 0 ناقص",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{token}}",
        "type": "string"
      }
    ]
  },
  "item": [
    {
      "name": "0) Login (run me first)",
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "// Stores the identity + token so every other request just works.",
              "const j = pm.response.json();",
              "if (j.result === \"Ok\") {",
              "    const u = j.UserMainData;",
              "    pm.collectionVariables.set(\"token\",        j.token.data);",
              "    pm.collectionVariables.set(\"edStudId\",     u.ED_STUD_ID);",
              "    pm.collectionVariables.set(\"staffId\",      u.SA_STAFF_MEMBER_ID);",
              "    pm.collectionVariables.set(\"seUserId\",     u.SE_USER_ID);",
              "    pm.collectionVariables.set(\"seUserAccntId\",u.SE_USER_ACCNT_ID);",
              "    pm.collectionVariables.set(\"facultyId\",    u.AS_FACULTY_INFO_ID);",
              "    pm.collectionVariables.set(\"acadYearId\",   u.ED_ACAD_YEAR_ID);",
              "    pm.collectionVariables.set(\"semesterId\",   u.ED_CODE_SEMESTER_ID);",
              "    console.log(\"signed in:\", u.ED_STUD_ID, u.YEAR_DESC_EN, u.SEM_DESC_EN);",
              "}",
              "pm.test(\"login ok\", () => pm.expect(j.result).to.eql(\"Ok\"));"
            ]
          }
        }
      ],
      "request": {
        "method": "POST",
        "auth": {
          "type": "noauth"
        },
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"UserName\": \"{{userName}}\",\n  \"Password\": \"{{password}}\"\n}"
        },
        "url": {
          "raw": "{{baseUrl}}/auth/login",
          "host": [
            "{{baseUrl}}"
          ],
          "path": [
            "auth",
            "login"
          ]
        },
        "description": "يخزّن التوكن وكل الـ ids في متغيرات الكوليكشن. **شغّله الأول.**"
      }
    },
    {
      "name": "0b) Login as STAFF (for the 👨‍🏫 requests)",
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "const j = pm.response.json();",
              "pm.test('staff login ok', () => pm.expect(j.result).to.eql('Ok'));",
              "const u = j.UserMainData || {};",
              "pm.collectionVariables.set('staffToken', (j.token && j.token.data) || '');",
              "pm.collectionVariables.set('staffId', u.SA_STAFF_MEMBER_ID || u.ED_STUD_ID || '');",
              "pm.collectionVariables.set('staffSeUserId', u.SE_USER_ID || '');",
              "pm.test('is NOT a student', () => pm.expect(u.IsStudent).to.eql(false));"
            ]
          }
        }
      ],
      "request": {
        "method": "POST",
        "auth": {
          "type": "noauth"
        },
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"UserName\": \"{{staffUserName}}\",\n  \"Password\": \"{{password}}\"\n}"
        },
        "url": {
          "raw": "{{baseUrl}}/auth/login",
          "host": [
            "{{baseUrl}}"
          ],
          "path": [
            "auth",
            "login"
          ]
        },
        "description": "نفس إندبوينت الدخول بحساب دكتور. بيخزّن **staffToken** و**staffId**. الريكويستات اللي عليها 👨‍🏫 بتستخدمه."
      }
    },
    {
      "name": "🌐  GET Info/Capabilities",
      "request": {
        "method": "GET",
        "auth": {
          "type": "noauth"
        },
        "header": [],
        "url": {
          "raw": "{{baseUrl}}/Info/Capabilities",
          "host": [
            "{{baseUrl}}"
          ],
          "path": [
            "Info",
            "Capabilities"
          ]
        },
        "description": "**✅ شغال بداتا حقيقية**\n⭐ لإخفاء الخدمات غير المتاحة\n\n> **من غير توكن** — بيشتغل قبل الدخول."
      },
      "response": [
        {
          "name": "رد حقيقي — فيه داتا · 200",
          "originalRequest": {
            "method": "GET",
            "auth": {
              "type": "noauth"
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/Info/Capabilities",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "Info",
                "Capabilities"
              ]
            },
            "description": "**✅ شغال بداتا حقيقية**\n⭐ لإخفاء الخدمات غير المتاحة\n\n> **من غير توكن** — بيشتغل قبل الدخول."
          },
          "status": "OK",
          "code": 200,
          "_postman_previewlanguage": "json",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "cookie": [],
          "body": "{\n  \"client\": \"INNOVATION\",\n  \"setupMode\": false,\n  \"academic\": {\n    \"model\": \"YearBased\",\n    \"semesterResolution\": \"ByUserType\"\n  },\n  \"payments\": {\n    \"provider\": \"Fawry\",\n    \"currency\": \"EGP\"\n  },\n  \"meetings\": \"MicrosoftTeams\",\n  \"lms\": \"Moodle\",\n  \"sandbox\": [\n    \"payments\",\n    \"meetings\",\n    \"lms\",\n    \"push\"\n  ],\n  \"features\": [\n    {\n      \"key\": \"courseworkMarks\",\n      \"name\": \"Coursework marks\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"staffTeachingLoad\",\n      \"name\": \"Teaching load\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"kuStudyPlanReport\",\n      \"name\": \"Study plan — KU report\",\n      \"status\": \"Disabled\",\n      \"available\": false\n    },\n    {\n      \"key\": \"pushNotifications\",\n      \"name\": \"Push notifications\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"payments\",\n      \"name\": \"Online payments\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"qrCard\",\n      \"name\": \"Student QR card\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"qrAttendanceReports\",\n      \"name\": \"QR attendance\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"bluetoothAttendance\",\n      \"name\": \"Bluetooth attendance\",\n      \"status\": \"Disabled\",\n      \"available\": false\n    },\n    {\n      \"key\": \"perDaySchedule\",\n      \"name\": \"Per-day schedule\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"ramadanSchedule\",\n      \"name\": \"Ramadan schedule\",\n      \"status\": \"Disabled\",\n      \"available\": false\n    },\n    {\n      \"key\": \"todaySchedule\",\n      \"name\": \"Today's schedule\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"examSchedule\",\n      \"name\": \"Exam schedule\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"courseRegistration\",\n      \"name\": \"Course registration\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"surveys\",\n      \"name\": \"Surveys & course evaluation\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"staffStudentChat\",\n      \"name\": \"Staff ↔ student messaging\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"forgetPasswordByCode\",\n      \"name\": \"Forgot password by code\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"backOfficeNotifications\",\n      \"name\": \"Back-office notification hook\",\n      \"status\": \"Disabled\",\n      \"available\": false\n    },\n    {\n      \"key\": \"onlinePaymentFawry\",\n      \"name\": \"Fawry payment reference\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"onlinePaymentWallets\",\n      \"name\": \"Mobile wallets (Vodafone / Orange / Etisalat Cash)\",\n      \"status\": \"Disabled\",\n      \"available\": false\n    },\n    {\n      \"key\": \"onlinePaymentCards\",\n      \"name\": \"Card checkout\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"paymentCallbacks\",\n      \"name\": \"Gateway settlement callbacks\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"studentWallet\",\n      \"name\": \"University wallet\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"teamsMeetings\",\n      \"name\": \"Microsoft Teams meetings\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"lmsMoodle\",\n      \"name\": \"Moodle (LMS)\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"advisingAppointments\",\n      \"name\": \"Advising appointments\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"serviceRequests\",\n      \"name\": \"Requests & documents\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"withdrawalRequests\",\n      \"name\": \"Withdrawals\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"roomBooking\",\n      \"name\": \"Housing service request\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"studentActivities\",\n      \"name\": \"Activities, training & lecture notes\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"campusRequests\",\n      \"name\": \"Locker, car sticker & fee discounts\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"studentViolations\",\n      \"name\": \"Violations & penalties\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"staffOfficeHours\",\n      \"name\": \"Staff office hours\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"studentComplaints\",\n      \"name\": \"Complaints\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"studentContactEdit\",\n      \"name\": \"Student edits own contact details\",\n      \"status\": \"Active\",\n      \"available\": true\n    },\n    {\n      \"key\": \"staffGradeEntry\",\n      \"name\": \"Grade entry from the app\",\n      \"status\": \"Active\",\n      \"available\": true\n    }\n  ]\n}"
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.109.123.243.32.sslip.io"
    },
    {
      "key": "userName",
      "value": "mahmoued.eprahim.23010062"
    },
    {
      "key": "staffUserName",
      "value": "atef.dahesh"
    },
    {
      "key": "regUserName",
      "value": "mahmoued.eprahim.23010062"
    },
    {
      "key": "password",
      "value": "demo"
    },
    {
      "key": "token",
      "value": ""
    },
    {
      "key": "staffToken",
      "value": ""
    },
    {
      "key": "regToken",
      "value": ""
    },
    {
      "key": "edStudId",
      "value": ""
    },
    {
      "key": "regStudId",
      "value": ""
    },
    {
      "key": "staffId",
      "value": ""
    },
    {
      "key": "staffSeUserId",
      "value": ""
    },
    {
      "key": "seUserId",
      "value": ""
    },
    {
      "key": "seUserAccntId",
      "value": ""
    },
    {
      "key": "facultyId",
      "value": ""
    },
    {
      "key": "acadYearId",
      "value": ""
    },
    {
      "key": "semesterId",
      "value": ""
    }
  ]
}