Files
clinicpro/docs/new_feture/taskes/task-13-cancellation-waitlist/task.md
T
hamed 021d0eb6b2 feat: implement cancellation policy, no-show tracking, and waitlist management
- Add implementation notes for cancellation and waitlist features.
- Create task documentation outlining goals, current status, and acceptance criteria for cancellation policy and resource utilization reporting.
- Establish architecture for domain events and outbox pattern to ensure reliable event publishing.
- Define database schema for domain events and necessary queries for resource utilization and plan accuracy reports.
- Implement detailed implementation notes covering edge cases, testing strategies, and documentation requirements.
2026-07-30 11:43:58 +03:30

5.1 KiB

تسک ۱۳ — سیاست لغو، عدم حضور، لیست انتظار

فاز: ۳ (کسب‌وکار) · وابستگی: ۰۷ · زمان: ۱۰-۱۲ ساعت


هدف

مستند بند ۱۱: «هر کلینیک تنظیم می‌کند: تا چند ساعت قبل لغو رایگان است، جریمه چقدر است، بیعانه برمی‌گردد یا نه، بعد از چند بار عدم حضور بیمار پرریسک علامت بخورد.» و بند ۱۷: «رقابت روی ساعت‌های پرتقاضا → پیشنهاد خودکار ساعت جایگزین» و بند ۱۸ فاز ۳: «لیست انتظار».

وضعیت فعلی

  • لغو کار می‌کند (cancelled_by_user / cancelled_by_doctor) ولی بدون سیاست: هیچ جریمه‌ای، هیچ محدودیت زمانی، هیچ رفتاری با بیعانه
  • no_show وضعیت هست ولی هیچ اثری ندارد
  • Appointment.is_reserve وجود دارد: «نوبت رزرو» روزی (بدون ساعت) — یک لیست انتظار ابتدایی که ReserveAppointmentsPage.tsx نمایشش می‌دهد
  • بیعانه ثبت می‌شود (deposit_required, deposit_amount_rials) ولی بازگشتش دستی است

دامنه

هست:

  • CancellationPolicy per محیط/سرویس: پنجرهٔ لغو رایگان، درصد/مبلغ جریمه، رفتار بیعانه
  • NoShowPolicy: بعد از N بار، برچسب پرریسک روی بیمار (استفاده از TenantTag موجود)
  • محاسبهٔ جریمه در لحظهٔ لغو + ثبت در دفتر مالی موجود
  • Waitlist — لیست انتظار برای بازهٔ زمانی مشخص (توسعهٔ is_reserve موجود)
  • اطلاع‌رسانی خودکار به لیست انتظار وقتی ظرفیت آزاد می‌شود

نیست: پیش‌بینی عدم حضور (فاز ۴ مستند — خارج از دامنه).

Endpoint ها

متد مسیر توضیح
GET/PUT /api/v1/cancellation-policy سیاست محیط
PUT /api/v1/service-item/{uuid}/cancellation-policy override سرویس
GET /api/v1/appointment/{uuid}/cancellation-preview جریمه و بازگشت پیش از لغو
POST /api/v1/appointment/{uuid}/cancel لغو با اعمال سیاست
GET/POST /api/v1/waitlist ثبت در لیست انتظار
DELETE /api/v1/waitlist/{uuid}
GET /api/v1/waitlist/matches (پنل) درخواست‌های قابل تطبیق با ظرفیت آزاد

معیار پذیرش

  • موفق: سیاست «لغو رایگان تا ۲۴ ساعت قبل، پس از آن ۵۰٪ جریمه، بیعانه برنمی‌گردد» → GET /cancellation-preview برای نوبت ۴۸ ساعت بعد: penalty_rials: 0, deposit_refundable: true؛ برای نوبت ۶ ساعت بعد: penalty_rials: <۵۰٪>, deposit_refundable: false.
  • موفق: POST /cancel جریمه را در wallet_transactions (الگوی موجود) ثبت می‌کند و اشغال منابع را آزاد می‌کند.
  • موفق: سومین no_show بیمار → برچسب «پرریسک» (TenantTag) خودکار اضافه می‌شود و در PatientDetailPage دیده می‌شود.
  • موفق: بیمار در لیست انتظار برای «۵ مرداد، بعدازظهر» است؛ نوبتی در آن بازه لغو می‌شود → یک پیامک به او می‌رود و رکورد notified_at پر می‌شود.
  • موفق: لغو دورهٔ درمان (تسک ۱۲) → اعتبار پکیج طبق سیاست برمی‌گردد، نه همیشه.
  • خطا: cancel نوبتی که قبلاً لغو شده → 409 idempotent (همان وضعیت برگردد).
  • خطا: cancel نوبت گذشته → 422؛ برای گذشته no_show یا completed معنی دارد.
  • خطا: ثبت در لیست انتظار برای بازهٔ گذشته → 422.
  • ⚠️ مرزی: جریمه بیشتر از مبلغ پرداختی → سقف = مبلغ پرداختی.
  • ⚠️ مرزی: لغو توسط کلینیک (cancelled_by_doctor) → هرگز جریمه ندارد و بیعانه کامل برمی‌گردد.
  • ⚠️ مرزی: نوبت بدون پرداخت (نقدی سر جلسه) → جریمه ثبت می‌شود به‌عنوان بدهی، نه کسر.
  • ⚠️ مرزی: لیست انتظار با ده نفر برای یک بازه → همه مطلع می‌شوند (اولین رزروکننده می‌برد) — نه صف انحصاری. تصمیم و دلیلش در implementation_notes.
  • ⚠️ مرزی: بیمار پرریسک → مسدود نمی‌شود؛ فقط برچسب. مسدودسازی یک قانون eligibility (تسک ۰۹) روی همان برچسب است.

خروجی

  • src/Cancellation/ + src/Waitlist/
  • assets/admin/pages/CancellationPolicyPage.tsx + WaitlistPage.tsx
  • توسعهٔ AppointmentDetailPage.tsx با پیش‌نمایش لغو
  • docs/api/cancellation.md + docs/api/waitlist.md