- 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.
161 lines
7.4 KiB
Markdown
161 lines
7.4 KiB
Markdown
# پایگاه داده — تسک ۰۵: ماژول دکتر
|
||
|
||
## جدول: doctors
|
||
_(entity_type=clinic_pro, bundle=doctor — از DB backup و config تأیید شده)_
|
||
|
||
| ستون | نوع | نام Drupal | توضیح |
|
||
|------|-----|-----------|-------|
|
||
| id | INT UNSIGNED AUTO_INCREMENT PK | id | |
|
||
| uuid | CHAR(36) UNIQUE NOT NULL | uuid | |
|
||
| user_id | INT FK → users.id UNIQUE NOT NULL | uid | کاربر صاحب پروفایل |
|
||
| name | VARCHAR(255) NOT NULL | field_name | نام دکتر |
|
||
| gender | VARCHAR(10) NULL | field_gender | `woman` یا `man` |
|
||
| medical_system_code | VARCHAR(25) NULL | field_doctor_id | شماره نظام پزشکی (max 25) |
|
||
| mobile_number | VARCHAR(15) NULL | field_doctor_mobile_number | شماره موبایل دکتر (max 15) |
|
||
| activity_time | INT NULL | field_activity_time | timestamp سال شروع فعالیت |
|
||
| degree | VARCHAR(30) NULL | field_degree | مدرک (مقادیر زیر) |
|
||
| info | LONGTEXT NULL | field_info | بیوگرافی |
|
||
| image_path | VARCHAR(255) NULL | field_image | تصویر (media) |
|
||
| doctor_rate | FLOAT NULL | field_doctor_rate | امتیاز ستارهای (default: 3.5) |
|
||
| doctor_rate_percentage | FLOAT NULL | field_doctor_rate_percentage | درصد رضایت (default: 60) |
|
||
| active_doctor_appointment | TINYINT(1) DEFAULT 1 | field_active_doctor_appointmen | نوبتدهی فعال (بدون حرف 't') |
|
||
| representation_id | INT FK → representations.id NULL | field_representation | entity ref → clinic_pro |
|
||
| created_at | INT NOT NULL | created | Unix timestamp |
|
||
| updated_at | INT NOT NULL | changed | Unix timestamp |
|
||
|
||
## مقادیر field_degree (از config)
|
||
```
|
||
expert → کارشناس
|
||
general → پزشک عمومی
|
||
specialist → پزشک متخصص
|
||
subspecialistplus → پزشک فوق تخصص
|
||
```
|
||
|
||
## مقادیر field_gender (از config)
|
||
```
|
||
woman → زن
|
||
man → مرد
|
||
```
|
||
|
||
## جدول: doctor_specialties (ManyToMany pivot)
|
||
| ستون | نوع | توضیح |
|
||
|------|-----|-------|
|
||
| doctor_id | INT FK → doctors.id | |
|
||
| category_id | INT FK → categories.id | |
|
||
| PRIMARY KEY (doctor_id, category_id) | | field_specialty → cardinality=2 (حداکثر ۲ تخصص) |
|
||
|
||
## جدول: doctor_services (ManyToMany pivot)
|
||
| ستون | نوع | توضیح |
|
||
|------|-----|-------|
|
||
| doctor_id | INT FK → doctors.id | |
|
||
| category_id | INT FK → categories.id | |
|
||
| PRIMARY KEY (doctor_id, category_id) | | field_doctor_services → cardinality=8 (حداکثر ۸ سرویس) |
|
||
|
||
## جدول: doctor_states (ManyToMany pivot)
|
||
| ستون | نوع | توضیح |
|
||
|------|-----|-------|
|
||
| doctor_id | INT FK → doctors.id | |
|
||
| category_id | INT FK → categories.id | |
|
||
| PRIMARY KEY (doctor_id, category_id) | | field_state → cardinality=1 |
|
||
|
||
## جدول: doctor_cities (ManyToMany pivot)
|
||
| ستون | نوع | توضیح |
|
||
|------|-----|-------|
|
||
| doctor_id | INT FK → doctors.id | |
|
||
| category_id | INT FK → categories.id | |
|
||
| PRIMARY KEY (doctor_id, category_id) | | field_city → cardinality=1 |
|
||
|
||
## جدول: doctor_addresses
|
||
_(entity_type=clinic_pro, bundle=doctors_addresses — از DB backup)_
|
||
|
||
| ستون | نوع | نام Drupal | توضیح |
|
||
|------|-----|-----------|-------|
|
||
| id | INT UNSIGNED AUTO_INCREMENT PK | id | |
|
||
| uuid | CHAR(36) UNIQUE NOT NULL | uuid | |
|
||
| doctor_id | INT FK → doctors.id CASCADE | field_doctor | دکتر |
|
||
| name | VARCHAR(255) NULL | field_name | نام مطب/آدرس |
|
||
| address | LONGTEXT NULL | field_address | آدرس کامل |
|
||
| telephone | VARCHAR(50) NULL | field_telephone | تلفن مطب |
|
||
| latitude | FLOAT NULL | field_latitude | عرض جغرافیایی |
|
||
| longitude | FLOAT NULL | field_longitude | طول جغرافیایی |
|
||
| created_at | INT NOT NULL | created | Unix timestamp |
|
||
| updated_at | INT NOT NULL | changed | Unix timestamp |
|
||
|
||
## جدول: clinics
|
||
_(entity_type=clinic_pro, bundle=clinic — از config تأیید شده)_
|
||
|
||
| ستون | نوع | نام Drupal | توضیح |
|
||
|------|-----|-----------|-------|
|
||
| id | INT UNSIGNED AUTO_INCREMENT PK | id | |
|
||
| uuid | CHAR(36) UNIQUE NOT NULL | uuid | |
|
||
| user_id | INT FK → users.id NOT NULL | uid | مالک |
|
||
| name | VARCHAR(255) NULL | field_name | نام کلینیک |
|
||
| info | LONGTEXT NULL | field_info | توضیحات |
|
||
| address | LONGTEXT NULL | field_address | آدرس |
|
||
| telephone | VARCHAR(50) NULL | field_telephone | تلفن |
|
||
| is_24_7 | TINYINT(1) DEFAULT 0 | field_24_7 | باز ۲۴/۷ |
|
||
| working_days | VARCHAR(255) NULL | field_working_days | روزهای کاری (متن آزاد، مثال: 'شنبه تا سه شنبه ساعت ۱۲:۲۰') |
|
||
| latitude | FLOAT NULL | field_latitude | |
|
||
| longitude | FLOAT NULL | field_longitude | |
|
||
| city_id | INT FK → categories.id NULL | field_city | |
|
||
| state_id | INT FK → categories.id NULL | field_state | |
|
||
| representation_id | INT FK → representations.id NULL | field_agent | نماینده کلینیک |
|
||
| created_at | INT NOT NULL | created | |
|
||
| updated_at | INT NOT NULL | changed | |
|
||
|
||
جداول pivot مرتبط با clinic:
|
||
- `clinic_doctors` (clinic_id, doctor_id) → field_doctors (cardinality نامحدود)
|
||
- `clinic_specialties` (clinic_id, category_id) → field_clinic_specialty
|
||
- `clinic_services` (clinic_id, category_id) → field_doctor_services
|
||
- `clinic_insurances` (clinic_id, category_id) → field_insurance
|
||
|
||
## جدول: doctor_secretaries
|
||
_(entity_type=clinic_pro, bundle=doctor_secretary — از config تأیید شده)_
|
||
|
||
| ستون | نوع | نام Drupal | توضیح |
|
||
|------|-----|-----------|-------|
|
||
| id | INT UNSIGNED AUTO_INCREMENT PK | id | |
|
||
| uuid | CHAR(36) UNIQUE NOT NULL | uuid | |
|
||
| user_id | INT FK → users.id NOT NULL | uid | |
|
||
| doctor_id | INT FK → doctors.id NOT NULL | field_doctor | entity ref → clinic_pro/doctor |
|
||
| secretary_id | INT FK → users.id NOT NULL | field_secretary | entity ref → user (منشی) |
|
||
| telephone | VARCHAR(50) NULL | field_telephone | تلفن |
|
||
| permission | LONGTEXT NULL | field_permission | مجوزها (JSON) |
|
||
| active | TINYINT(1) DEFAULT 1 | field_active | فعال/غیرفعال |
|
||
| created_at | INT NOT NULL | created | |
|
||
| updated_at | INT NOT NULL | changed | |
|
||
|
||
## ایندکسها
|
||
```sql
|
||
CREATE UNIQUE INDEX idx_doctors_user ON doctors(user_id);
|
||
CREATE INDEX idx_doctors_representation ON doctors(representation_id);
|
||
CREATE INDEX idx_doctors_active ON doctors(active_doctor_appointment);
|
||
CREATE INDEX idx_doctors_rate ON doctors(doctor_rate DESC);
|
||
CREATE INDEX idx_doctor_addresses_doctor ON doctor_addresses(doctor_id);
|
||
CREATE INDEX idx_clinics_user ON clinics(user_id);
|
||
CREATE UNIQUE INDEX idx_doctor_secretaries_doctor_secretary ON doctor_secretaries(doctor_id, secretary_id);
|
||
```
|
||
|
||
## نمونه داده واقعی از DB (clinic_pro table)
|
||
```
|
||
id=18, bundle='doctor'
|
||
id=22, bundle='doctor'
|
||
id=23, bundle='clinic'
|
||
id=24, bundle='clinic'
|
||
id=27, bundle='doctor_secretary'
|
||
id=29, bundle='doctor'
|
||
id=38, bundle='doctors_addresses'
|
||
id=41, bundle='representation'
|
||
```
|
||
|
||
## روابط کامل clinic_pro entity
|
||
- `doctors` → `users` (ManyToOne, UNIQUE → OneToOne)
|
||
- `doctors` → `representations` (ManyToOne)
|
||
- `doctors` ↔ `categories` (ManyToMany: specialties, services, states, cities)
|
||
- `doctor_addresses` → `doctors` (ManyToOne, CASCADE)
|
||
- `clinics` → `users` (ManyToOne)
|
||
- `clinics` ↔ `doctors` (ManyToMany)
|
||
- `clinics` ↔ `categories` (ManyToMany)
|
||
- `doctor_secretaries` → `doctors` (ManyToOne)
|
||
- `doctor_secretaries` → `users` as secretary (ManyToOne)
|