Files
clinicpro/docs/PRD/prd.md
T

21 KiB
Raw Blame History

PRD — ClinicPro Phase 2

تاریخ: ۲۴ خرداد ۱۴۰۵
نسخه: 1.0
وضعیت: Draft


خلاصه اجرایی

این سند نیازمندی‌های فاز ۲ پلتفرم ClinicPro را پوشش می‌دهد. هدف: تبدیل پلتفرم از یک سیستم نوبت‌دهی ساده به یک سیستم مدیریت کلینیک کامل با پنل‌های اشتراکی، پرونده بیمار، مدیریت پرسنل و پنل پیامکی.


وضعیت فعلی پروژه

ماژول وضعیت
Auth (OTP + JWT) کامل
Doctor profile کامل
Clinic management کامل
Appointment booking کامل
Secretary entity (DoctorSecretary) موجود — نیاز به UI و permissions بیشتر
Payment gateway (Mellat, SEP) کامل — برای نوبت + subscription
SMS (SmsLog, SmsTemplate) زیرساخت موجود — نیاز به پنل کلینیک
Wallet / Settlement کامل
Site config (SiteConfig key-value) موجود
Staff (پرسنل) موجود نیست
Panel subscription tiers موجود نیست
Patient records (پرونده بیمار) موجود نیست
Clinic services (خدمات) موجود نیست
SMS panel per clinic UI نیاز دارد

اپیک‌ها و قابلیت‌ها


اپیک ۱ — پرسنل (Staff)

توضیح

مدیر کلینیک یا دکتر مستقل می‌تواند پرسنلی که نیازی به لاگین ندارند را ثبت کند. این پرسنل در سرویس‌دهی، سشن‌ها و گزارشات استفاده می‌شوند.

نیازمندی‌های کارکردی

  • F1.1 — ایجاد / ویرایش / غیرفعال‌سازی پرسنل (حذف نرم — soft delete)
  • F1.2 — فیلدهای پرسنل:
    • نام و نام خانوادگی (اجباری)
    • شماره تماس
    • عنوان شغل (مثال: پرستار، منشی، تکنسین)
    • آدرس
    • کد ملی
    • فعال / غیرفعال
  • F1.3 — پرسنل به کلینیک یا مطب دکتر وابسته است (FK به clinic_id یا doctor_id)
  • F1.4 — لیست پرسنل فقط در scope کلینیک/مطب فعال نمایش داده می‌شود
  • F1.5 — در ایجاد سرویس، از لیست پرسنل انتخاب می‌شود

موجودیت‌های جدید مورد نیاز

ClinicStaff:
  - id, uuid
  - clinic_id (FK → clinics) OR doctor_id (FK → doctors)  [یکی از دو]
  - full_name, phone, job_title, address, national_code
  - active (bool, default: true)
  - created_at, updated_at (Unix timestamp)

API endpoints

Method Path Permission
GET /api/v1/staff clinic/doctor
POST /api/v1/staff clinic/doctor
PATCH /api/v1/staff/{uuid} clinic/doctor
PATCH /api/v1/staff/{uuid}/toggle clinic/doctor

Frontend

  • صفحه: StaffPage.tsx — لیست با DataTable + Modal ایجاد/ویرایش
  • در Sidebar زیر بخش «تنظیمات»

اپیک ۲ — پنل اشتراکی (Subscription Tiers)

توضیح

سه سطح پنل وجود دارد. برای هر پنل، ادمین می‌تواند چند دوره زمانی با قیمت‌های مختلف تعریف کند (مثلاً ۱ ماهه، ۶ ماهه، ۱۲ ماهه). کلینیک/دکتر دوره و پنل مورد نظر را انتخاب و پرداخت می‌کند.

پنل‌ها

سطح نام قابلیت‌ها
0 Free نوبت‌دهی + ۱ منشی — رایگان، بدون زمان انقضا
1 Basic ۲ منشی + پرونده بیمار + مدیریت سرویس‌ها
2 Professional ۵ منشی + پرونده بیمار + مدیریت سرویس‌ها

دوره‌های اشتراک (مثال)

دوره مدت (ماه) نوع قیمت
تریال 1 trial — رایگان ۰ ریال
۱ ماهه 1 paid ادمین تعیین می‌کند
۳ ماهه 3 paid ادمین تعیین می‌کند
۶ ماهه 6 paid ادمین تعیین می‌کند
۱۲ ماهه 12 paid ادمین تعیین می‌کند

