- 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.6 KiB
Markdown
96 lines
4.6 KiB
Markdown
# دیتابیس — تسک ۰۵
|
||
|
||
## `segment_templates`
|
||
|
||
| ستون | نوع | توضیح |
|
||
|---|---|---|
|
||
| `id` | INT PK AI | |
|
||
| `uuid` | VARCHAR(36) UNIQUE | از request میآید |
|
||
| `entity_type` / `entity_id` | VARCHAR(10) / INT NOT NULL | |
|
||
| `owner_type` | VARCHAR(10) NOT NULL | `service` \| `option` |
|
||
| `service_item_id` | INT NULL | FK → `service_items.id` ON DELETE CASCADE |
|
||
| `service_option_id` | INT NULL | FK → `service_options.id` ON DELETE CASCADE |
|
||
| `name` | VARCHAR(150) NOT NULL | |
|
||
| `segment_type` | VARCHAR(40) NOT NULL | کلید ادغام |
|
||
| `sequence` | SMALLINT NOT NULL | |
|
||
| `fixed_minutes` | SMALLINT NULL | |
|
||
| `duration_share` | SMALLINT NULL | درصد ۰..۱۰۰ |
|
||
| `patient_present` | TINYINT(1) NOT NULL DEFAULT 1 | |
|
||
| `mergeable` | TINYINT(1) NOT NULL DEFAULT 0 | |
|
||
| `active` | TINYINT(1) NOT NULL DEFAULT 1 | |
|
||
| `created_at`/`updated_at` | INT NOT NULL | |
|
||
|
||
```sql
|
||
KEY idx_seg_tpl_tenant (entity_type, entity_id, active)
|
||
KEY idx_seg_tpl_service (service_item_id, sequence)
|
||
KEY idx_seg_tpl_option (service_option_id, sequence)
|
||
```
|
||
|
||
قیدهای اپلیکیشنی (در سازنده/سرویس، نه `CHECK`):
|
||
- دقیقاً یکی از `service_item_id` / `service_option_id` غیر-NULL و با `owner_type` سازگار
|
||
- دقیقاً یکی از `fixed_minutes` / `duration_share` غیر-NULL
|
||
- جمع `duration_share` بخشهای یک سرویس = ۱۰۰ (اگر حداقل یکی سهمی باشد)
|
||
|
||
## `segment_requirements`
|
||
|
||
| ستون | نوع | توضیح |
|
||
|---|---|---|
|
||
| `id` | INT PK AI | |
|
||
| `uuid` | VARCHAR(36) UNIQUE | |
|
||
| `segment_template_id` | INT NOT NULL | FK ON DELETE CASCADE |
|
||
| `resource_type_id` | INT NOT NULL | FK → `resource_types.id` ON DELETE RESTRICT |
|
||
| `count` | SMALLINT NOT NULL DEFAULT 1 | |
|
||
| `resource_pool_id` | INT NULL | FK → `resource_pools.id` ON DELETE SET NULL |
|
||
| `specific_resource_id` | INT NULL | FK → `clinic_resources.id` ON DELETE SET NULL |
|
||
| `required_skills` | JSON NULL | آرایهٔ `skill_id` |
|
||
| `constraints` | JSON NULL | فهرست بسته — جدول architecture |
|
||
| `occupancy` | VARCHAR(10) NOT NULL DEFAULT 'exclusive' | `exclusive`\|`shared`\|`passive` |
|
||
| `sort_order` | SMALLINT NOT NULL DEFAULT 0 | |
|
||
|
||
```sql
|
||
KEY idx_seg_req_segment (segment_template_id, sort_order)
|
||
KEY idx_seg_req_pool (resource_pool_id)
|
||
```
|
||
|
||
فرزند aggregate با ریشهٔ `SegmentTemplate` — uuid از request فقط در
|
||
`PUT /segment-template/{uuid}/requirements` میآید که خودش از ریشه لنگر میخورد،
|
||
پس ستون tenant لازم ندارد.
|
||
|
||
> `required_skills` عمداً JSON است نه جدول واسط: همیشه کامل خوانده و کامل جایگزین میشود،
|
||
> و هیچ کوئریای از سمت مهارت به نیازمندی نمیرود. جدول واسط اینجا فقط سه JOIN اضافه
|
||
> به مسیر داغ تسک ۰۶ میآورد.
|
||
|
||
## هیچ جدول جدیدی برای «برنامهٔ ساختهشده» نیست
|
||
|
||
`AppointmentPlan` یک DTO درونحافظهای است، نه entity. ذخیرهاش وقتی معنی پیدا میکند که
|
||
نوبت ثبت شود — که کار تسک ۰۷ است (`appointment_segments`).
|
||
|
||
دلیل: برنامه یک تابع خالص از (سرویس، آیتمها، بیمار، شعبه، قوانین فعال) است. ذخیرهکردنش
|
||
پیش از ثبت یعنی نگهداشتن حالت موقتی که باید منقضی شود — همان مسئلهای که رزرو موقت
|
||
تسک ۰۷ حل میکند و دو مکانیزم موازی لازم نیست.
|
||
|
||
## Migration
|
||
|
||
```bash
|
||
ddev exec php bin/console doctrine:migrations:diff --no-interaction
|
||
ddev exec php bin/console doctrine:migrations:migrate --no-interaction
|
||
ddev exec php bin/console app:segment:seed-templates --preset=beauty --tenant=clinic:12 --force
|
||
```
|
||
|
||
`app:segment:seed-templates` سه پریست دارد (مستند بند ۱۷: «الگوی آماده برای هر نوع کلینیک»):
|
||
|
||
| پریست | بخشها |
|
||
|---|---|
|
||
| `beauty` | آمادهسازی ۵ · انتظار ۳۰ (فقط اتاق) · درمان (سهمی ۱۰۰) · مراقبت ۵ |
|
||
| `dental` | آمادهسازی ۵ · درمان (سهمی ۱۰۰) · تمیزکاری یونیت ۱۰ (بدون حضور بیمار) |
|
||
| `physio` | درمان (سهمی ۱۰۰) |
|
||
|
||
dry-run پیشفرض. پریستها روی سرویسهای موجود اعمال نمیشوند مگر با `--service=<uuid>`.
|
||
|
||
## طبقهبندی tenant
|
||
|
||
| جدول | وضعیت |
|
||
|---|---|
|
||
| `segment_templates` | جفت tenant |
|
||
| `segment_requirements` | `AGGREGATE_CHILDREN` → ریشه `SegmentTemplate` |
|