Files
clinicpro/docs/new_feture/taskes/task-06-availability-engine/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

4.9 KiB
Raw Blame History

تسک ۰۶ — موتور جستجوی وقت چندمنبعی

فاز: ۱ (هسته) · وابستگی: ۰۳، ۰۵ · زمان: ۲۰-۲۴ ساعت


هدف

مستند بند ۱۰: برنامهٔ نوبت (تسک ۰۵) را روی تقویم منابع (تسک ۰۳) بلغزان و بگو چه ساعت‌هایی واقعاً ممکن‌اند — با پیشنهاد اینکه کدام منبع استفاده شود. هدف کارایی: جستجوی یک ماهه زیر نیم ثانیه.

وضعیت فعلی

// SlotCalculatorService::getServiceStartTimes() — تک‌منبعی، یک بلوک پیوسته
$busy = $this->appointmentRepo->findBusyIntervals($doctor, $dayStart, $dayStart + 86400);
while ($t + $durSec <= $winEnd) {
    $conflict = $this->firstOverlap($t, $t + $needSec, $busy);
    
}

فقط تداخل پزشک بررسی می‌شود. اتاق، دستگاه و اپراتور اصلاً وجود ندارند.

دامنه

هست:

  • AvailabilityEngine — ورودی: برنامهٔ نوبت + بازهٔ تاریخ + شعبه؛ خروجی: وقت‌های معتبر همراه با تخصیص منبع پیشنهادی
  • تولید نقطه‌های شروع کاندید (پیش‌فرض هر ۱۵ دقیقه، قابل تنظیم per محیط)
  • هرس زودهنگام کاندیدهای قطعاً ناممکن
  • تخصیص منبع: تطبیق نیازمندی‌های هر بخش به منابع آزاد
  • استراتژی انتخاب منبع: least_gap (پیش‌فرض) · balanced · preserve_specialists · same_as_previous
  • کش روزانهٔ پنجرهٔ آزاد هر منبع
  • endpoint عمومی و پنلی
  • حالت booking_mode = resource روی WeeklySchedule و مسیر ارتقای داوطلبانه

نیست: ثبت اشغال و رزرو موقت (تسک ۰۷)، قوانین فاصلهٔ زمانی (تسک ۰۹ — قلاب اینجا گذاشته می‌شود).

Endpoint ها

متد مسیر توضیح
POST /api/v1/appointment-availability جستجوی وقت با برنامه (بدنه: سرویس، آیتم‌ها، شعبه، بازهٔ تاریخ)
GET /api/v1/appointment-availability/month روزهای دارای ظرفیت در یک ماه (سبک — فقط بولین per روز)

معیار پذیرش

  • موفق: سناریوی مستند — سرویس لیزر با چهار بخش، شعبه با ۳ اتاق / ۲ اپراتور / ۳ دستگاه. جستجوی یک روز → لیست زمان‌های شروع، و برای هر زمان assignment شامل اتاق، اپراتور و دستگاه انتخابی.
  • موفق (آزادسازی ظرفیت — قلب کل پروژه): بیمار الف نوبت ۱۰:۰۰-۱۱:۰۰ دارد (اپراتور فقط ۱۰:۰۰-۱۰:۰۵ و ۱۰:۳۵-۱۱:۰۰ درگیر است). جستجو برای بیمار ب باید زمانی در بازهٔ ۱۰:۰۵-۱۰:۳۵ پیدا کند اگر اتاق دومی آزاد باشد. تست بدون این سناریو، تسک را تأیید نمی‌کند.
  • موفق: کارایی — جستجوی ۳۰ روزه با ۲۰ منبع و ۵۰۰ نوبت ثبت‌شده، زیر ۵۰۰ms. تست کارایی بخشی از تسک است، نه اختیاری.
  • موفق: پزشکی که در حالت slot یا service است → این endpoint 422 با ERR_WRONG_BOOKING_MODE می‌دهد و مسیر قدیمی دست‌نخورده کار می‌کند.
  • خطا: بازهٔ بزرگ‌تر از ۹۰ روز → 422.
  • خطا: شعبهٔ محیط دیگر → 404.
  • خطا: نیازمندی بدون منبع واجد شرایط → 422 با پیام انسانی (از تسک ۰۵).
  • ⚠️ مرزی: منبع با capacity=3 و دو نوبت هم‌زمان → سومی هنوز جا دارد، چهارمی نه.
  • ⚠️ مرزی: setup/cleanup منبع → بازهٔ اشغال گسترده‌تر از بازهٔ بخش است و باید در بررسی تداخل لحاظ شود.
  • ⚠️ مرزی: بخش با occupancy=passive → منبع را می‌گیرد ولی در گزارش بهره‌وری «کار» نیست.
  • ⚠️ مرزی: نقطهٔ شروع در گذشته → حذف.
  • ⚠️ مرزی: هیچ روزی ظرفیت ندارد → آرایهٔ خالی + reason قابل فهم، نه ۴۰۴.
  • ⚠️ مرزی: منبع مشترک بین دو بخش غیرمجاور یک نوبت → همان منبع باید انتخاب شود (اپراتور بخش ۱ و بخش ۳ یکی است، نه دو نفر).

خروجی

  • src/Appointment/Availability/
  • docs/api/appointment-availability.md
  • تست کارایی با داده مصنوعی: tests/Appointment/AvailabilityPerformanceTest.php
  • توسعهٔ AppointmentSettingsPage.tsx برای انتخاب حالت resource و استراتژی