Tasks 07 through 13 each changed something the rest of the system might want to know about, with no contract for saying so. And task 05 shipped a powerful segment editor with no feedback on whether a clinic defined its segments right. Events - A closed list of names, because a consumer branches on the string and a one-letter typo would produce an event nobody hears and no error either - Payloads carry uuids and scalars only; non-scalars are dropped, not serialised, so a consumer always fetches fresh rather than reading a stale detached entity - record() deliberately does not flush: the event row commits with the change it describes, so a rolled-back transaction leaves no event behind. A test pins exactly that - app:events:publish drains the outbox; five failed attempts park a row with its error rather than deleting it, because a silently dropped event is a loss with no trace. app:events:prune only ever removes published rows Reports - Resource utilisation separates available, occupied and active minutes. The gap between occupied and active is what exposes a bad segment definition, and available is multiplied by capacity so a three-chair room does not read as permanently over 100% - A resource with no calendar reports utilization: null, not zero — dividing by zero means something different from being idle - Plan accuracy compares planned against actual duration per service and flags both directions: running short wastes capacity that could have been sold. Its row links straight to editing that service's segments, because a report with no route to a fix does not get read Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
تسکهای موتور نوبتدهی چندمنبعی Clinic Pro
پیادهسازی تدریجی clinic-pro-mostanad-sade.md روی کد موجود. گزارش وضعیت فعلی و تحلیل شکاف: 00-current-state-report.md
⛔ سه قاعدهای که پیش از هر تسکی باید بخوانی
| سند | چه میگوید |
|---|---|
| _shared/red-lines.md | منطق اسلاتی به هیچ عنوان دستکاری نمیشود · نوبتدهی سرویسی در همین فاز کامل میشود |
| _shared/ui-conventions.md | هر صفحه یا بخش جدید عیناً با دیزاینسیستم موجود — هیچ طراحی جدید |
| _shared/definition-of-done.md | هیچ تسکی بدون تکمیل چکلیستش تمام نیست — ✅ 🔄 ⏳ ⚠️ |
در تناقض، این سه سند بر متن تسکها برندهاند.
لیست تسکها
فاز ۰ — تثبیت وضعیت فعلی (پیشنیاز بقیه)
| تسک | ماژول | پروژه | Endpoint | وابستگی | زمان |
|---|---|---|---|---|---|
| ۰۰ | تکمیل نوبتدهی سرویسی | clinicpro |
۴ | — | ۱۴-۱۸h |
| ۰۰ب | سازگارسازی سایت عمومی | nobat724_front |
— | ۰۰ | ۱۰-۱۴h |
فاز ۱ — هستهٔ چندمنبعی
| تسک | ماژول | Endpoint | وابستگی | زمان |
|---|---|---|---|---|
| ۰۱ | شعبه و اتاق | ۸ | ۰۰ | ۱۰-۱۲h |
| ۰۲ | منبع، نوع منبع، مهارت، استخر | ۱۴ | ۰۱ | ۱۴-۱۸h |
| ۰۳ | تقویم منبع، مرخصی، تعطیلات ملی | ۹ | ۰۱، ۰۲ | ۱۲-۱۴h |
| ۰۴ | کاتالوگ خدمات v2 (گروه آیتم، دو نوع زمان) | ۱۰ | ۰۱ | ۱۴-۱۶h |
| ۰۵ | بخشهای نوبت و سازندهٔ برنامه | ۳ | ۰۲، ۰۴ | ۱۶-۲۰h |
| ۰۶ | موتور جستجوی وقت چندمنبعی | ۲ | ۰۳، ۰۵ | ۲۰-۲۴h |
| ۰۷ | رزرو موقت و ثبت نهایی چندمنبعی | ۴ | ۰۶ | ۱۶-۲۰h |
| ۰۸ | لیست قیمت بازهدار و snapshot فاکتور | ۷ | ۰۴، ۰۷ | ۱۲-۱۴h |
فاز ۲ — قوانین
| تسک | ماژول | Endpoint | وابستگی | زمان |
|---|---|---|---|---|
| ۰۹ | موتور قوانین ششدستهای | ۶ | ۰۵، ۰۶، ۰۸ | ۲۰-۲۴h |
| ۱۰ | فرم ساخت قانون + محیط آزمایش | ۲ | ۰۹ | ۱۰-۱۲h |
فاز ۳ — کسبوکار
| تسک | ماژول | Endpoint | وابستگی | زمان |
|---|---|---|---|---|
| ۱۱ | پکیج و دفتر اعتبار جلسات | ۸ | ۰۸ | ۱۰-۱۲h |
| ۱۲ | دوره درمان | ۹ | ۰۷، ۱۱ | ۱۶-۲۰h |
| ۱۳ | سیاست لغو، عدم حضور، لیست انتظار | ۷ | ۰۷ | ۱۰-۱۲h |
فاز ۴ — بهینهسازی
| تسک | ماژول | Endpoint | وابستگی | زمان |
|---|---|---|---|---|
| ۱۴ | رویدادهای دامنه و گزارش بهرهوری | ۳ | ۰۷ | ۸-۱۰h |
مجموع endpoint جدید: ~۹۶ · مجموع زمان: ۲۱۴ تا ۲۵۶ ساعت
ساختار هر تسک
task-XX-name/
├── task.md ← شرح، دامنه، endpoint ها، معیار پذیرش، زمان
├── architecture.md ← فایلها، entity ها، سرویسها، لایهها، قواعد UI
├── database.md ← جداول، ستونها، ایندکسها، migration
├── implementation_notes.md ← نکات فنی، edge case، سازگاری عقبرو، تست
├── checklist.md ← ☑️ وضعیت هر مورد: ✅ 🔄 ⏳ ⚠️
└── user_flow.md ← (تسکهای پیچیده) جریان کاربری
checklist.md اجباری است و ساختار ثابتی دارد:
۰. خط سرخها ۱. بکاند ۲. دیتابیس ۳. UI ۴. تست ۵. مستندات ۶. بازبینی پایانی
چکلیست — قواعد
| نماد | معنی | اجازهٔ باقیماندن در پایان تسک |
|---|---|---|
| ✅ | انجامشده و تأییدشده | بله |
| 🔄 | در حال انجام | نه |
| ⏳ | انجامنشده | نه — مگر با دلیل مکتوب و تسک مقصد |
| ⚠️ | نیازمند بررسی یا تست | نه — باید تعیین تکلیف شود |
پیش از پایان هر تسک، همهٔ ردیفهای چکلیست بازبینی میشوند و وضعیت نهایی میگیرند. هر تسک بخش «۶. بازبینی پایانی» دارد که تستها، مستندات، UI و دو کلاینت دیگر را میسنجد.
ترتیب پیشنهادی اجرا
۰۰ ── ۰۰ب
│
├─ ۰۱ ─┬─ ۰۲ ── ۰۳ ─┐
│ └─ ۰۴ ── ۰۵ ─┴─ ۰۶ ── ۰۷ ─┬─ ۰۸ ─┬─ ۰۹ ── ۱۰
│ │ └─ ۱۱ ── ۱۲
│ ├─ ۱۳
│ └─ ۱۴
فاز ۰ اختیاری نیست. اگر حالت resource (تسک ۰۶) روی حالت service نیمهکاره ساخته
شود، هر باگ موجود سرویسی به موتور جدید ارث میرسد و تشخیص منبعش غیرممکن میشود.
فاز اول قابل عرضه: ۰۰ تا ۰۸ — بعد از آن یک کلینیک زیبایی با اتاق، دستگاه و اپراتور میتواند واقعاً نوبت بگیرد.
سه حالت نوبتدهی
| حالت | مقدار WeeklySchedule.meta.booking_mode |
وضعیت |
|---|---|---|
| اسلاتی | slot |
⛔ قفل — پیشفرض، تولیدی، دستنخورده |
| سرویسی | service |
🔄 موجود ولی نیمهکاره → تسک ۰۰ و ۰۰ب کاملش میکنند |
| چندمنبعی | resource |
⏳ جدید — تسک ۰۶ به بعد |
booking_mode پس از اولین ثبت قفل میشود (WeeklySchedule::getStoredBookingMode()).
تسک ۰۶ یک استثنای کنترلشده اضافه میکند: ارتقای یکطرفه از slot/service به
resource، مشروط بر نبودِ نوبت فعال آینده. بازگشت ممنوع.
ماتریس کامل «کدام endpoint در کدام حالت» در docs/architecture/booking-modes.md
(تسک ۰۰ میسازد، تسک ۰۶ حالت سوم را اضافه میکند).
اجبار خودکار خط سرخ
هر تسک باید این را سبز نگه دارد:
ddev exec php bin/phpunit --group=slot-mode-frozen
تسک ۰۰ این تست و سه fixture آن را میسازد. fixture ها بعد از آن read-only اند: اگر تستی قرمز شد، کد باید برگردد، نه fixture.
قواعد مشترک همهٔ تسکها
از CLAUDE.md و docs/architecture/tenancy.md. فهرست کامل در _shared/definition-of-done.md:
- entity جدید یا
TenantOwnedTraitمیگیرد یا با دلیل درGlobalTablesثبت میشود entity_type, entity_idستونهای اول هر ایندکس ترکیبیِ لیست- هر uuid از request با
TenantOwnershipCheckerسنجیده میشود - timestamp ها
intیونیکس؛ نمایش شمسی فقط در UI - کنترلر نازک ·
BaseController·success/paginated/error - API جدید فقط وقتی هیچ endpoint موجودی کافی نباشد — دلیلش نوشته شود
- تست موفق + خطا + مرزی؛ بدون اجرای موفق تست، تسک تمام نیست
- هر endpoint جدید یا تغییریافته →
docs/api/*در همان نشست - رشتههای UI فارسی از i18n؛ کد و کامیت و مستندات انگلیسی
- سازگاری عقبرو:
nobat724_frontوclinic-pro-tauriدر build خطا نمیدهند — بررسی دستی اجباری است (ردیف بازبینی پایانی هر تسک) - اول commit، بعد
graphify update .