ادمین می‌تواند دوره‌های دلخواه اضافه، ویرایش یا غیرفعال کند.

دوره تریال

  • تریال فقط برای پنل Basic فعال است
  • هر کلینیک/دکتر فقط یک بار می‌تواند از تریال استفاده کند (بررسی در ClinicSubscription)
  • تریال نیازی به پرداخت ندارد — مستقیم فعال می‌شود
  • ادمین می‌تواند تریال را به‌طور کلی فعال/غیرفعال کند (trial_enabled در SiteConfig)
  • بعد از انقضای تریال، سیستم به پنل Free بازمی‌گردد (نه حذف داده)

نیازمندی‌های کارکردی

  • F2.1 — ادمین برای هر ترکیب (پنل × دوره) یک قیمت تعریف می‌کند
  • F2.2 — ادمین می‌تواند دوره‌های جدید اضافه کند (مثلاً ۲ ماهه) یا دوره‌ای را غیرفعال کند
  • F2.3 — کلینیک/دکتر پنل + دوره را انتخاب و از طریق gateway موجود (Mellat/SEP) پرداخت می‌کند
  • F2.4 — پس از پرداخت موفق، اشتراک فعال می‌شود: starts_at = now, expires_at = now + duration_months * 30 * 86400
  • F2.5 — تمدید: اگر اشتراک فعال باشد، starts_at از تاریخ انقضای قبلی محاسبه می‌شود (نه از now)
  • F2.6 — gate: hasFeature('patient_records') — بررسی اشتراک فعال و expired نبودن
  • F2.7 — گزارش فروش پنل‌ها در داشبورد ادمین (تعداد، درآمد، بر اساس دوره و سطح)
  • F2.8 — نمایش تاریخ انقضا و هشدار ۷ روز قبل به کلینیک/دکتر
  • F2.9 — تریال Basic: فعال‌سازی رایگان یک‌بار — endpoint جداگانه POST /api/v1/subscription/trial
  • F2.10 — بررسی استفاده قبلی از تریال قبل از فعال‌سازی (used_trial: bool روی entity)

موجودیت‌های جدید مورد نیاز

SubscriptionPlan:
  - id, uuid
  - name: 'free' | 'basic' | 'professional'
  - level: int (0/1/2)
  - max_secretaries: int (1/2/5)
  - features: json { patient_records: bool, services: bool, sms_panel: bool }
  - active: bool
  - created_at, updated_at

SubscriptionPeriod:
  - id, uuid
  - plan_id (FK → subscription_plans)
  - label: string (مثال: "۶ ماهه", "تریال ۱ ماهه")
  - duration_months: int (1, 3, 6, 12, ...)
  - price_rials: int (0 برای تریال)
  - is_trial: bool (default: false — فقط یک دوره trial در Basic)
  - active: bool
  - sort_order: int (ترتیب نمایش)
  - created_at, updated_at

ClinicSubscription:
  - id, uuid
  - entity_type: 'doctor' | 'clinic'
  - entity_id: int
  - plan_id (FK → subscription_plans)
  - period_id (FK → subscription_periods)
  - payment_id (FK → payments, nullable — برای تریال null است)
  - is_trial: bool (کپی از period — برای گزارش راحت‌تر)
  - starts_at: int (Unix timestamp)
  - expires_at: int (Unix timestamp — null = بی‌نهایت برای Free)
  - created_at

وابستگی به Payment موجود

  • Payment.type = 'subscription' (از قبل موجود)
  • Callback در PaymentController::subscriptionCallback(): ایجاد ClinicSubscription پس از تأیید

API endpoints

Method Path Permission
GET /api/v1/subscription/plans public — لیست پنل‌ها با دوره‌ها، قیمت‌ها و دوره تریال
GET /api/v1/subscription/my clinic/doctor — اشتراک فعال + تاریخ انقضا + used_trial
POST /api/v1/subscription/trial clinic/doctor — فعال‌سازی تریال Basic (رایگان، یک‌بار)
POST /api/v1/subscription-payment clinic/doctor — { period_uuid }
GET /api/v1/admin/subscription/plans admin — مدیریت پنل‌ها
POST /api/v1/admin/subscription/plan admin
PATCH /api/v1/admin/subscription/plan/{uuid} admin
POST /api/v1/admin/subscription/period admin — افزودن دوره جدید
PATCH /api/v1/admin/subscription/period/{uuid} admin — ویرایش قیمت/مدت/تریال
DELETE /api/v1/admin/subscription/period/{uuid} admin — غیرفعال‌سازی
GET /api/v1/admin/subscription/report admin — گزارش فروش + تعداد تریال‌های فعال‌شده

