# چک‌لیست — تسک ۰۵ (بخش‌های نوبت و سازندهٔ برنامه) **وضعیت کلی:** ⏳ شروع نشده · **آخرین بازبینی:** — قواعد: [_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` سبز | ⏳ | | | ۰.۲ | `SlotCalculatorService` دست‌نخورده | ⏳ | | | ۰.۳ | سرویس بدون `SegmentTemplate` → یک بخش مجازی با منبع `type=doctor` | ⏳ | ⭐ سازگاری حالت `service` فعلی | | ۰.۴ | هیچ جدولی برای «برنامهٔ ساخته‌شده» ساخته نشد | ⏳ | DTO درون‌حافظه؛ ذخیره کار تسک ۰۷ | ## ۱. بک‌اند | # | مورد | وضعیت | یادداشت | |---|---|---|---| | ۱.۱ | `SegmentTemplate` · `SegmentRequirement` | ⏳ | | | ۱.۲ | DTO های `AppointmentPlan` · `PlannedSegment` · `PlannedRequirement` (immutable) | ⏳ | | | ۱.۳ | پنج سرویس جدا: `Builder` · `Assembler` · `DurationResolver` · `RequirementResolver` | ⏳ | نه یک کلاس بزرگ | | ۱.۴ | `build()` تابع **خالص** است — بدون write، بدون cache، بدون `time()` | ⏳ | ⭐ تسک ۰۶ رویش حساب می‌کند | | ۱.۵ | مرحلهٔ ۷ (`policies->applyToPlan`) از روز اول در امضا، حتی no-op | ⏳ | تسک ۰۹ پرش می‌کند | | ۱.۶ | ادغام: `count` **بیشینه**، نه جمع | ⏳ | | | ۱.۷ | `offset_minutes` نسبی است، نه timestamp مطلق | ⏳ | تسک ۰۶ برنامه را می‌لغزاند | | ۱.۸ | `occupancyStartOffset`/`occupancyEndOffset` جدا از offset نمایشی | ⏳ | `setup/cleanup` | | ۱.۹ | قید جنسیت بدون داده → ۴۲۲، **نه نادیده گرفتن** | ⏳ | ⭐ الزام جدی کلینیک زیبایی | | ۱.۱۰ | `constraints` فهرست بسته؛ کلید ناشناخته → ۴۲۲ | ⏳ | | | ۱.۱۱ | `NoEligibleResourceException` با پیام انسانی + `meta` | ⏳ | نقش، مهارت، شعبه | | ۱.۱۲ | سه endpoint | ⏳ | | | ۱.۱۳ | `patient_facing_minutes` جدا از `total_minutes` در پاسخ | ⏳ | بخش‌های بدون حضور بیمار | | ۱.۱۴ | سقف‌ها اعمال شد: ۲۰ بخش · ۴۸۰ دقیقه · ۱۰ نیازمندی · ۲۰ آیتم | ⏳ | | | ۱.۱۵ | `app:segment:seed-templates --preset=beauty\|dental\|physio` — dry-run | ⏳ | | | ۱.۱۶ | `TenantOwnershipChecker` روی هر uuid از request | ⏳ | | ## ۲. دیتابیس | # | مورد | وضعیت | یادداشت | |---|---|---|---| | ۲.۱ | `segment_templates` · `segment_requirements` | ⏳ | | | ۲.۲ | دقیقاً یکی از `service_item_id`/`service_option_id` — قید اپلیکیشنی | ⏳ | | | ۲.۳ | دقیقاً یکی از `fixed_minutes`/`duration_share` | ⏳ | | | ۲.۴ | جمع `duration_share` یک سرویس = ۱۰۰ (اعتبارسنجی هنگام ذخیره) | ⏳ | | | ۲.۵ | `required_skills` به‌صورت JSON با دلیل مکتوب | ⏳ | نه جدول واسط | | ۲.۶ | `segment_requirements` در `AGGREGATE_CHILDREN` | ⏳ | | | ۲.۷ | `TenantSchemaCoverageTest` سبز | ⏳ | | ## ۳. UI | # | مورد | وضعیت | یادداشت | |---|---|---|---| | ۳.۱ | `ServiceSegmentsPage` به‌عنوان زیرصفحهٔ `ServiceDetailPage` | ⏳ | | | ۳.۲ | لیست بخش‌ها با `sequence` عددی (بدون drag) | ⏳ | | | ۳.۳ | نیازمندی‌ها: نقش با `SearchableSelect`، مهارت با چیپ، اشغال با رادیو | ⏳ | | | ۳.۴ | هر گزینهٔ نوع اشغال توضیح فارسی دارد | ⏳ | انحصاری/اشتراکی/منفعل | | ۳.۵ | **نوار پیش‌نمایش زمانی** با عرض متناسب مدت و آیکن منابع | ⏳ | ⭐ تنها راه فهم کاربر غیرفنی | | ۳.۶ | خط «اپراتور واقعاً درگیر: N دقیقه» زیر نوار | ⏳ | ⭐ ارزش کار را نشان می‌دهد | | ۳.۷ | `backTo` روی صفحه | ⏳ | | | ۳.۸ | هیچ رنگ/شعاع hard-code — نوار پیش‌نمایش هم | ⏳ | | | ۳.۹ | دارک‌مود و حالت فشرده | ⏳ | | | ۳.۱۰ | RTL و موبایل — نوار پیش‌نمایش روی موبایل اسکرول افقی داخلی دارد | ⏳ | | | ۳.۱۱ | همهٔ رشته‌ها فارسی | ⏳ | | | ۳.۱۲ | `meta` خطای «هیچ منبعی» به لینک «افزودن منبع» تبدیل شد | ⏳ | بن‌بست نباشد | ## ۴. تست | # | مورد | وضعیت | یادداشت | |---|---|---|---| | ۴.۱ | `SegmentAssemblerTest` — ادغام، `count` بیشینه، غیر-mergeable | ⏳ | | | ۴.۲ | `SegmentDurationResolverTest` — fixed ثابت، سهمی مقیاس‌پذیر، جمع = total | ⏳ | | | ۴.۳ | `AppointmentPlanBuilderTest` — سناریوی کامل مستند (۰/۵/۳۵/۵۵، total=60) | ⏳ | | | ۴.۴ | `AppointmentPlanBuilderTest` — **قطعیت**: دو build یکسان → خروجی یکسان | ⏳ | | | ۴.۵ | سرویس بدون الگو → یک بخش با منبع doctor | ⏳ | ⭐ | | ۴.۶ | `RequirementResolverTest` — مهارت، هیچ کاندید، قید جنسیت، محیط دیگر | ⏳ | | | ۴.۷ | `PlanLimitsTest` — ۲۱ بخش و ۴۸۱ دقیقه → ۴۲۲ | ⏳ | | ## ۵. مستندات | # | مورد | وضعیت | یادداشت | |---|---|---|---| | ۵.۱ | `docs/api/appointment-plan.md` | ⏳ | | | ۵.۲ | جدول سه حالت اشغال و تفاوت عملی‌شان | ⏳ | | | ۵.۳ | تفاوت `offset` نمایشی با `occupancy_offset` | ⏳ | | | ۵.۴ | مثال کامل خروجی `preview` | ⏳ | | ## ۶. بازبینی پایانی | # | مورد | وضعیت | یادداشت | |---|---|---|---| | ۶.۱ | هیچ 🔄 و ⏳ بی‌دلیل نمانده | ⏳ | | | ۶.۲ | `bin/phpunit` کامل سبز | ⏳ | | | ۶.۳ | `--group=slot-mode-frozen` سبز | ⏳ | | | ۶.۴ | `phpstan` بدون خطای جدید | ⏳ | | | ۶.۵ | `npx tsc --noEmit` و `yarn test` سبز | ⏳ | | | ۶.۶ | تست‌های tenant سبز | ⏳ | | | ۶.۷ | `docs/api/*` به‌روز | ⏳ | | | ۶.۸ | چک‌لیست UI کامل | ⏳ | | | ۶.۹ | دو کلاینت دیگر بررسی شدند | ⏳ | `preview` هنوز مصرف نمی‌شود | | ۶.۱۰ | commit، سپس `graphify update .` | ⏳ | | | ۶.۱۱ | موارد به‌تعویق با دلیل و تسک مقصد | ⏳ | |