# پایگاه داده — تسک ۱۰: ماژول نوبت‌دهی ## جدول: appointments _(entity_type=appointment — از DB backup تأیید شده)_ | ستون | نوع | نام Drupal | توضیح | |------|-----|-----------|-------| | id | INT UNSIGNED AUTO_INCREMENT PK | id | | | uuid | CHAR(36) UNIQUE NOT NULL | uuid | | | patient_id | INT FK → users.id NOT NULL | uid | بیمار (owner) | | doctor_id | INT FK → doctors.id NOT NULL | field_doctor_id | entity ref → clinic_pro | | address_id | INT FK → doctor_addresses.id NULL | field_address | entity ref → clinic_pro | | representation_id | INT FK → representations.id NULL | field_representation | entity ref → clinic_pro | | start_time | INT NOT NULL | field_start_time | Unix timestamp (Asia/Tehran) | | end_time | INT NOT NULL | field_end_time | Unix timestamp | | slot | LONGTEXT NULL | field_slot | JSON (ساختار زیر) | | status | VARCHAR(40) DEFAULT 'waiting_for_payment' | field_status | وضعیت | | visited_at | INT NULL | field_visited_at | زمان ویزیت (Unix timestamp) | | info | LONGTEXT NULL | field_info | یادداشت | | created_at | INT NOT NULL | created | Unix timestamp | | updated_at | INT NOT NULL | changed | Unix timestamp | ## ساختار واقعی JSON فیلد `slot` (از DB backup) ```json { "time": "17:00", "status": "available", "start_time_timestamp": 1763472600, "end_time_timestamp": 1763473800, "duration_per_patient": 20, "location_id": 38 } ``` ## وضعیت‌های کامل (field_status) — از config ``` waiting_for_payment → پیش‌فرض — منتظر پرداخت reserved → رزرو‌شده (پرداخت انجام شده) auto_cancel_unpaid → لغو خودکار (عدم پرداخت) cancelled_by_patient → لغو توسط بیمار cancelled_by_doctor → لغو توسط دکتر checked_in → بیمار آمده waiting → در صف انتظار in_progress → در حال ویزیت visited → ویزیت تمام شده no_show → غایب postponed → به تعویق افتاده completed → تکمیل شده ``` ⚠️ وضعیت‌هایی که slot را آزاد می‌کنند (قابل رزرو مجدد): `auto_cancel_unpaid`, `cancelled_by_patient`, `cancelled_by_doctor` ## ایندکس‌ها ```sql CREATE INDEX idx_appointments_patient ON appointments(patient_id); CREATE INDEX idx_appointments_doctor ON appointments(doctor_id); CREATE INDEX idx_appointments_doctor_time ON appointments(doctor_id, start_time); CREATE INDEX idx_appointments_status ON appointments(status); CREATE INDEX idx_appointments_representation ON appointments(representation_id); ``` ## نمونه داده واقعی از DB backup ``` id=1, uuid='617f78af-...', uid=32, doctor_id=29 start_time=1763472600, end_time=1763473800 slot: {"time":"17:00","status":"available","start_time_timestamp":1763472600, "end_time_timestamp":1763473800,"duration_per_patient":20,"location_id":38} ``` ## روابط - `appointments.patient_id` → `users.id` - `appointments.doctor_id` → `doctors.id` (clinic_pro entity) - `appointments.address_id` → `doctor_addresses.id` (clinic_pro entity) - `appointments.representation_id` → `representations.id` (clinic_pro entity) - `appointments` ← `payments.field_reference_id` (OneToOne) ## نکات مهم - تایم‌زون: `Asia/Tehran` - `start_time` و `end_time` هر دو Unix timestamp هستند (INT) - `slot.time` ساعت شروع برای نمایش است (HH:MM) - نوبت ابتدا `waiting_for_payment` → بعد پرداخت → `reserved`