Frontend

  • صفحه کلینیک/دکتر: SubscriptionPage.tsx
    • اگر used_trial = false: بنر «۱ ماه رایگان امتحان کنید» با دکمه فعال‌سازی تریال
    • نمایش پنل فعال + تاریخ انقضا (شمسی) + badge «تریال» اگر is_trial باشد
    • جدول مقایسه پنل‌ها با انتخاب دوره (toggle)
    • دکمه خرید → redirect به gateway
  • صفحه ادمین: AdminSubscriptionPage.tsx
    • تب «پنل‌ها»: ویرایش قیمت دوره‌ها + مشخص کردن کدام دوره تریال است
    • تب «گزارش»: فروش + تریال‌ها بر اساس بازه زمانی

اپیک ۳ — منشی (Secretary) — تکمیل

توضیح

جدول doctor_secretaries و entity DoctorSecretary موجود است. نیاز به:

  • محدودیت تعداد منشی بر اساس پنل
  • صفحه فرانت‌اند کامل برای مدیریت منشیان و تنظیم دسترسی‌ها

نیازمندی‌های کارکردی

  • F3.1 — بررسی سقف تعداد منشی قبل از ایجاد (free→1, basic→2, pro→5)
  • F3.2 — UI کامل: لیست منشیان + اضافه کردن + ویرایش دسترسی + غیرفعال‌سازی
  • F3.3 — پنل دسترسی: checkbox matrix برای هر منشی (permissions JSON موجود)
    • نوبت‌ها: view, create, cancel, update_status
    • آدرس‌ها: view, create, update, delete
    • اطلاعات کلینیک: view, update
    • بیمه‌ها: view, create, update, delete
  • F3.4 — منشی هرگز حذف نمی‌شود (soft delete با active: false)

وضعیت فعلی

// DoctorSecretary.DEFAULT_PERMISSIONS — موجود
// API موجود: GET /api/v1/secretaries/{doctorUuid}, POST /api/v1/secretary, PATCH, DELETE
// صفحه SecretariesPage.tsx موجود — نیاز به بررسی کامل بودن

تغییرات مورد نیاز

  • Backend: اضافه کردن بررسی سقف پنل در SecretaryController::create()
  • Frontend: ویرایشگر گرافیکی permissions (checkbox matrix در Modal)

اپیک ۴ — سرویس‌های کلینیک (Clinic Services)

توضیح

دسترسی فقط در پنل Basic و بالاتر. سرویس‌ها در دو سطح تعریف می‌شوند: بخش و زیر بخش.

ساختار سرویس

ServiceSection (بخش — مثال: تزریقات، پانسمان)
  └── ServiceItem (زیر بخش — مثال: سرم)
        - section_id (FK)
        - staff_id (FK → clinic_staff) — پرسنل انجام‌دهنده
        - price (ریال)
        - active

نیازمندی‌های کارکردی

  • F4.1 — CRUD بخش‌ها (ServiceSection)
  • F4.2 — CRUD زیر بخش‌ها (ServiceItem) با انتخاب بخش و پرسنل
  • F4.3 — قیمت هر زیر بخش قابل ویرایش
  • F4.4 — gate: hasFeature('services') — بدون Basic+ → 403

موجودیت‌های جدید مورد نیاز

ServiceSection:
  - id, uuid
  - entity_type: 'doctor' | 'clinic', entity_id
  - name
  - active, created_at, updated_at

ServiceItem:
  - id, uuid
  - section_id (FK → service_sections)
  - staff_id (FK → clinic_staff, nullable)
  - name, price_rials
  - active, created_at, updated_at

API endpoints

Method Path Permission
GET /api/v1/service-sections clinic/doctor
POST /api/v1/service-section clinic/doctor (basic+)
PATCH /api/v1/service-section/{uuid} clinic/doctor
DELETE /api/v1/service-section/{uuid} clinic/doctor
GET /api/v1/service-items/{sectionUuid} clinic/doctor
POST /api/v1/service-item clinic/doctor (basic+)
PATCH /api/v1/service-item/{uuid} clinic/doctor
DELETE /api/v1/service-item/{uuid} clinic/doctor

