# پایگاه داده — تسک ۱۰: ماژول نوبت‌دهی

## جدول: 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`
