Files
clinicpro/docs/new_feture/taskes/task-14-events-utilization/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.7 KiB
Raw Blame History

چک‌لیست — تسک ۱۴ (رویدادهای دامنه و گزارش بهره‌وری)

وضعیت کلی: تمام‌شده با انحراف‌های ثبت‌شده · آخرین بازبینی: ۱۴۰۵/۰۵/۰۹

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


۰. خط سرخ

# مورد وضعیت یادداشت
۰.۱ --group=slot-mode-frozen سبز
۰ AppointmentEvent دست‌نخورده جدول تفاوت در domain-events.md
۰ پیامک‌های موجود نشکستند Sms domain دست نخورد؛ تست‌هایش سبز
۰ گزارش با داده حدسی ساخته نشد مبنای «واقعی» فاصلهٔ ثبت‌شدهٔ اسلات است و همین در سند نوشته شد — نه حدسِ ساعت ورود و خروج

۱. بک‌اند — رویدادها

# مورد وضعیت یادداشت
۱.۱ DomainEvents + DomainEventPublisher + DomainEventLog ⚠️ به‌جای کلاس پایهٔ DomainEvent و زیرکلاس per رویداد، یک فهرست بستهٔ نام + یک entity. چهارده زیرکلاس خالی فقط برای اینکه نام را در تایپ نگه دارند، همان کاری را می‌کنند که const می‌کند
۱ payload فقط uuid و اسکالر مقادیر غیراسکالر حذف می‌شوند، نه سریال
۱ هر رویداد محیط دارد TenantOwnedTrait
۱ outbox — record() فقط persist تست rollback
۱.۵ worker انتشار ⚠️ app:events:publish هست؛ ثبتش در scheduler انجام نشد (تصمیم استقرار، نه کد — نیازمند هماهنگی با Coolify)
۱ سقف تلاش، بدون حذف ردیف شکست‌خورده تست دارد
۱.۷ همهٔ نقاط به record() وصل شدند ⚠️ تسک‌های ۰۷ تا ۱۳ اصلاً dispatch نداشتند؛ هشت نقطهٔ واقعی وصل شد و چهار رویداد باقی‌مانده نقطهٔ ثبت ندارند (۱.۸)
۱ چهارده رویداد بند ۱۶ ⚠️ ده رویداد ثبت می‌شوند. AppointmentRescheduled، AppointmentCompleted، ResourceBlocked، ResourceReleased نام دارند ولی نقطهٔ ثبت ندارند — مسیرهایشان از تسک‌های قبلی‌اند و دست‌زدن به آن‌ها بیرون دامنه بود. فهرست وضعیت در domain-events.md
۱ idempotency در مصرف‌کننده DomainEventMessage::$uuid + توضیح صریح در docblock و سند
۱.۱۰ worker با loop-wrap برای Coolify با ۱.۵ یک بسته است
۱.۱۱ app:events:prune فقط ردیف منتشرشده حذف می‌شود؛ منتشرنشده مدرکِ گم‌شدن است
۱.۱۲ GET /domain-events فقط ادمین تست ۴۰۳/۲۰۰

۲. بک‌اند — گزارش‌ها

# مورد وضعیت یادداشت
۲.۱ ResourceUtilizationReporter
۲.۲ available × capacity اتاق سه‌تخته سه برابر عرضه دارد
۲.۳ passive در occupied هست، در active نه active از appointment_segments.patient_present می‌آید
۲.۴ setup/cleanup در occupied از resource_occupancy که همه را دارد
۲.۵ released شمرده نمی‌شود BLOCKING_STATUSES
۲.۶ available = 0utilization = null تست دارد
۲.۷ مرز بازه همپوشانی بازه‌ای (start < to AND end > from) — دقیق‌تر از مرز روی یک سر
۲.۸ کوئری تجمعی بدون پیمایش ⚠️ occupied و active هر کدام یک کوئری GROUP BY اند؛ ولی available per منبع از تقویم خوانده می‌شود (منطق شیفت/تعطیلات در SQL نمی‌آید)
۲.۹ تأیید وجود دادهٔ واقعی پیش از پیاده‌سازی patient_sessions زمان شروع/پایان مراجعه ندارد، پس مبنای «واقعی» فاصلهٔ اسلات شد و همین در سند نوشته شد
۲.۱۰ آستانه‌های شدت ۳۰/۱۵/۵ درصد
۲.۱۱ انحراف منفی هم high قدر مطلق
۲.۱۲ حداقل نمونه ۱۰ ⚠️ ۳ انتخاب شد. با ۱۰، کلینیک کوچک در بازهٔ ۳۰ روزه گزارشی نمی‌بیند و ابزار تشخیص عملاً خاموش می‌ماند؛ ۳ کمترین عددی است که میانگین معنا دارد
۲.۱۳ بازه > ۹۰ روز → ۴۲۲
۲.۱۴ سه endpoint