Frontend

  • صفحه: ServicesPage.tsx با دو سطح accordion: بخش‌ها و زیر بخش‌ها

اپیک ۵ — پنل پیامکی (SMS Panel)

توضیح

زیرساخت SMS (SmsLog, SmsTemplate, SmsProvider) موجود است. باید پنل شارژی برای هر کلینیک/دکتر اضافه شود.

نیازمندی‌های کارکردی

  • F5.1 — کیف پول پیامک جداگانه از کیف پول مالی (یا همان wallet با type مجزا)
  • F5.2 — شارژ کردن پنل پیامک از طریق gateway موجود
  • F5.3 — ادمین تعرفه هر پیامک را در SiteConfig تعیین می‌کند (sms_price_rials)
  • F5.4 — کسر خودکار هزینه از پنل پس از هر ارسال موفق
  • F5.5 — تنظیمات ارسال پیامک (در صفحه تنظیمات کلینیک):
    • یادآوری نوبت: فعال/غیرفعال + چند ساعت قبل
    • پیام بعد از ویزیت: فعال/غیرفعال + متن قابل تنظیم
  • F5.6 — گزارش لاگ پیامک‌های هر کلینیک/دکتر
  • F5.7 — گزارش ادمین: درآمد پیامکی، مصرف هر کلینیک

موجودیت‌های جدید/تغییر یافته

SmsWallet (یا افزودن فیلد به Doctor/Clinic):
  - entity_type, entity_id
  - balance_rials (موجودی)
  - created_at, updated_at

SmsSettings:
  - entity_type, entity_id
  - reminder_enabled (bool)
  - reminder_hours_before (int)
  - post_visit_enabled (bool)
  - post_visit_text (text)
  - updated_at

API endpoints

Method Path Permission
GET /api/v1/sms/wallet/balance clinic/doctor
POST /api/v1/sms/wallet/charge clinic/doctor
GET /api/v1/sms/wallet/logs clinic/doctor
GET /api/v1/sms/settings clinic/doctor
PATCH /api/v1/sms/settings clinic/doctor
GET /api/v1/admin/sms/wallet-report admin

Frontend

  • تب «پیامک» در صفحه تنظیمات کلینیک/دکتر
  • نمایش موجودی + دکمه شارژ + لاگ

اپیک ۶ — پرونده بیمار (Patient Records)

توضیح

دسترسی در پنل Basic+. پرونده بیمار به صورت خودکار پس از تأیید نوبت ایجاد می‌شود یا دستی توسط منشی/دکتر.

ساختار پرونده

PatientRecord (پرونده بیمار):
  - entity_type, entity_id (کلینیک/مطب که پرونده به آن تعلق دارد)
  - user_id (FK → users — بیمار)
  - created_by (منشی/دکتر که ایجاد کرده)
  - created_at

PatientSession (مراجعه/ویزیت):
  - record_id (FK → patient_records)
  - appointment_id (FK → appointments, nullable — اگر از نوبت)
  - insurance_base_id (FK → categories, bundle='insurance_type')
  - insurance_supplementary_id (FK → categories)
  - visit_price_rials (مبلغ کل ویزیت)
  - base_insurance_discount_percent (کسر بیمه پایه)
  - supplementary_discount_percent (کسر بیمه مکمل)
  - final_price_rials (مبلغ نهایی پس از کسورات)
  - payment_method: 'cash' | 'card' | 'insurance' | 'pending'
  - notes (text)
  - created_at, updated_at

SessionService (سرویس انجام‌شده در یک مراجعه):
  - session_id (FK → patient_sessions)
  - service_item_id (FK → service_items)
  - staff_id (FK → clinic_staff — پرسنل انجام‌دهنده)
  - price_rials (قیمت در زمان ارائه)
  - created_at

