PRD — ClinicPro Phase 2
تاریخ: ۲۴ خرداد ۱۴۰۵
نسخه: 1.2
وضعیت: Draft
خلاصه اجرایی
فاز ۲ پلتفرم ClinicPro را از یک سیستم نوبتدهی ساده به یک سیستم مدیریت کلینیک کامل تبدیل میکند. شامل پنلهای اشتراکی، مدیریت پرسنل، پرونده بیمار، سرویسهای درمانی و پنل پیامکی اختصاصی برای هر کلینیک/مطب.
وضعیت فعلی پروژه
| ماژول |
Backend |
API Doc |
| Auth (OTP + JWT + switch-context) |
✅ کامل |
docs/api/auth.md |
| Doctor profile |
✅ کامل |
docs/api/doctor.md |
| Clinic management |
✅ کامل |
docs/api/clinic.md |
| Appointment booking + settings |
✅ کامل |
docs/api/appointment.md, appointment-settings.md |
Secretary (DoctorSecretary entity) |
✅ entity + API موجود |
docs/api/secretary.md |
| Payment gateway (Mellat, SEP) |
✅ کامل — Payment.type='subscription' هم موجود |
docs/api/payment.md |
| SMS log + template |
✅ زیرساخت موجود |
docs/api/sms.md |
| Wallet / Settlement |
✅ کامل |
docs/api/settlement.md |
| SiteConfig (key-value store) |
✅ موجود |
docs/api/admin.md §Settings |
| Dashboard (clinic/doctor/secretary) |
✅ کامل |
docs/api/dashboard.md |
| Rating, Blog, Representation, Location |
✅ کامل |
فایلهای مربوطه در docs/api/ |
| Staff (پرسنل) |
❌ entity وجود ندارد |
❌ فایل doc وجود ندارد |
| Subscription tiers |
❌ entity وجود ندارد |
❌ فایل doc وجود ندارد |
| Clinic services |
❌ entity وجود ندارد |
❌ فایل doc وجود ندارد |
| Patient records |
❌ entity وجود ندارد |
❌ فایل doc وجود ندارد |
| SMS wallet/settings per clinic |
❌ entity وجود ندارد |
❌ بخش در sms.md وجود ندارد |
اپیکها
اپیک ۱ — پرسنل (Staff)
توضیح
مدیر کلینیک یا دکتر مستقل میتواند پرسنل کلینیک را ثبت کند. پرسنل حساب کاربری ندارند و نیازی به لاگین ندارند. در سرویسدهی، سشنها و گزارشات به آنها ارجاع میشود.
نیازمندیهای کارکردی
| کد |
نیازمندی |
| F1.1 |
ایجاد / ویرایش / غیرفعالسازی پرسنل — حذف سخت ممنوع (تاریخچه حفظ شود) |
| F1.2 |
فیلدها: نام و نامخانوادگی (اجباری)، شماره تماس، عنوان شغل، آدرس، کد ملی، وضعیت فعال |
| F1.3 |
پرسنل به entity_type + entity_id وابسته است (کلینیک یا مطب) |
| F1.4 |
لیست پرسنل فقط در scope کلینیک/مطب کاربر جاری نمایش داده میشود |
| F1.5 |
در ایجاد ServiceItem و SessionService از لیست پرسنل انتخاب میشود |
Entity جدید
API
| Method |
Path |
توضیح |
GET |
/api/v1/staff |
لیست پرسنل کاربر جاری |
POST |
/api/v1/staff |
ایجاد پرسنل جدید |
PATCH |
/api/v1/staff/{uuid} |
ویرایش اطلاعات |
PATCH |
/api/v1/staff/{uuid}/toggle |
فعال/غیرفعال (soft delete) |
Frontend
StaffPage.tsx — DataTable + Modal ایجاد/ویرایش
- Sidebar: زیر «تنظیمات»
فایلهای جدید
src/Staff/Entity/ClinicStaff.php
src/Staff/Controller/StaffController.php
src/Staff/Repository/ClinicStaffRepository.php
docs/api/staff.md ← باید ایجاد شود
اپیک ۲ — پنل اشتراکی (Subscription Tiers)
توضیح
سه سطح پنل با قابلیتهای متفاوت. ادمین برای هر پنل دورههای زمانی با قیمت مشخص تعریف میکند. کلینیک/دکتر دوره + پنل انتخاب کرده و پرداخت میکند.
سطوح پنل
| Level |
Name |
منشی |
قابلیتهای اضافه |
| 0 |
Free |
۱ منشی |
نوبتدهی — رایگان، بدون انقضا |
| 1 |
Basic |
۲ منشی |
پرونده بیمار + سرویسها |
| 2 |
Professional |
۵ منشی |
پرونده بیمار + سرویسها |
دورههای اشتراک (مثال — ادمین تنظیم میکند)
| نوع |
مدت |
قیمت |
| تریال |
۱ ماه |
۰ ریال — فقط برای Basic، یکبار |
| ۱ ماهه |
۱ ماه |
ادمین تعیین میکند |
| ۳ ماهه |
۳ ماه |
ادمین تعیین میکند |
| ۶ ماهه |
۶ ماه |
ادمین تعیین میکند |
| ۱۲ ماهه |
۱۲ ماه |
ادمین تعیین میکند |
قوانین تریال
- فقط برای پنل Basic
- هر کلینیک/دکتر یکبار — بعد از استفاده، دکمه تریال نمایش داده نمیشود
- بدون پرداخت — endpoint مستقل دارد
- بعد از انقضا → برگشت به Free (دادهها حفظ میشوند)
- ادمین میتواند تریال را کلاً غیرفعال کند (
trial_enabled در SiteConfig)
نیازمندیهای کارکردی
| کد |
نیازمندی |
| F2.1 |
ادمین قیمت هر ترکیب (پنل × دوره) را تعریف میکند |
| F2.2 |
ادمین میتواند دورههای جدید اضافه یا غیرفعال کند |
| F2.3 |
پرداخت از طریق gateway موجود (Mellat/SEP) — Payment.type='subscription' ✅ |
| F2.4 |
پس از پرداخت موفق: starts_at=now, expires_at=now + months*30*86400 |
| F2.5 |
تمدید از تاریخ انقضای قبلی محاسبه میشود (نه از now) |
| F2.6 |
gate check: hasFeature('patient_records') — اشتراک فعال و منقضی نشده |
| F2.7 |
هشدار ۷ روز قبل از انقضا به کلینیک/دکتر |
| F2.8 |
گزارش فروش برای ادمین (تعداد، درآمد، بر اساس سطح و دوره) |
Entities جدید
API
| 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 |
فعالسازی تریال (رایگان، یکبار) |
POST |
/api/v1/subscription-payment |
clinic/doctor |
شروع پرداخت — body: { 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 «تریال»
- جدول مقایسه پنلها با انتخاب دوره
- دکمه خرید → redirect به gateway
AdminSubscriptionPage.tsx:
- تب «پنلها»: ویرایش دورهها و قیمتها
- تب «گزارش»: فروش بر اساس بازه زمانی
فایلهای جدید
src/Subscription/Entity/SubscriptionPlan.php
src/Subscription/Entity/SubscriptionPeriod.php
src/Subscription/Entity/ClinicSubscription.php
src/Subscription/Controller/SubscriptionController.php
src/Subscription/Service/SubscriptionService.php
docs/api/subscription.md ← باید ایجاد شود
اپیک ۳ — منشی (Secretary) — تکمیل
توضیح
Entity DoctorSecretary و API کامل موجود است (docs/api/secretary.md). باید:
- محدودیت تعداد بر اساس پنل اعمال شود
- UI مدیریت permissions تکمیل شود
نیازمندیهای کارکردی
| کد |
نیازمندی |
| F3.1 |
بررسی سقف پنل قبل از ایجاد: Free→1، Basic→2، Pro→5 |
| F3.2 |
UI لیست منشی ها + اضافهکردن + ویرایش + غیرفعالسازی |
| F3.3 |
ویرایشگر permissions: checkbox matrix (موجود در DoctorSecretary.DEFAULT_PERMISSIONS) |
| F3.4 |
منشی هرگز حذف نمیشود — active: false |
تغییرات مورد نیاز
- Backend:
SecretaryController::create() — بررسی سقف پنل با SubscriptionService
- Frontend: Modal با checkbox matrix برای permissions در
SecretariesPage.tsx
API موجود (نیاز به تغییر ندارند)
GET /api/v1/secretaries/{doctorUuid} | POST /api/v1/secretary | PATCH /api/v1/secretary/{uuid} | DELETE /api/v1/secretary/{uuid}
اپیک ۴ — سرویسهای کلینیک (Clinic Services)
توضیح
دسترسی فقط در پنل Basic+. سرویسها در دو سطح: بخش (مثلاً «تزریقات») و زیربخش (مثلاً «سرم»).
نیازمندیهای کارکردی
| کد |
نیازمندی |
| F4.1 |
CRUD بخشها (ServiceSection) |
| F4.2 |
CRUD زیربخشها (ServiceItem) با انتخاب بخش + پرسنل انجامدهنده |
| F4.3 |
قیمت هر زیربخش قابل ویرایش |
| F4.4 |
gate: hasFeature('services') — بدون Basic+ → 403 |
| F4.5 |
لیست ServiceItems در ثبت سشن بیمار استفاده میشود (وابستگی اپیک ۶) |
Entities جدید
API
| Method |
Path |
توضیح |
GET |
/api/v1/service-sections |
لیست بخشها |
POST |
/api/v1/service-section |
ایجاد بخش (Basic+) |
PATCH |
/api/v1/service-section/{uuid} |
ویرایش |
DELETE |
/api/v1/service-section/{uuid} |
حذف |
GET |
/api/v1/service-items/{sectionUuid} |
لیست زیربخشهای یک بخش |
POST |
/api/v1/service-item |
ایجاد زیربخش (Basic+) |
PATCH |
/api/v1/service-item/{uuid} |
ویرایش |
DELETE |
/api/v1/service-item/{uuid} |
حذف |
Frontend
ServicesPage.tsx — accordion دو سطحی: بخشها ← زیربخشها
فایلهای جدید
src/ClinicService/Entity/ServiceSection.php
src/ClinicService/Entity/ServiceItem.php
src/ClinicService/Controller/ClinicServiceController.php
docs/api/clinic-services.md ← باید ایجاد شود
اپیک ۵ — پنل پیامکی (SMS Panel)
توضیح
زیرساخت SMS موجود است (SmsLog, SmsTemplate, SmsProvider در src/Sms/). باید:
- کیف پول پیامک اختصاصی برای هر کلینیک/دکتر
- تنظیمات ارسال پیامک (یادآوری، بعد از ویزیت)
- گزارش لاگ برای کلینیک و ادمین
نیازمندیهای کارکردی
| کد |
نیازمندی |
| F5.1 |
کیف پول پیامک جدا از کیف پول مالی |
| F5.2 |
شارژ از طریق gateway موجود |
| F5.3 |
ادمین تعرفه هر پیامک را تعیین میکند (sms_price_rials در SiteConfig) |
| F5.4 |
کسر خودکار هزینه بعد از هر ارسال موفق |
| F5.5 |
تنظیمات: یادآوری نوبت (فعال/غیرفعال + چند ساعت قبل) |
| F5.6 |
تنظیمات: پیام بعد از ویزیت (فعال/غیرفعال + متن) |
| F5.7 |
گزارش لاگ پیامکهای کلینیک/مطب |
| F5.8 |
گزارش ادمین: مصرف هر کلینیک + درآمد پیامکی |
Entities جدید
API
| Method |
Path |
Permission |
توضیح |
GET |
/api/v1/sms/wallet/balance |
clinic/doctor |
موجودی کیف پول پیامک |
POST |
/api/v1/sms/wallet/charge |
clinic/doctor |
شارژ — body: { gateway, amount_rials } |
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
- تب «پیامک» در صفحه تنظیمات کلینیک/دکتر
- نمایش موجودی + دکمه شارژ + لاگ + فرم تنظیمات
تأثیر بر فایلهای موجود
docs/api/sms.md ← بخش جدید wallet/settings اضافه شود
اپیک ۶ — پرونده بیمار (Patient Records)
توضیح
دسترسی فقط در پنل Basic+. پرونده به صورت خودکار پس از تأیید نوبت ایجاد میشود یا دستی توسط منشی/دکتر. هر مراجعه یک سشن است که شامل ویزیت + سرویسها است.
نیازمندیهای کارکردی
| کد |
نیازمندی |
| F6.1 |
ایجاد خودکار PatientRecord بعد از تأیید appointment (اگر وجود نداشت) |
| F6.2 |
ایجاد دستی توسط منشی یا دکتر |
| F6.3 |
ثبت سشن: بیمه پایه + مکمل، مبلغ ویزیت (پیشفرض یا دستی)، محاسبه خودکار کسورات |
| F6.4 |
ثبت سرویسهای انجامشده در سشن با پرسنل انجامدهنده |
| F6.5 |
gate: hasFeature('patient_records') — بدون Basic+ → 403 |
| F6.6 |
تاریخچه کامل مراجعات یک بیمار |
محاسبه مبلغ نهایی سشن
Entities جدید
API
| 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 ثبت سشن جدید (بیمه + ویزیت + سرویسها)
فایلهای جدید
src/Patient/Entity/PatientRecord.php
src/Patient/Entity/PatientSession.php
src/Patient/Entity/SessionService.php
src/Patient/Controller/PatientController.php
docs/api/patient.md ← باید ایجاد شود
اپیک ۷ — داشبورد هوشمند (Smart Dashboard)
توضیح
داشبوردهای موجود (clinic/doctor/secretary در docs/api/dashboard.md) باید با چارت و فیلتر بازه زمانی تکمیل شوند.
نیازمندیهای کارکردی
| کد |
نیازمندی |
| F7.1 |
داشبورد ادمین: چارت درآمد + چارت نوبتها + گزارش فروش پنلها |
| F7.2 |
داشبورد کلینیک/مطب: درآمد ماه جاری + بیماران منحصربهفرد + موجودی پیامک |
| F7.3 |
فیلتر بازه زمانی: این هفته / این ماه / ۳ ماه / سفارشی |
| F7.4 |
فیلتر نقش: منشی فقط نوبتها را میبیند |
API موجود (نیاز به endpoint جدید ندارد)
GET /api/v1/admin/dashboard/stats | /charts | /recent
GET /api/v1/dashboard/clinic | /doctor | /secretary
تغییر مورد نیاز
- backend: اضافه کردن پارامترهای
from و to به endpoint های charts
- frontend:
DashboardPage.tsx — افزودن date range selector + نمودارها (Recharts/Chart.js)
اولویتبندی پیادهسازی
| اولویت |
اپیک |
وابستگی |
| ۱ |
اپیک ۱ — Staff |
پیشنیاز اپیک ۴ و ۶ |
| ۲ |
اپیک ۲ — Subscription |
پیشنیاز gate در اپیک ۳، ۴، ۶ |
| ۳ |
اپیک ۳ — Secretary تکمیل |
وابسته به اپیک ۲ |
| ۴ |
اپیک ۴ — Services |
وابسته به اپیک ۱ و ۲ |
| ۵ |
اپیک ۵ — SMS Panel |
مستقل |
| ۶ |
اپیک ۶ — Patient Records |
وابسته به اپیک ۱، ۲، ۴ |
| ۷ |
اپیک ۷ — Dashboard |
آخر — نیاز به داده واقعی |
نقشه Entityهای جدید
زیرساخت موجود قابل استفاده
| زیرساخت |
مسیر |
استفاده در فاز ۲ |
| Payment gateway |
src/Payment/ |
پرداخت subscription + شارژ SMS wallet |
Payment.type='subscription' |
Payment::TYPE_SUBSCRIPTION |
پرداخت پنل اشتراکی — موجود ✅ |
| SiteConfig (key-value) |
src/Config/Entity/SiteConfig.php |
sms_price_rials, trial_enabled |
| Categories (insurance) |
bundle='insurance_type' |
انتخاب بیمه در PatientSession |
| DoctorSecretary |
src/Secretary/Entity/ |
اضافه کردن gate check |
| SmsLog/SmsTemplate |
src/Sms/Entity/ |
ارسال پیامکهای خودکار |
| WalletTransaction |
src/Settlement/Entity/ |
الگوی مشابه برای SmsWallet |
معماری مشترک
- همه entityهای جدید: Unix timestamp (
int) برای created_at, updated_at
- همه controllerهای جدید از
BaseController ارث میبرند
- پاسخها:
$this->success() / $this->paginated() / $this->error()
- polymorphic pattern:
entity_type: 'doctor'|'clinic' + entity_id
- gate check:
SubscriptionService::hasFeature(string $feature): bool
Definition of Done (هر اپیک)