Files
clinicpro/docs/new_feture/taskes/task-07-hold-and-book/checklist.md
T
hamedandClaude Opus 5 a8020e3c20 docs: reconcile checklists with what the last passes actually built
Rows closed by the resource-strategy and blocking work: task 06's picker
interface and four strategies, task 07's ad-hoc blocking and 409 recovery, and
task 12's same-as-previous preference, which had been blocked on task 06's
missing strategies since it was written.

Tasks 13 and 14 both carried the flaky-suite caveat against their final review;
that flake has a diagnosed cause and a fix, so both now say so instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 20:53:02 +03:30

9.0 KiB
Raw Blame History

چک‌لیست — تسک ۰۷ (رزرو موقت و ثبت نهایی چندمنبعی)

وضعیت کلی: بک‌اند، تضمین دیتابیسی، مستندات و جریان رزرو (چند مورد UI با مقصد) · آخرین بازبینی:

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


۰. خط سرخ

# مورد وضعیت یادداشت
۰.۱ --group=slot-mode-frozen سبز
۰ active_slot_key و refreshActiveSlotKey() دست‌نخورده و فعال دو تور ایمنی موازی
۰ slot_start/slot_end باقی ماندند چهار مصرف‌کننده رویشان کوئری می‌زنند
۰ is_reserve دست‌نخورده — رزرو هیچ ردیف اشغالی نمی‌سازد
۰.۵ POST /api/v1/appointment قدیمی بیت‌به‌بیت کار می‌کند LegacyBookingUnchangedTest
۰ PAYMENT_TTL و رفتار انقضای موجود حفظ شد

۱. تضمین همزمانی — قلب تسک

# مورد وضعیت یادداشت
۱.۱ resource_occupancy_slot با UNIQUE(resource_id, bucket, unit_index) کل تضمین اینجاست
۱ BUCKET_SECONDS = 300 ثابت + کامنت هشدار تغییرش
۱ سطل‌ها با intdiv($end - 1, 300) — نه بدون -1 وگرنه نوبت مجاور رد می‌شود
۱ unit_index با INSERT پشت‌سرهم، نه SELECT قبلش پنجرهٔ رقابت
۱.۵ ردیف‌ها مرتب بر (resource_id, bucket, unit_index) درج می‌شوند جلوگیری از deadlock
۱ SlotTakenException موجود بازاستفاده شد
۱.۷ محدودیت گرانولاریتی ۵ دقیقه در مستندات صریح

۲. بک‌اند

# مورد وضعیت یادداشت
۲.۱ ResourceOccupancy · AppointmentSegment
۲.۲ OccupancyWriterتنها نویسندهٔ resource_occupancy
۲.۳ HoldService · BookingService · RescheduleService
۲.۴ یک ردیف per (بخش × منبع) — نه per نوبت آزادسازی ظرفیت
۲.۵ برنامه در hold دوباره ساخته می‌شود؛ assignment کلاینت فقط اعتبارسنجی می‌شود سه نشتی ثبت‌شده از همین شکل بودند
۲.۶ منبع باید کاندید همان نیازمندی باشد، نه فقط هم‌محیط
۲.۷ confirm هفت مرحله در یک تراکنش
۲.۸ confirm idempotent — دوباره روی همان hold خطا نمی‌دهد
۲.۹ رویداد بعد از commit (DispatchAfterCurrentBusStamp) با uuid در payload تسک ۱۲ رویش حساب می‌کند
۲.۱۰ reschedule: اول hold جدید، بعد آزادسازی قدیم ترتیب
۲.۱۱ لغو = status='released' + حذف فیزیکی ردیف‌های سطل
۲.۱۲ setup/cleanup در بازهٔ اشغال، نه در appointment_segments
۲.۱۳ STATUS_RESCHEDULED + گذارهای مجاز
۲.۱۴ ExpireAppointmentsHandler موجود توسعه یافت AppointmentExpiryService::expireHolds() — همان زمان‌بند موجود
۲.۱۵ قلاب‌های تسک ۰۸ و ۰۹ در confirm (مراحل ۳ و ۶)
۲.۱۶ چهار endpoint
۲.۱۷ دو کد خطا در ErrorCodes.php با پیام فارسی ERR_SLOT_TAKEN · ERR_HOLD_EXPIRED

۳. دیتابیس