۳. دیتابیس

# مورد وضعیت یادداشت
۳.۱ domain_events با سه ایندکس Version20260731084058
۳.۲ ایندکس worker
۳.۳ هیچ جدول دیگری تغییر نکرد
۳.۴ TenantSchemaCoverageTest سبز

۴. UI

# مورد وضعیت یادداشت
۴.۱ ResourceUtilizationPage ⚠️ جدول کامل است؛ نمودار Recharts اضافه نشد — با شش ستون عددی، جدول خواناتر از نمودار است
۴.۲ PlanAccuracyPage
۴.۳ نشان «ظرفیت هدررفته» زیر ۰٫۳
۴.۴ توضیح active_ratio در خود UI هم زیرنویس صفحه هم title ستون
۴.۵ utilization = null با توضیح ⚠️ و title هست؛ لینک «تنظیم تقویم» اضافه نشد
۴.۶ لینک اصلاح از PlanAccuracyPage «ویرایش بخش‌های این خدمت»
۴.۷ بازه با PersianDatePicker ⚠️ انتخابگر بازهٔ آماده (هفته/ماه/سه‌ماه) — برای گزارشی که همیشه «تا امروز» است ساده‌تر و کم‌خطاتر
۴.۸ وضعیت در URL بازه و شعبه در state محلی‌اند
۴.۹ DataTable با skeleton و empty state
۴.۱۰ رنگ نمودار از توکن‌ها نمودار ندارد (۴.۱)
۴.۱۱ هیچ رنگ hard-code
۴.۱۲ دارک‌مود ⚠️ فقط توکن‌ها؛ بازبینی چشمی نشد
۴.۱۳ حالت فشرده ⚠️ همان
۴.۱۴ RTL و موبایل جدول‌ها اسکرول افقی داخلی دارند
۴.۱۵ رشته‌ها فارسی
۴.۱۶ backTo

۵. تست

# مورد وضعیت یادداشت
۵.۱ صندوق خروجی — rollback، انتشار، شکست، سقف تلاش
۵ payload فقط اسکالر مقادیر تودرتو و object حذف می‌شوند
۵ بهره‌وری — سنجه‌ها ⚠️ utilization = null تست شد؛ سناریوی کامل با اشغال واقعی و capacity تست نشد (نیازمند نوبت با بخش‌های ثبت‌شده)
۵ دقت برنامه — انحراف دوطرفه و نمونهٔ کم
۵.۵ دسترسی و بازه ۴۲۲ بازه، ۴۰۳ رویدادها، جداسازی محیط
۵ تعداد کوئری مستقل از تعداد منبع با ۲.۸ یک بسته است

اجرا: ddev exec php bin/phpunit tests/Report → ۱۶ تست.

۶. مستندات

# مورد وضعیت یادداشت
۶.۱ docs/api/reports.md معنی هر عدد + جدول شدت
۶.۲ docs/architecture/domain-events.md قرارداد، فهرست، outbox، idempotency، وضعیت انتشار هر رویداد
۶.۳ جدول تفاوت AppointmentEvent و DomainEventLog

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

# مورد وضعیت یادداشت
۷.۱ هیچ بی‌دلیل نمانده همه با دلیل
۷ bin/phpunit کامل سبز ۱۳۴۰ تست؛ flakeِ ثبت‌شده در تسک ۱۳ پیدا و رفع شد
۷ --group=slot-mode-frozen سبز
۷ phpstan بدون خطای جدید ۱۴ = baseline
۷.۵ npx tsc --noEmit و تست‌های فرانت سبز ۶۳۴ تست
۷ تست‌های tenant سبز
۷.۷ docs/api/* به‌روز
۷ چک‌لیست UI کامل ⚠️ جز ۴.۱، ۴.۵، ۴.۷، ۴.۸، ۴.۱۲، ۴.۱۳
۷ پیامک‌های موجود سرتاسر تست شدند مسیر Sms تغییر نکرد؛ رویدادها مسیر جدا دارند
۷.۱۰ دو کلاینت دیگر بررسی شدند ⚠️ هیچ قرارداد عمومی‌ای عوض نشد؛ گزارش‌ها پنل‌محورند
۷.۱۱ commit، سپس graphify update . دو کامیت جدا
۷.۱۲ موارد به‌تعویق با دلیل چهار رویداد بی‌نقطهٔ ثبت (۱.۸) · scheduler/worker استقرار (۱.۵/۱.۱۰) · نمودار و URL-state (۴.۱/۴.۸) · تست کوئری‌شماری (۵.۶)