Files
clinicpro/docs/tasks/task-02-authentication/database.md
T
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

104 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# پایگاه داده — تسک ۰۲: ماژول احراز هویت
## جدول: 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 به خودش اشاره می‌کند
## ایندکس‌ها
```sql
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)
```json
{
"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): تسک ۱۶
```