# مورد وضعیت یادداشت
۳.۱ resource_occupancy (BIGINT id) با چهار ایندکس
۳.۲ resource_occupancy_slot با UNIQUE
۳.۳ appointment_segments با snapshot name/segment_type قانون پنجم
۳.۴ سه ستون تهی‌پذیر روی appointments branch_id · plan_total_minutes · patient_facing_minutes
۳.۵ ترتیب ستون ایندکس‌ها دستی در migration
۳.۶ app:occupancy:backfill --force — idempotent، نوبت‌های بی‌منبع را گزارش می‌کند بدون آن رزرو جدید روی نوبت قدیم می‌نشیند
۳.۷ app:occupancy:prune --older-than=90d
۳.۸ resource_occupancy_slot در AGGREGATE_CHILDREN + هرگز کوئری مستقیم
۳.۹ TenantSchemaCoverageTest سبز

۴. UI

# مورد وضعیت یادداشت
۴.۱ تایمر شمارش معکوس hold HoldCountdown — مبنا expires_at سرور است نه شمارندهٔ مرورگر؛ زیر یک دقیقه هشدار می‌شود. سه تست
۴.۲ خطای 409 با لیست جایگزین انتخاب کهنه کنار گذاشته و جستجو دوباره اجرا می‌شود؛ جایگزین‌ها بلافاصله روی صفحه‌اند
۴.۳ خطای reschedule شامل «نوبت فعلی تغییری نکرد» جریان جابه‌جایی نوبت در پنل ساخته نشد؛ rebook از API کامل است
۴.۴ مسدودسازی موردی منبع از صفحهٔ منابع ResourceBlocksModal + سه اندپوینت تازه؛ ۶ تست بک‌اند
۴.۵ تفکیک «مسدودسازی موردی» از «بلندمدت» در UI تفاوتشان بالای همان مودال نوشته شده، نه فقط در مستندات
۴.۶ هیچ رنگ/شعاع hard-code
۴.۷ دارک‌مود و حالت فشرده ⚠️ فقط توکن‌ها؛ بازبینی چشمی انجام نشد
۴.۸ RTL و موبایل جدول وقت‌ها اسکرول افقی داخلی دارد
۴.۹ همهٔ رشته‌ها فارسی
۴.۱۰ بخش‌های نوبت در AppointmentDetailPage کارت فاکتور اضافه شد (تسک ۰۸) ولی بخش‌های نوبت نه
۴.۱۱ جریان سه‌مرحله‌ای رزرو ResourceBookingPage: جستجو → نگه‌داشتن → ثبت، با آزادسازی صریح
۴.۱۲ انتخاب پزشک پیش از ثبت ثبت نهایی بدون پزشک ممکن نیست؛ دکمه تا انتخاب نشدن غیرفعال است

۵. تست

# مورد وضعیت یادداشت
۵.۱ ConcurrentHoldTestدو اتصال واقعی، دقیقاً یکی موفق mock قبول نیست
۵ OccupancyWriterTest — بازهٔ مماس، capacity، ترتیب INSERT
۵ HoldLifecycleTest — hold/انقضا/آزادسازی زودهنگام
۵ BookingConfirmTest — hold دیگری ۴۰۴، منقضی ۴۰۹، idempotent
۵.۵ CapacityReleaseIntegrationTest اپراتور در بازهٔ انتظار ردیف ندارد
۵ RescheduleTest — شکست hold جدید → نوبت قدیم سالم
۵.۷ OccupancyBackfillTest — idempotent
۵ LegacyBookingUnchangedTest
۵ BookingTenantTest موجود سبز

۶. مستندات

# مورد وضعیت یادداشت
۶.۱ docs/api/appointment-booking.md
۶.۲ گرانولاریتی ۵ دقیقه و محدودیتش
۶.۳ قرارداد hold_uuid و TTL
۶.۴ تفکیک مسدودسازی موردی/بلندمدت
۶.۵ docs/architecture/booking-concurrency.md — سطل زمانی + دلیل رد دو گزینهٔ دیگر شش ماه بعد زیر سؤال می‌رود

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

# مورد وضعیت یادداشت
۷.۱ هیچ 🔄 و بی‌دلیل نمانده
۷ bin/phpunit کامل سبز
۷ --group=slot-mode-frozen سبز
۷ phpstan بدون خطای جدید
۷.۵ npx tsc --noEmit و yarn test سبز
۷ تست‌های tenant سبز
۷.۷ docs/api/* به‌روز
۷ چک‌لیست UI کامل
۷ دو کلاینت دیگر بررسی شدند slot_start/slot_end سالم است؟
۷.۱۰ commit، سپس graphify update .
۷.۱۱ موارد به‌تعویق با دلیل و تسک مقصد