Files
hamed de1a78a235 feat: Implement SMS sending functionality with KavehNegar and Rangineh providers
- Add SendSmsMessage class for encapsulating SMS message data.
- Create KavehNegarProvider and RanginehProvider classes implementing SmsProviderInterface for sending SMS.
- Implement SmsLogRepository and SmsTemplateRepository for managing SMS logs and templates.
- Develop SendSmsHandler for handling SMS sending messages.
- Create SmsService to manage SMS dispatching and logging.
- Add UserProfileController for managing user profiles with CRUD operations.
- Implement UserProfile entity and repository for user profile data management.
- Update symfony.lock and bootstrap.php for project dependencies and environment setup.
2026-06-09 22:00:34 +03:30

4.3 KiB
Raw Permalink Blame History

پایگاه داده — تسک ۰۲: ماژول احراز هویت

جدول: users

(از بخش ۲.۱ مستند + بررسی DB backup Drupal)

ستون نوع نام Drupal توضیح
id INT AUTO_INCREMENT PK id شناسه داخلی
uuid CHAR(36) UNIQUE NOT NULL uuid شناسه عمومی UUID
uid INT FK → users.id NOT NULL uid ارجاع به خود جدول (self-reference — در Drupal الزامی)
mobile_number VARCHAR(20) UNIQUE NOT NULL name شماره موبایل — به عنوان username استفاده می‌شود
password VARCHAR(255) NOT NULL pass رمز عبور هش‌شده با bcrypt
realname VARCHAR(255) NULL field_realname نام و نام‌خانوادگی کامل (نه first_name/last_name!)
picture VARCHAR(500) NULL user_picture آدرس تصویر پروفایل
email VARCHAR(180) UNIQUE NULL mail ایمیل (اختیاری)
status TINYINT(1) DEFAULT 1 status ۱=فعال، ۰=غیرفعال
roles JSON NOT NULL نقش‌ها — مثال: {"0":"authenticated","2":"doctor"}
created_at INT NOT NULL created Unix timestamp — زمان ایجاد
updated_at INT NOT NULL changed Unix timestamp — آخرین ویرایش

⚠ مهم:

  • Drupal از realname (یک فیلد) استفاده می‌کند، نه first_name + last_name!
  • timestamp‌ها نوع INT هستند (Unix timestamp)، نه DATETIME
  • status نوع TINYINT است (نه ENUM)
  • uid self-reference است — در Drupal هر user به خودش اشاره می‌کند

ایندکس‌ها

CREATE UNIQUE INDEX idx_users_uuid ON users(uuid);
CREATE UNIQUE INDEX idx_users_mobile ON users(mobile_number);
CREATE UNIQUE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_status ON users(status);

ذخیره‌سازی OTP در Redis (نه پایگاه داده)

کلید:  otp:{uuid}       ← UUID از /api/v1/user/send-code برگردانده می‌شود (نه mobile!)
مقدار: {"code": "12345", "attempts": 0}
TTL:   1200 ثانیه (20 دقیقه)

جریان OTP (MobileGrant)

1. POST /api/v1/user/send-code   → {mobile, captcha_token}
   → UUID تولید + کد OTP ذخیره در Redis با کلید otp:{uuid}
   → UUID برگردانده می‌شود

2. POST /api/v1/user/verify-code → {mobile, captcha_token}
   → کد از Redis با کلید otp:{uuid} تأیید می‌شود

3. POST /oauth/token             → grant_type=mobile (MobileGrant)
   → JWT token صادر می‌شود

4. GET  /oauth/userinfo          → Bearer token
   → اطلاعات کاربر + شیء clinic_pro برگردانده می‌شود

نمونه پاسخ GET /oauth/userinfo (واقعی از Drupal)

{
  "email": null,
  "email_verified": true,
  "username": "09120671710",
  "id": "22",
  "uuid": "d200f5c5-d717-4526-b263-d3bb7d0228d6",
  "created": "1762262151",
  "changed": "1762262267",
  "status": "1",
  "roles": {
    "0": "authenticated",
    "2": "doctor"
  },
  "realName": "single doctor",
  "picture": [],
  "clinic_pro": {
    "base_role": "doctor",
    "db_uuid": "61be915b-595a-42e5-bca5-f80d22f4f14a",
    "db_key": "22bea8c1dc64d9b0c744810722519efe7290276ecd82d9bc650482aa4539bf0d",
    "my_doctors_uuid": {
      "uuid": "61be915b-595a-42e5-bca5-f80d22f4f14a",
      "id": "29",
      "name": "single doctor"
    }
  }
}

نکات /oauth/userinfo:

  • realName با حرف بزرگ N (camelCase)
  • roles یک object است، نه array: {"0":"authenticated","2":"doctor"}
  • clinic_pro.base_role → نقش اصلی: doctor, clinic, doctor_s_secretary
  • clinic_pro.db_uuid → UUID موجودیت doctor/clinic در جدول clinic_pro
  • فقط نقش‌های doctor, clinic, doctor_s_secretary می‌توانند با پسورد لاگین کنند

روابط با سایر جداول

users → user_profiles (OneToOne)  : تسک ۰۳
users → doctors      (OneToOne)   : تسک ۰۵
users → clinics      (OneToOne)   : تسک ۰۶
users → appointments (OneToMany)  : تسک ۱۰
users → payments     (OneToMany)  : تسک ۱۵
users → representations (OneToOne): تسک ۱۶