نیازمندی‌های کارکردی

  • F6.1 — ایجاد خودکار PatientRecord پس از تأیید appointment (اگر وجود ندارد)
  • F6.2 — ایجاد دستی توسط منشی یا دکتر
  • F6.3 — ثبت سشن جدید با:
    • انتخاب بیمه پایه و تکمیلی (از categories)
    • تعیین مبلغ ویزیت (از پیش تعیین‌شده یا قابل ویرایش)
    • محاسبه خودکار مبلغ نهایی
    • ثبت سرویس‌های انجام شده (از ServiceItems)
    • تعیین پرسنل انجام‌دهنده
  • F6.4 — gate: hasFeature('patient_records') — بدون Basic+ → 403
  • F6.5 — تاریخچه مراجعات یک بیمار قابل نمایش

API endpoints

Method Path Permission
GET /api/v1/patients clinic/doctor (basic+)
POST /api/v1/patient clinic/doctor (basic+)
GET /api/v1/patient/{uuid} clinic/doctor
GET /api/v1/patient/{uuid}/sessions clinic/doctor
POST /api/v1/patient/{uuid}/session clinic/doctor
PATCH /api/v1/session/{uuid} clinic/doctor

Frontend

  • صفحه PatientsPage.tsx — لیست بیماران با جستجو
  • صفحه PatientDetailPage.tsx — پرونده کامل + تاریخچه مراجعات
  • Modal ثبت سشن جدید

اپیک ۷ — داشبورد هوشمند (Smart Dashboard)

توضیح

هر داشبورد (ادمین، کلینیک، مطب، منشی) باید چارت‌های مناسب با فیلترهای role-based داشته باشد.

نیازمندی‌های کارکردی

  • F7.1 — داشبورد ادمین:
    • چارت: درآمد پلتفرم (ماهانه، هفتگی)
    • چارت: نوبت‌های ثبت‌شده در بازه زمانی
    • آمار: تعداد کلینیک‌ها، دکترها، کاربران فعال
    • گزارش پنل‌های فروخته‌شده
  • F7.2 — داشبورد کلینیک/مطب:
    • نوبت‌های امروز (موجود)
    • درآمد ماه جاری
    • تعداد بیماران منحصربه‌فرد
    • موجودی پیامک
  • F7.3 — فیلتر بازه زمانی در همه چارت‌ها (این هفته / این ماه / ۳ ماه / سفارشی)
  • F7.4 — فیلتر بر اساس نقش (منشی فقط نوبت‌ها را می‌بیند)

اولویت‌بندی پیاده‌سازی

اولویت اپیک دلیل
1 اپیک ۱ (Staff) پیش‌نیاز اپیک ۴ و ۶
2 اپیک ۲ (Subscription) پیش‌نیاز gate checks
3 اپیک ۳ (Secretary - تکمیل) وابسته به پنل
4 اپیک ۴ (Services) پیش‌نیاز اپیک ۶
5 اپیک ۵ (SMS Panel) مستقل از بقیه
6 اپیک ۶ (Patient Records) بیشترین وابستگی
7 اپیک ۷ (Dashboard) آخر — نیاز به داده واقعی

وابستگی‌های فنی

وضعیت زیرساخت موجود و قابل استفاده

زیرساخت فایل نحوه استفاده در فاز ۲
Payment gateway src/Payment/ پرداخت پنل اشتراکی و شارژ SMS
Wallet src/Settlement/Entity/WalletTransaction.php بررسی مدل برای SMS wallet
SiteConfig src/Config/Entity/SiteConfig.php ذخیره قیمت پنل‌ها + تعرفه SMS
Categories (insurance) bundle='insurance_type' انتخاب بیمه در سشن
DoctorSecretary src/Secretary/Entity/DoctorSecretary.php افزودن بررسی سقف پنل
SmsLog/SmsTemplate src/Sms/Entity/ زیرساخت ارسال موجود

نکات معماری

  • همه entity‌های جدید از الگوی Unix timestamp استفاده می‌کنند
  • همه controller‌های جدید از BaseController ارث می‌برند
  • gate check برای features با یک helper در BaseController یا SubscriptionService پیاده‌سازی شود
  • entity_type + entity_id pattern (polymorphic) برای Staff، Services، SmsSettings، Patient Records

معیارهای پذیرش (Definition of Done)

برای هر اپیک:

  • Entity + Migration ایجاد شده
  • Controller + Repository + Service نوشته شده
  • API endpoints تست‌پذیر در Swagger (/api/doc)
  • Frontend page کامل با CRUD
  • مستندات docs/api/ به‌روزرسانی شده
  • بررسی gate/permission برای plan-gated features