# چک‌لیست — تسک ۰۳ (تقویم منبع، استثنا، تعطیلات ملی)

**وضعیت کلی:** ⏳ شروع نشده · **آخرین بازبینی:** —

قواعد: [_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` **هیچ** تغییری نکرد | ⏳ | `ResourceAvailabilityService` سرویس موازی است |
| ۰.۳ | `WeeklySchedule` · `DateOverride` · `Holiday` موجود دست‌نخورده | ⏳ | |
| ۰.۴ | `HolidayResolver` به مسیر اسلاتی **وصل نشد** | ⏳ | تغییر رفتاری است؛ تسک جدا با تأیید محصول |

## ۱. `IntervalSet` — اول از همه

| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۱.۱ | `src/Shared/Time/IntervalSet.php` ساخته شد **پیش از** entity ها | ⏳ | |
| ۱.۲ | قرارداد نیم‌باز `[start, end)` همه‌جا | ⏳ | |
| ۱.۳ | `IntervalSetTest` — هفت حالت مرزی سند | ⏳ | واحد، بدون DB |
| ۱.۴ | هر جای دیگری که بازه جمع/کم می‌کند از همین استفاده می‌کند | ⏳ | نه پیاده‌سازی دوم |

## ۲. بک‌اند

| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۲.۱ | `ResourceCalendar` · `ResourceException` | ⏳ | |
| ۲.۲ | `NationalHoliday` · `TenantHolidayOverride` | ⏳ | |
| ۲.۳ | `ResourceAvailabilityService::rawWindows()` + `explainEmptyDay()` | ⏳ | پنج دلیل خالی‌بودن |
| ۲.۴ | `HolidayResolver::isClosedFor()` — تنها نقطهٔ ترکیب | ⏳ | |
| ۲.۵ | ترتیب تعطیلی: ملی + override محیط؛ منبع فقط می‌بندد نه باز می‌کند | ⏳ | |
| ۲.۶ | شعبهٔ بدون ساعت کاری = بی‌قید، **نه بسته** | ⏳ | همان تصمیم تسک ۰۱ |
| ۲.۷ | `union` استثناها بعد `subtract` — نه کسر پشت‌سرهم | ⏳ | |
| ۲.۸ | تبدیل روز هفته `(w+1)%7` عیناً مثل `SlotCalculatorService:359` | ⏳ | دو قرارداد = باگ قطعی |
| ۲.۹ | `DateTimeZone` صریح از `branch.timezone`، نه `date()` خالی | ⏳ | |
| ۲.۱۰ | نُه endpoint | ⏳ | |
| ۲.۱۱ | `app:holiday:import --year=` — idempotent | ⏳ | |
| ۲.۱۲ | `app:resource:calendar:backfill` از `WeeklySchedule` — dry-run | ⏳ | |

## ۳. کارایی

| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۳.۱ | `rawWindows` برای ۹۰ روز **دقیقاً ۵ کوئری** | ⏳ | |
| ۳.۲ | `AvailabilityQueryCountTest` عدد را قفل می‌کند | ⏳ | وگرنه اولین refactor می‌شکند |
| ۳.۳ | هیچ کوئری داخل حلقهٔ روز | ⏳ | |
| ۳.۴ | `idx_rex_resource_range` ساخته شد | ⏳ | |

## ۴. دیتابیس

| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۴.۱ | چهار جدول | ⏳ | |
| ۴.۲ | `valid_from`/`valid_to` روی شیفت از روز اول | ⏳ | شیفت فصلی |
| ۴.۳ | نوع `blocked` در استثناها هست | ⏳ | تفکیک از مرخصی برای گزارش تسک ۱۴ |
| ۴.۴ | `national_holidays` در `GlobalTables::ENTITIES` با دلیل | ⏳ | |
| ۴.۵ | `resource_calendars` در `AGGREGATE_CHILDREN` | ⏳ | |
| ۴.۶ | `TenantSchemaCoverageTest` سبز | ⏳ | |

## ۵. UI

| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۵.۱ | `ResourceCalendarPage` · `ResourceExceptionsPage` · `HolidaysSettingsPage` | ⏳ | |
| ۵.۲ | گرید هفت‌روزه با فرم ساده (بدون drag) | ⏳ | |
| ۵.۳ | بازهٔ تاریخ با `PersianDatePicker` | ⏳ | |
| ۵.۴ | `backTo`/`BackButton` روی هر سه | ⏳ | |
| ۵.۵ | تعطیلات سال با تیک «ما این روز کار می‌کنیم» | ⏳ | |
| ۵.۶ | هیچ رنگ/شعاع hard-code | ⏳ | |
| ۵.۷ | دارک‌مود و حالت فشرده | ⏳ | |
| ۵.۸ | RTL و موبایل | ⏳ | |
| ۵.۹ | دلیل خالی‌بودن روز با پیام فارسی نمایش داده می‌شود | ⏳ | پنج حالت |

## ۶. تست

| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۶.۱ | `IntervalSetTest` | ⏳ | |
| ۶.۲ | `ResourceCalendarTest` — `end<=start`، هم‌پوشانی، شیفت شبانه → ۴۲۲ | ⏳ | |
| ۶.۳ | `ResourceAvailabilityTest` — تقاطع، شعبهٔ بی‌ساعت، نیم‌روزه، دو استثنای هم‌پوشان | ⏳ | |
| ۶.۴ | `AvailabilityQueryCountTest` | ⏳ | |
| ۶.۵ | `HolidayResolverTest` — ملی، override دو جهت | ⏳ | |
| ۶.۶ | `ImportNationalHolidaysTest` — idempotent | ⏳ | |
| ۶.۷ | بازهٔ > ۹۰ روز → ۴۲۲ | ⏳ | |

## ۷. مستندات

| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۷.۱ | `docs/api/resource-calendar.md` | ⏳ | |
| ۷.۲ | `docs/api/appointment-settings.md` بخش «تفاوت با تقویم منبع» | ⏳ | دو سیستم قاطی نشوند |
| ۷.۳ | تصمیم «شیفت شبانه پشتیبانی نمی‌شود» مکتوب | ⏳ | |

## ۸. بازبینی پایانی

| # | مورد | وضعیت | یادداشت |
|---|---|---|---|
| ۸.۱ | هیچ 🔄 و ⏳ بی‌دلیل نمانده | ⏳ | |
| ۸.۲ | `bin/phpunit` کامل سبز | ⏳ | |
| ۸.۳ | `--group=slot-mode-frozen` سبز | ⏳ | |
| ۸.۴ | `phpstan` بدون خطای جدید | ⏳ | |
| ۸.۵ | `npx tsc --noEmit` و `yarn test` سبز | ⏳ | |
| ۸.۶ | تست‌های tenant سبز | ⏳ | |
| ۸.۷ | `docs/api/*` به‌روز | ⏳ | |
| ۸.۸ | چک‌لیست UI کامل | ⏳ | |
| ۸.۹ | دو کلاینت دیگر بررسی شدند | ⏳ | |
| ۸.۱۰ | commit، سپس `graphify update .` | ⏳ | |
| ۸.۱۱ | موارد به‌تعویق با دلیل و تسک مقصد | ⏳ | اتصال `HolidayResolver` به مسیر اسلاتی |
