- 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.
96 lines
4.9 KiB
Markdown
96 lines
4.9 KiB
Markdown
# نکات پیادهسازی — تسک ۰۱
|
||
|
||
## ۱. چرا شعبه بالای آدرس مینشیند، نه جای آن
|
||
|
||
سه مصرفکنندهٔ زنده به `doctor_addresses.id` وابستهاند:
|
||
|
||
1. `WeeklySchedule.setting[day].sessions[].location_id` (JSON)
|
||
2. `SlotCalculatorService::buildSessionSlots()` که آن را در هر اسلات کپی میکند
|
||
3. `AppointmentController::bookingLocations()` که به سایت عمومی `location_uuid` میدهد
|
||
|
||
عوض کردن این قرارداد در build هیچکدام از سه ریپو خطا نمیدهد — فقط در runtime آدرس گم میشود.
|
||
پس `branch_id` روی آدرس اضافه میشود و آدرس همانجا میماند.
|
||
|
||
## ۲. پزشک مستقل هم شعبه دارد
|
||
|
||
وسوسه میشود که شعبه را فقط برای `entity_type=clinic` بسازیم. نکن. اگر پزشک مستقل شعبه
|
||
نداشته باشد، تسک ۰۲ باید دو مسیر کد برای «منبع مال شعبه» و «منبع مال پزشک» داشته باشد و
|
||
تسک ۰۶ هر دو را جدا حساب کند. مطب شخصی = شعبهای با `entity_type=doctor`.
|
||
|
||
## ۳. حذف شعبه
|
||
|
||
هرگز `CASCADE` روی حذف شعبه به منابع و نوبتها نده. `DELETE` فقط وقتی مجاز است که:
|
||
|
||
- هیچ `Room` فعالی نداشته باشد، **و**
|
||
- هیچ `Resource` فعالی (تسک ۰۲) نداشته باشد، **و**
|
||
- هیچ نوبت آیندهٔ فعالی روی منابعش نباشد (تسک ۰۷)
|
||
|
||
تا آن تسکها نیامدهاند، فقط شرط اول را چک کن ولی سرویس را طوری بنویس که افزودن دو شرط
|
||
بعدی یک خط باشد (لیست `DeletionGuardInterface` و تزریق آرایهای از گاردها).
|
||
|
||
`active=false` مسیر اصلی است، نه `DELETE`.
|
||
|
||
## ۴. ساعت کاری — دقیقه، نه رشته
|
||
|
||
```php
|
||
// ❌ اشتباه: مقایسهٔ رشتهای در تسک ۰۶ میشکند ("9:00" < "10:00" غلط است)
|
||
private string $startTime = '09:00';
|
||
|
||
// ✅ درست
|
||
private int $startMinute = 540;
|
||
```
|
||
|
||
اعتبارسنجی در `WorkingHoursService`:
|
||
- `0 <= start < end <= 1440`
|
||
- بازههای یک روز نباید همپوشانی داشته باشند (مرتب کن، بعد `prev.end <= next.start`)
|
||
- `sequence` را خود سرویس بعد از مرتبسازی تخصیص میدهد، نه کلاینت
|
||
|
||
## ۵. تفسیر «شعبه بدون ساعت کاری»
|
||
|
||
تصمیم صریح: **تعریفنشده، نه همیشهباز.** تسک ۰۳ وقتی برای شعبهای ساعتی پیدا نکرد، به
|
||
رفتار فعلی برمیگردد (برنامهٔ پزشک تنها مرجع است). این باعث میشود همهٔ دادههای موجود
|
||
بدون ساعت کاری شعبه دقیقاً مثل امروز کار کنند.
|
||
|
||
این نکته را در `docs/api/branch.md` بنویس، وگرنه اولین کسی که کش را دیباگ میکند فکر میکند
|
||
باگ است.
|
||
|
||
## ۶. edge case ها
|
||
|
||
| حالت | رفتار درست |
|
||
|---|---|
|
||
| شعبه در محیط A، اتاق ساختهشده با uuid شعبهٔ محیط B | `404` — `TenantOwnershipChecker::belongsTo` قبل از هر کاری |
|
||
| دو شعبه همنام در یک محیط | مجاز (نام یکتا نیست؛ آدرس فرق دارد) |
|
||
| `capacity = 0` | `422` — حداقل ۱ |
|
||
| ساعت کاری روز جمعه خالی | معتبر — یعنی شعبه جمعه بسته است |
|
||
| شعبهای که تنها شعبهٔ محیط است و غیرفعال میشود | مجاز، ولی هشدار در UI: «هیچ شعبهٔ فعالی باقی نمیماند» |
|
||
| ساعت شبانهروزی | `start=0, end=1440` — نه دو ردیف |
|
||
|
||
## ۷. تست
|
||
|
||
```
|
||
tests/Branch/BranchCrudTest.php
|
||
- ساخت شعبه با نقش مالک کلینیک → 201 و tenant درست
|
||
- ساخت با نقش منشیِ بدون محیط انتخابشده → 403
|
||
- دیدن شعبهٔ محیط دیگر → 404 (نه 403)
|
||
tests/Branch/WorkingHoursTest.php
|
||
- هفت روز معتبر → 200 و بازخوانی یکسان
|
||
- end <= start → 422
|
||
- دو بازهٔ همپوشان در یک روز → 422
|
||
- بازهٔ شبانهروزی 0..1440 → 200
|
||
tests/Branch/BranchDeletionTest.php
|
||
- حذف شعبهٔ دارای اتاق فعال → 422
|
||
- حذف شعبهٔ خالی → 204
|
||
tests/Shared/TenantSchemaCoverageTest.php ← باید سبز بماند
|
||
```
|
||
|
||
اجرا:
|
||
```bash
|
||
ddev exec php bin/phpunit tests/Branch
|
||
ddev exec php vendor/bin/phpstan analyse src/Branch
|
||
```
|
||
|
||
## ۸. مستندات
|
||
|
||
`docs/api/branch.md` بساز (الگو: `docs/api/staff.md`). در `docs/api/README.md` هم اضافه کن.
|
||
در `docs/architecture/tenancy.md` جدول طبقهبندی را با سه جدول جدید بهروز کن.
|