Files
clinicpro/docs/new_feture/taskes/task-06-availability-engine/checklist.md
T
hamedandClaude Opus 5 d98a0396a4 test(policy): fail if the schema advertises a field nothing ever supplies
Task 09 left this as its starred risk and deferred it to task 10, which then
shipped without it. The failure mode is silent and expensive: an operator
writes a rule on a field no call site puts in the context, activates it, and it
never matches — no error, no log, and the clinic believes the rule is running.

The test is structural rather than behavioural on purpose. Walking every real
path for every field would need a test rig larger than the engine; asserting
that each advertised field is populated somewhere in src/ catches the case that
actually happens, which is a field added to the schema and nowhere else.

Also closes the last few rows that had gone stale:

- evaluateIsolated: PolicyResolver::evaluateOne() landed with the sandbox
- forbid before candidate generation: the plan builder already reads
  prohibitions before the availability engine is reached
- appointments.applied_policies and app:policy:seed-examples are declined with
  their reasons rather than left open — the trace lives on the price snapshot
  and a second column would be a second source of truth, and the template
  registry does the seeding job from inside the UI where the user can see the
  result before creating anything
- the reserve list keeps its page in the URL like every other panel list

Every checklist across the sixteen tasks now has zero pending rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 14:37:32 +03:30

9.8 KiB
Raw Blame History

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

وضعیت کلی: تمام‌شده — موتور، کارایی، مستندات، انتخاب حالت و جریان رزرو · آخرین بازبینی:

قواعد: _shared/definition-of-done.md · red-lines.md · ui-conventions.md


۰. خط سرخ — حساس‌ترین تسک این فاز

# مورد وضعیت یادداشت
۰.۱ --group=slot-mode-frozen سبز
۰ SlotCalculatorService هیچ متدی عوض نشد AvailabilityEngine کلاس موازی
۰ GET /appointment-slots بیت‌به‌بیت دست‌نخورده
۰ GET /appointment-service-slots دست‌نخورده حالت service موجود
۰.۵ GET /month-availability/{doctorUuid} دست‌نخورده
۰ LegacyBookingUnchangedTest: همهٔ تست‌های اسلاتی و سرویسی موجود سبز
۰.۷ انتخاب موتور فقط با match($mode) در کنترلر — هیچ fallback خاموشی حالت اشتباه → ERR_WRONG_BOOKING_MODE
۰ DEFAULT_META['booking_mode'] همچنان slot

۱. بک‌اند

# مورد وضعیت یادداشت
۱.۱ AvailabilityEngine · CandidateGenerator · ResourceAllocator · OccupancyIndex
۱ چهار استراتژی + ResourcePicker با tagged_iterator first_available · least_gap · least_loaded · same_as_previous؛ استراتژی مرتب می‌کند، انتخاب نمی‌کند
۱ DailyWindowCacheفقط پنجرهٔ تقویمی، هرگز اشغال
۱ MODE_RESOURCE + slot_granularity + picker_strategy در meta با اعتبارسنجی
۱.۵ POST /appointment-settings/upgrade-booking-mode — یک‌طرفه، با شرط
۱ دو endpoint جستجو
۱.۷ groupKey = (role, skills, constraints, indexInSegment)؛ تطبیق بین‌بخشی روی سه جزء اول تلهٔ دو نیازمندی هم‌شکل در یک بخش
۱ تخصیص حریصانه (بدون backtracking) + دلیل مکتوب
۱ دو گذر setup/cleanup: بیشینهٔ کاندیدها، بعد دقیق منبع انتخابی
۱.۱۰ hasRoom شرط expires_at > now روی hold
۱.۱۱ reason در پاسخ خالی: no_resource/no_calendar/fully_booked/outside_window نه ۴۰۴، نه پیام واحد
۱.۱۲ قلاب policies->filterSlots از روز اول در امضا تسک ۰۹
۱.۱۳ سقف‌ها: بازه ۹۰ روز · limit ۲۰۰ · گام ≥۵ · کاندید ≤۵۰ per نیازمندی
۱.۱۴ TenantOwnershipChecker روی هر uuid از request

۲. کارایی — بخشی از تسک، نه اختیاری

# مورد وضعیت یادداشت
۲.۱ سه کوئری برای کل بازه؛ هیچ I/O داخل حلقه
۲.۲ هرس با «تنگ‌ترین منبع» پیاده شد ~۸۰٪ کاندیدها حذف
۲.۳ busy مرتب + جستجوی دودویی در OccupancyIndex
۲.۴ app:dev:seed-availability-benchmark ۳ اتاق، ۲ اپراتور، ۳ دستگاه، ۵۰۰ نوبت
۲.۵ AvailabilityPerformanceTest: < ۵۰۰ms
۲.۶ AvailabilityPerformanceTest: ۵ کوئری مهم‌تر از زمان — ماشین‌مستقل
۲.۷ ابطال کش: تقویم/استثنا/ساعت شعبه/تعطیلی → win؛ ثبت نوبت → فقط month کش پیاده نشد — تست کارایی بدون کش هم زیر بودجه است، پس کش الان بهینه‌سازی زودرس بود. مقصد: وقتی اندازه‌گیری واقعی لازمش کند

۳. دیتابیس

