# 📌 مستند فرآیند ورود / ثبت‌نام یکپارچه با سجام

## 🔷 سرویس احراز هویت

این فرآیند بر اساس APIهای شرکت سپرده‌گذاری مرکزی اوراق بهادار و تسویه وجوه (سجام) پیاده‌سازی شده است.

---

# 🎯 هدف

فرم ورود و ثبت‌نام یکسان است.

کاربر فقط با **کد ملی** وارد می‌شود و احراز هویت از طریق سجام انجام می‌شود.  
در صورت وجود کاربر → ورود  
در صورت عدم وجود → ثبت‌نام و سپس ورود

---

# 🧭 فلو کلی سیستم

```text
1. دریافت Access Token از سجام
2. ارسال درخواست OTP با کد ملی
3. دریافت کد پیامکی توسط کاربر
4. تایید OTP و دریافت اطلاعات هویتی
5. ایجاد یا ورود کاربر در سیستم داخلی
```

---

# 1️⃣ دریافت Access Token

### Endpoint

```
POST https://api.sejam.ir:8080/v1.1/accessToken
```

### نمونه درخواست

```bash
curl --location 'https://api.sejam.ir:8080/v1.1/accessToken' \
--header 'Content-Type: application/json-patch+json' \
--header 'Accept: application/json' \
--data-raw '{
  "username": "YOUR_USERNAME",
  "password": "YOUR_PASSWORD"
}'
```

### نمونه پاسخ

```json
{
  "accessToken": "YOUR_ACCESS_TOKEN",
  "expiresIn": 3600
}
```

🔐 مقدار `accessToken` باید در سرور ذخیره شود.

---

# 2️⃣ ارسال درخواست OTP

### Endpoint

```
POST https://api.sejam.ir:8080/v1.1/kycOtp
```

### Header

```
Authorization: Bearer {accessToken}
Content-Type: application/json-patch+json
```

### نمونه درخواست

```bash
curl --location 'https://api.sejam.ir:8080/v1.1/kycOtp' \
--header 'Content-Type: application/json-patch+json' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--data '{
  "uniqueIdentifier": "4310780008"
}'
```

📩 در صورت موفقیت، پیامک OTP به شماره ثبت‌شده در سجام ارسال می‌شود.

---

# 3️⃣ تایید OTP و دریافت اطلاعات کاربر

### Endpoint

```
GET https://api.sejam.ir:8080/v1.1/servicesWithOtp/profiles/{nationalCode}?otp={otp}
```

### نمونه درخواست

```bash
curl --location 'https://api.sejam.ir:8080/v1.1/servicesWithOtp/profiles/4310780008?otp=62207' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
```

---

# 4️⃣ نمونه پاسخ موفق

