Add checklists for tasks 11 to 14 covering credit ledger, treatment course, cancellation policies, and event utilization

- Created checklist for task 11: Package and Credit Ledger
- Created checklist for task 12: Treatment Course
- Created checklist for task 13: Cancellation Policy, No-Show, and Waitlist
- Created checklist for task 14: Domain Events and Utilization Reports
This commit is contained in:
hamed
2026-07-30 12:12:45 +03:30
parent 158dcb58aa
commit 70739691d1
16 changed files with 1726 additions and 53 deletions
@@ -0,0 +1,122 @@
# چک‌لیست — تسک ۰۷ (رزرو موقت و ثبت نهایی چندمنبعی)
**وضعیت کلی:** ⏳ شروع نشده · **آخرین بازبینی:**
قواعد: [_shared/definition-of-done.md](../_shared/definition-of-done.md) ·
[red-lines.md](../_shared/red-lines.md) · [ui-conventions.md](../_shared/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` موجود توسعه یافت | ⏳ | آزادسازی + حذف سطل |
| ۲.۱۵ | قلاب‌های تسک ۰۸ و ۰۹ در `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 در UI رزرو | ⏳ | |
| ۴.۲ | خطای `409` با پیام «این ساعت همین لحظه رزرو شد» + **لیست جایگزین خودکار** | ⏳ | ⭐ مستند بند ۱۷ |
| ۴.۳ | خطای `reschedule` شامل «نوبت فعلی تغییری نکرد» | ⏳ | ⭐ |
| ۴.۴ | مسدودسازی موردی منبع از صفحهٔ منابع | ⏳ | |
| ۴.۵ | تفکیک «مسدودسازی موردی» (occupancy) از «بلندمدت» (exception) در UI روشن است | ⏳ | دو راه یک کار گیج‌کننده است |
| ۴.۶ | هیچ رنگ/شعاع hard-code | ⏳ | |
| ۴.۷ | دارک‌مود و حالت فشرده | ⏳ | |
| ۴.۸ | RTL و موبایل | ⏳ | |
| ۴.۹ | همهٔ رشته‌ها فارسی | ⏳ | |
| ۴.۱۰ | `AppointmentDetailPage` بخش بخش‌های نوبت (فقط حالت `resource`) | ⏳ | |
## ۵. تست
| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۵.۱ | `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 .` | ⏳ | |
| ۷.۱۱ | موارد به‌تعویق با دلیل و تسک مقصد | ⏳ | |