Files
clinicpro/docs/new_feture/taskes/task-01-branch-room/task.md
T
hamed 021d0eb6b2 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.
2026-07-30 11:43:58 +03:30

62 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# تسک ۰۱ — شعبه (Branch) و اتاق (Room)
**فاز:** ۱ (هسته) · **وابستگی:** — · **زمان:** ۱۰-۱۲ ساعت
---
## هدف
سطح سوم مکان را به مدل اضافه کن: امروز `(entity_type, entity_id)` می‌گوید داده مال کدام
محیط است، ولی نمی‌گوید در کدام **ساختمان** و کدام **اتاق**. مستند بند ۴ سه سطح می‌خواهد
و «منابع همیشه مال شعبه‌اند چون فیزیکی‌اند» — بدون شعبه، تسک ۰۲ جایی برای نشستن ندارد.
## وضعیت فعلی
- محل مراجعه امروز `DoctorAddress` است و `location_id` هر شیفت در
`WeeklySchedule.setting[day].sessions[].location_id` به `doctor_addresses.id` اشاره می‌کند
(`SlotCalculatorService::buildSessionSlots()` آن را در هر اسلات کپی می‌کند).
- `Clinic` هیچ فیلد شعبه‌ای ندارد؛ یک آدرس متنی تخت دارد.
- ساعت کاری شعبه وجود ندارد — ساعت کاری فقط روی برنامهٔ پزشک است.
## دامنه
**هست:** entity های `Branch` و `Room`، ساعت کاری هفتگی شعبه، CRUD پنل ادمین،
پل زدن `DoctorAddress.branch_id` برای اینکه شیفت‌های موجود بدون تغییر به شعبه نگاشت شوند.
**نیست:** استفاده از شعبه در محاسبهٔ اسلات (تسک ۰۳)، اتاق به‌عنوان منبع قابل رزرو (تسک ۰۲).
## Endpoint ها
| متد | مسیر | توضیح |
|---|---|---|
| GET | `/api/v1/branches` | لیست شعب محیط جاری (paginated) |
| POST | `/api/v1/branch` | ساخت شعبه |
| GET | `/api/v1/branch/{uuid}` | جزئیات + ساعت کاری |
| PATCH | `/api/v1/branch/{uuid}` | ویرایش |
| DELETE | `/api/v1/branch/{uuid}` | حذف (فقط بدون منبع/اتاق فعال) |
| PUT | `/api/v1/branch/{uuid}/working-hours` | ثبت ساعت کاری هفتگی |
| GET | `/api/v1/branch/{uuid}/rooms` | اتاق‌های شعبه |
| POST/PATCH/DELETE | `/api/v1/room[/{uuid}]` | CRUD اتاق |
## معیار پذیرش
- ✅ موفق: کلینیک با توکن مالک `POST /api/v1/branch` می‌زند → `201` و شعبه با
`entity_type=clinic, entity_id=<id>` ثبت می‌شود. `GET /api/v1/branches` همان را برمی‌گرداند.
- ✅ موفق: `PUT /branch/{uuid}/working-hours` با هفت روز → `200`؛ `GET /branch/{uuid}` همان
ساختار را با کلیدهای `0..6` (۰=شنبه) برمی‌گرداند.
- ❌ خطا: کلینیک B با uuid شعبهٔ کلینیک A → `404` با `ERR_NOT_FOUND_001` (نه ۴۰۳ — طبق
رفتار `TenantFilter`).
- ❌ خطا: `DELETE` شعبه‌ای که اتاق فعال دارد → `422` با پیام فارسی «شعبه دارای اتاق فعال است».
- ⚠️ مرزی: پزشک مستقل (محیط `doctor`) هم می‌تواند شعبه بسازد — «مطب» یک شعبه است.
اولین شعبه از روی `DoctorAddress` موجود ساخته می‌شود، نه دستی.
- ⚠️ مرزی: ساعت کاری با `end_time <= start_time``422`.
- ⚠️ مرزی: شعبه بدون ساعت کاری معتبر است (وراثت: تسک ۰۳ آن را «همیشه باز» تفسیر نمی‌کند،
«تعریف‌نشده» تفسیر می‌کند).
## خروجی
- `src/Branch/` کامل با تست
- `assets/admin/pages/BranchesPage.tsx` + `BranchFormPage.tsx` + `RoomsPage.tsx`
- `docs/api/branch.md`
- migration + دستور `app:branch:backfill` برای ساخت شعبهٔ اولیه از آدرس‌های موجود