feat: implement cancellation policy, no-show tracking, and waitlist management

- Add implementation notes for cancellation and waitlist features.
- Create task documentation outlining goals, current status, and acceptance criteria for cancellation policy and resource utilization reporting.
- Establish architecture for domain events and outbox pattern to ensure reliable event publishing.
- Define database schema for domain events and necessary queries for resource utilization and plan accuracy reports.
- Implement detailed implementation notes covering edge cases, testing strategies, and documentation requirements.
This commit is contained in:
hamed
2026-07-30 11:43:58 +03:30
parent 1d338503c8
commit 021d0eb6b2
62 changed files with 8098 additions and 0 deletions
@@ -0,0 +1,76 @@
# تسک ۰۳ — تقویم منبع، استثنا، تعطیلات ملی
**فاز:** ۱ (هسته) · **وابستگی:** ۰۱، ۰۲ · **زمان:** ۱۲-۱۴ ساعت
---
## هدف
مستند بند ۹ ساعت آزاد را از کسر هفت لایه می‌سازد. امروز چهار لایه داریم و همه روی
**پزشک** سوارند. این تسک لایه‌های غایب را اضافه می‌کند و آن‌ها را روی **منبع** می‌نشاند:
```
ساعت کاری شعبه ← تسک ۰۱ ساخت، اینجا وارد محاسبه می‌شود
– شیفت منبع ← این تسک
– تعطیلات رسمی کشور ← این تسک
– مرخصی و غیبت ← این تسک
– سرویس دوره‌ای دستگاه ← این تسک (همان جدول استثنا با نوع دیگر)
– نوبت‌های ثبت‌شده ← موجود (تسک ۰۷ به resource_occupancy منتقل می‌کند)
– رزروهای موقت ← موجود
– آماده‌سازی و تمیزکاری ← تسک ۰۲ ستون‌ها را ساخت، تسک ۰۶ اعمال می‌کند
```
## وضعیت فعلی
- `WeeklySchedule` — JSON هفتگی per `(doctor, clinic)` با `sessions[]`
- `DateOverride` — تنظیم یک روز خاص per `(doctor, clinic)`
- `Holiday` — بازهٔ تعطیلی per `(doctor, clinic)`، دستی
- جدول تعطیلات رسمی کشور **وجود ندارد**؛ هر پزشک باید دستی ثبت کند
## دامنه
**هست:** `ResourceCalendar` (شیفت تکرارشوندهٔ منبع)، `ResourceException` (مرخصی، غیبت،
سرویس دوره‌ای، تعطیلی موردی)، `NationalHoliday` (جدول کشوری با import شمسی) و
`TenantHolidayOverride` (کلینیکی که پنجشنبه کار می‌کند)، و یک سرویس واحد
`ResourceAvailabilityService` که «ساعت آزاد یک منبع در یک بازه» را می‌دهد.
**نیست:** تقاطع چند منبع و برنامهٔ چندبخشی (تسک ۰۶)، ثبت اشغال (تسک ۰۷).
## Endpoint ها
| متد | مسیر | توضیح |
|---|---|---|
| GET | `/api/v1/resource/{uuid}/calendar` | شیفت‌های هفتگی منبع |
| PUT | `/api/v1/resource/{uuid}/calendar` | جایگزینی کامل شیفت‌ها |
| GET | `/api/v1/resource/{uuid}/exceptions` | مرخصی/سرویس، با فیلتر بازه |
| POST | `/api/v1/resource/{uuid}/exception` | ثبت استثنا |
| PATCH/DELETE | `/api/v1/resource-exception/{uuid}` | |
| GET | `/api/v1/resource/{uuid}/availability?from&to` | ساعت آزاد خام (بدون نوبت) — برای پنل |
| GET | `/api/v1/national-holidays?year=1405` | تعطیلات رسمی سال |
| POST | `/api/v1/holiday-overrides` | تغییر تعطیلی رسمی توسط محیط |
| DELETE | `/api/v1/holiday-override/{uuid}` | |
## معیار پذیرش
- ✅ موفق: منبع «اپراتور مریم» شیفت شنبه تا چهارشنبه ۹:۰۰-۱۷:۰۰ می‌گیرد →
`GET /resource/{uuid}/availability?from=…&to=…` پنج بازه برمی‌گرداند و جمعه خالی است.
- ✅ موفق: مرخصی سه‌شنبه ثبت می‌شود → همان endpoint سه‌شنبه را خالی می‌دهد.
- ✅ موفق: تعطیل رسمی ۱۳ فروردین در `national_holidays` هست → آن روز برای همهٔ منابع
همهٔ محیط‌ها خالی است، بدون هیچ ثبت دستی.
- ✅ موفق: کلینیکی که پنجشنبه کار می‌کند یک `holiday_override` با `is_working=true` ثبت
می‌کند → فقط منابع همان محیط پنجشنبه باز می‌شوند.
- ❌ خطا: شیفت با `end_minute <= start_minute``422`.
- ❌ خطا: استثنا با `end < start``422`؛ استثنا روی منبع محیط دیگر → `404`.
- ⚠️ مرزی: شیفت منبع بیرون از ساعت کاری شعبه → **تقاطع** گرفته می‌شود، نه رد. اگر تقاطع
خالی شد، پاسخ `availability` آن روز را خالی می‌دهد و دلیل `outside_branch_hours` را
برمی‌گرداند.
- ⚠️ مرزی: شعبهٔ بدون ساعت کاری → شیفت منبع بی‌قید اعمال می‌شود (سازگاری با داده‌های موجود).
- ⚠️ مرزی: استثنای نیم‌روزه (۱۴:۰۰ تا ۱۸:۰۰) → فقط همان بازه کسر می‌شود، نه کل روز.
- ⚠️ مرزی: دو استثنای هم‌پوشان → مجاز، اتحاد گرفته می‌شود.
## خروجی
- `src/Resource/Calendar/` + `src/Resource/Service/ResourceAvailabilityService.php`
- صفحات: `ResourceCalendarPage.tsx`, `ResourceExceptionsPage.tsx`, `HolidaysSettingsPage.tsx`
- `docs/api/resource-calendar.md`
- دستور `app:holiday:import --year=1405` برای بارگذاری تعطیلات رسمی