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:
@@ -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 .` | ⏳ | |
|
||||
| ۷.۱۱ | موارد بهتعویق با دلیل و تسک مقصد | ⏳ | |
|
||||
Reference in New Issue
Block a user