```json
{
  "data": {
    "mobile": 989122159380,
    "email": null,
    "uniqueIdentifier": "4310780008",
    "type": "IranianPrivatePerson",
    "status": "Sejami",
    "privatePerson": {
      "firstName": "مرتضی",
      "lastName": "طالبی",
      "fatherName": "عباسعلی",
      "gender": "Male",
      "seriShChar": "ا",
      "seriSh": "75",
      "serial": "143218",
      "shNumber": "4310780008",
      "birthDate": "1994-02-09T00:00:00",
      "placeOfIssue": "قزوین",
      "placeOfBirth": "قزوین",
      "signatureFile": null
    },
    "legalPerson": null,
    "addresses": [
      {
        "postalCode": "1667864711",
        "country": {
          "id": 1,
          "name": "ایران"
        },
        "province": {
          "id": 151,
          "name": "تهران"
        },
        "city": {
          "id": 2229,
          "name": "تهران"
        },
        "section": {
          "id": 3235,
          "name": "مرکزئ"
        },
        "cityPrefix": null,
        "remnantAddress": "تهران 4 -  خیابان استاد حسن بنا ",
        "alley": " کاوه غربی ",
        "plaque": " 16",
        "tel": "22949621",
        "countryPrefix": "+98",
        "mobile": "9127813986",
        "emergencyTel": "33783619",
        "emergencyTelCityPrefix": "028",
        "emergencyTelCountryPrefix": "98",
        "faxPrefix": "",
        "fax": "",
        "website": null,
        "email": "Morteza561@gmail.com"
      }
    ],
    "tradingCodes": [
      {
        "type": "StockExchange",
        "firstPart": "طالـ21178",
        "secondPart": "",
        "thirdPart": "",
        "code": "طالـ21178"
      }
    ],
    "agent": null,
    "accounts": [
      {
        "accountNumber": "3532924455",
        "type": "CurrentAccount",
        "sheba": "IR180180000000003532924455",
        "bank": {
          "id": 123105,
          "name": "بانک تجارت"
        },
        "branchCode": "000832",
        "branchName": "توانیر",
        "branchCity": {
          "id": 2229,
          "name": "تهران"
        },
        "isDefault": true,
        "modifiedDate": "2024-06-16T16:19:09"
      }
    ],
    "jobInfo": {
      "employmentDate": null,
      "companyName": null,
      "companyAddress": null,
      "companyPostalCode": null,
      "companyEmail": "",
      "companyWebSite": null,
      "companyCityPrefix": null,
      "companyPhone": null,
      "position": null,
      "companyFaxPrefix": null,
      "companyFax": null,
      "job": {
        "id": 123135,
        "title": "دانشجوی دانشگاه"
      },
      "jobDescription": null
    },
    "financialInfo": {
      "assetsValue": null,
      "inComingAverage": null,
      "sExchangeTransaction": null,
      "cExchangeTransaction": null,
      "outExchangeTransaction": null,
      "transactionLevel": 0,
      "tradingKnowledgeLevel": 0,
      "companyPurpose": null,
      "referenceRateCompany": null,
      "rateDate": null,
      "rate": null,
      "financialBrokers": []
    },
    "legalPersonShareholders": [],
    "legalPersonStakeholders": []
  },
  "meta": null,
  "error": null
}
```

---

# 5️⃣ منطق داخلی سیستم

در هر صورت (چه کاربر از قبل وجود داشته باشد و چه نداشته باشد)  
در نهایت یک رکورد کاربر با مدل زیر در سیستم نگهداری می‌شود.

## حالت اول: کاربر وجود دارد

- اطلاعات احراز هویت به‌روزرسانی می‌شود
- فیلد `isSejamVerified` برابر `true` قرار می‌گیرد
- فیلد `sejamInquiryDate` با تاریخ روز مقداردهی می‌شود
- کاربر وارد سیستم می‌شود

## حالت دوم: کاربر وجود ندارد

- کاربر جدید ساخته می‌شود
- مقدار `isSejamVerified = true`
- مقدار `sejamInquiryDate = now()`
- مقدار `isActive = true`
- سپس ورود انجام می‌شود

---

# 📦 مدل نهایی کاربر در سیستم

```ts
{
  _id: ObjectId,

  // -------------------------
  // Identity
  // -------------------------
  nationalId: "4310780008",          // uniqueIdentifier (Unique Index)
  personType: "IranianPrivatePerson",
  firstName: "مرتضی",
  lastName: "طالبی",
  fatherName: "عباسعلی",
  gender: "Male",
  birthDate: ISODate("1994-02-09"),
  "placeOfIssue": "قزوین",
  "placeOfBirth": "قزوین",
  "seriShChar": "ا",
  "seriSh": "75",
  "serial": "143218",
  "shNumber": "4310780008",

  // -------------------------
  // Contact
  // -------------------------
  mobile: "989122159380",            // موبایل تاییدشده سجام
  email: "Morteza561@gmail.com",

  // -------------------------
  // Address
  // -------------------------
  address: {
    province: "تهران",
    city: "تهران",
    postalCode: "1667864711",
    fullAddress: "تهران 4 - خیابان استاد حسن بنا - کاوه غربی - پلاک 16",
    "remnantAddress": "تهران 4 -  خیابان استاد حسن بنا ",
    "alley": " کاوه غربی ",
    "plaque": " 16",
  },

  // -------------------------
  // Banking
  // -------------------------
  bankAccount: {
    sheba: "IR180180000000003532924455",
    accountNumber: "3532924455",
    bankName: "بانک تجارت",
    bankId: 123105,
    isDefault: true,
    lastModified: ISODate("2024-06-16T16:19:09")
  },

  // -------------------------
  // Info
  // -------------------------
  isSejamVerified: true,          // آیا احراز شده؟
  sejamVerifiedAt: ISODate(),
}

```