# مورد وضعیت یادداشت
۳.۱ resource_occupancy در این تسک migrate شد (تعریف در تسک ۰۷) وابستگی معکوس
۳.۲ idx_occupancy_resource_range (resource_id, start_at, end_at, status) resource_id اول — نه tenant
۳.۳ ترتیب ستون‌های ایندکس در migration دستی نوشته شد diff گاهی جابه‌جا می‌کند
۳.۴ setMeta کلیدهای جدید را با اعتبارسنجی می‌پذیرد مقدار نامعتبر → مقدار فعلی

۴. UI

# مورد وضعیت یادداشت
۴.۱ انتخاب حالت resource + گام + استراتژی هر سه در ScheduleSection؛ فهرست استراتژی‌ها از GET /appointment-settings/resource-strategies می‌آید، نه از فهرستی که در فرانت تکرار شود
۴.۲ چک‌لیست پیش از ارتقا با ✓/✗ «حداقل یک منبع فعال» و «حداقل یک سرویس با بخش» با لینک اصلاح؛ همان شرطی که بک‌اند هم اعمال می‌کند
۴.۳ تأیید برگشت‌ناپذیری ConfirmDialog موجود، حالا با برچسب درست هر سه حالت
۴.۴ جدول وقت‌ها با ستون «منابع پیشنهادی» ResourceBookingPage — تاریخ، ساعت، منابع، انتخاب
۴.۵ عوض کردن یک منبع → گزینه‌های همان زمان فهرست هر نقش فقط منابعی است که موتور برای همان زمان داده؛ فهرست کامل شعبه یعنی انتخابی که ۴۰۹ می‌گیرد
۴.۶ reason خالی‌بودن با پیام فارسی REASON_LABELS — «بازه را بزرگ‌تر کنید یا شعبهٔ دیگری را امتحان کنید»
۴.۷ assignment به بیمار نمایش داده نمی‌شود صفحه پنل‌محور است و همان‌جا هم نوشته شده
۴.۸ هیچ رنگ/شعاع hard-code فقط var(--…)
۴.۹ دارک‌مود و حالت فشرده ⚠️ فقط توکن‌ها؛ بازبینی چشمی انجام نشد
۴.۱۰ RTL و موبایل کارت‌های حالت روی موبایل تک‌ستونه می‌شوند
۴.۱۱ همهٔ رشته‌ها فارسی
۴.۱۲ ScheduleSection.tsx توسعه یافت، کامپوننت موازی نه همان فایل، سه کارت به‌جای دو
۴.۱۳ نگهبان بک‌اند برای آمادگی حالت تازه اضافه شد: بدون منبع فعال، 422 — وگرنه انتخابِ برگشت‌ناپذیر محیط را قفل می‌کرد
۴.۱۴ تست نگهبان ResourceModeReadinessTest — سه تست

۵. تست

# مورد وضعیت یادداشت
۵.۱ OccupancyIndexTest — capacity، بازهٔ مماس، shared/exclusive واحد
۵ CandidateGeneratorTest — هرس، گذشته، برنامهٔ جا‌نشو
۵ ResourceAllocatorTest — منبع مشترک یکی؛ دو هم‌شکل در یک بخش دو منبع
۵ CapacityReleaseTestآزادسازی ظرفیت بدون این تسک تأیید نمی‌شود
۵.۵ تست استراتژی‌ها ResourcePickerTest — ۹ تست: ترتیب هر چهار استراتژی، رجیستری، بازگشت به پیش‌فرض روی کلید ناشناخته، رد شدن هنگام ذخیره
۵ BookingModeGuardTest — حالت اشتباه دو طرفه ۴۲۲ + ارتقا با نوبت فعال
۵.۷ AvailabilityPerformanceTest
۵ LegacyBookingUnchangedTest

۶. مستندات

# مورد وضعیت یادداشت
۶.۱ docs/api/appointment-availability.md
۶.۲ جدول استراتژی‌ها در appointment-availability.md با «کِی مناسب است» هر کدام
۶.۳ محدودیت تخصیص حریصانه مکتوب
۶.۴ ماتریس «کدام endpoint در کدام حالت»
۶.۵ docs/architecture/booking-modes.md (تسک ۰۰) حالت سوم را گرفت
۶.۶ در docs/api/appointment.md برجسته: کلاینت‌ها پس از ارتقا باید مسیر جدید بزنند

۷. بازبینی پایانی

# مورد وضعیت یادداشت
۷.۱ هیچ 🔄 و بی‌دلیل نمانده
۷ bin/phpunit کامل سبز
۷ --group=slot-mode-frozen سبز
۷ phpstan بدون خطای جدید
۷.۵ npx tsc --noEmit و yarn test سبز
۷ تست‌های tenant سبز
۷.۷ docs/api/* به‌روز
۷ چک‌لیست UI کامل
۷ ⚠️ nobat724_front و clinic-pro-tauri: تا کلینیک ارتقا نداده، تغییری لازم نیست — تأیید شد
۷.۱۰ تسک frontend حالت resource برای سایت ثبت شد (خارج از این فاز)
۷.۱۱ commit، سپس graphify update .
۷.۱۲ موارد به‌تعویق با دلیل و تسک مقصد