# پایگاه داده — تسک ۱۷: ماژول پیامک ## جدول: sms_accounts (حساب پیامک) _(از Manual بخش ۴.۱ — entity جدید در Symfony)_ | ستون | نوع | توضیح | |------|-----|-------| | id | INT AUTO_INCREMENT PK | | | uuid | CHAR(36) UNIQUE NOT NULL | | | user_id | INT FK → users.id NOT NULL | کاربر مالک | | owner_type | VARCHAR(10) NOT NULL | `doctor` یا `clinic` | | owner_id | INT NOT NULL | FK به doctors.id یا clinics.id | | balance | INT DEFAULT 0 | تعداد پیامک باقی‌مانده | | created_at | INT NOT NULL | Unix timestamp | | updated_at | INT NOT NULL | Unix timestamp | ## جدول: sms_queue (صف پیامک) _(از Manual بخش ۴.۲)_ | ستون | نوع | توضیح | |------|-----|-------| | id | INT AUTO_INCREMENT PK | | | account_id | INT FK → sms_accounts.id CASCADE | حساب پیامک مالک | | recipient_mobile | VARCHAR(20) NOT NULL | شماره موبایل گیرنده | | message | TEXT NOT NULL | متن پیامک | | scheduled_at | INT NOT NULL | زمان برنامه‌ریزی‌شده (Unix timestamp) — معمولاً یک روز قبل از نوبت | | sent_at | INT NULL | زمان واقعی ارسال | | status | VARCHAR(20) DEFAULT 'queued' | `queued`, `sent`, `failed`, `cancelled` | | created_at | INT NOT NULL | | | updated_at | INT NOT NULL | | ## ایندکس‌ها ```sql CREATE UNIQUE INDEX idx_sms_accounts_owner ON sms_accounts(owner_type, owner_id); CREATE INDEX idx_sms_queue_account ON sms_queue(account_id); CREATE INDEX idx_sms_queue_status ON sms_queue(status, scheduled_at); CREATE INDEX idx_sms_queue_scheduled ON sms_queue(scheduled_at); ``` ## نکات مهم - هر دکتر/کلینیک فقط یک حساب پیامک دارد (UNIQUE owner_type, owner_id) - `scheduled_at` معمولاً یک روز قبل از `appointment.start_time` تنظیم می‌شود - Tauri (نرم‌افزار لوکال) پیامک‌ها را در صف می‌گذارد، بک‌اند آن‌ها را ارسال می‌کند - کسر موجودی باید atomic باشد (transaction)