Files
clinicpro/docs/phase2_taskes/task-14-sms-panel/database.md
T

3.7 KiB

پایگاه داده — تسک ۱۴: پنل پیامکی

جدول: sms_wallets

ستون نوع توضیح
id INT UNSIGNED AUTO_INCREMENT PK
entity_type VARCHAR(10) NOT NULL 'doctor' | 'clinic'
entity_id INT NOT NULL
balance_rials INT NOT NULL DEFAULT 0 موجودی فعلی
created_at INT NOT NULL
updated_at INT NOT NULL
UNIQUE (entity_type, entity_id) یک wallet به ازای هر entity

جدول: sms_wallet_transactions

ستون نوع توضیح
id INT UNSIGNED AUTO_INCREMENT PK
uuid CHAR(36) UNIQUE NOT NULL
sms_wallet_id INT NOT NULL FK→sms_wallets.id ON DELETE CASCADE
type VARCHAR(10) NOT NULL 'credit' | 'debit'
amount_rials INT NOT NULL مبلغ (همیشه مثبت)
description VARCHAR(255) NULL توضیح
payment_id INT NULL FK→payments.id ON DELETE SET NULL برای شارژ
created_at INT NOT NULL

ایندکس:

INDEX idx_sms_wallet_tx ON sms_wallet_transactions(sms_wallet_id, created_at)

جدول: sms_settings

ستون نوع توضیح
id INT UNSIGNED AUTO_INCREMENT PK
entity_type VARCHAR(10) NOT NULL
entity_id INT NOT NULL
reminder_enabled TINYINT(1) NOT NULL DEFAULT 0
reminder_hours_before TINYINT NOT NULL DEFAULT 2 چند ساعت قبل از نوبت
post_visit_enabled TINYINT(1) NOT NULL DEFAULT 0
post_visit_text TEXT NULL متن پیامک بعد از ویزیت
updated_at INT NOT NULL
UNIQUE (entity_type, entity_id)

SiteConfig key جدید

کلید نوع مقدار پیش‌فرض توضیح
sms_price_rials string '250' قیمت هر پیامک — ادمین تنظیم می‌کند

Migration نمونه

CREATE TABLE sms_wallets (
    id           INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    entity_type  VARCHAR(10) NOT NULL,
    entity_id    INT NOT NULL,
    balance_rials INT NOT NULL DEFAULT 0,
    created_at   INT NOT NULL,
    updated_at   INT NOT NULL,
    UNIQUE KEY uniq_sms_wallet_entity (entity_type, entity_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE sms_wallet_transactions (
    id            INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    uuid          CHAR(36) NOT NULL UNIQUE,
    sms_wallet_id INT NOT NULL,
    type          VARCHAR(10) NOT NULL,
    amount_rials  INT NOT NULL,
    description   VARCHAR(255) NULL,
    payment_id    INT NULL,
    created_at    INT NOT NULL,
    FOREIGN KEY (sms_wallet_id) REFERENCES sms_wallets(id) ON DELETE CASCADE,
    FOREIGN KEY (payment_id)    REFERENCES payments(id) ON DELETE SET NULL,
    INDEX idx_sms_wallet_tx (sms_wallet_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE sms_settings (
    id                    INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    entity_type           VARCHAR(10) NOT NULL,
    entity_id             INT NOT NULL,
    reminder_enabled      TINYINT(1) NOT NULL DEFAULT 0,
    reminder_hours_before TINYINT NOT NULL DEFAULT 2,
    post_visit_enabled    TINYINT(1) NOT NULL DEFAULT 0,
    post_visit_text       TEXT NULL,
    updated_at            INT NOT NULL,
    UNIQUE KEY uniq_sms_settings_entity (entity_type, entity_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

نکات مهم

  • balance_rials هرگز منفی نمی‌شود — در SmsWalletService::deduct() چک می‌شود
  • sms_wallet_transactions لاگ کامل تمام تراکنش‌ها است — حذف نمی‌شود
  • sms_settings با UPSERT ذخیره می‌شود (اگر وجود نداشت INSERT، وگرنه UPDATE)