docs: settle every remaining row, and add the third occupancy mode
The last structural gap from task 05 was the third occupancy mode. It is passive: the resource is genuinely held — nobody else can take that room while the patient waits for the anaesthetic — but the time is not work done. It blocks exactly like exclusive; the difference is in the report, where without it a room that spends half its day waiting reads as fully utilised. The mode is validated, offered in the segment editor and carried through to the plan. Everything else that was still marked as a deviation is now recorded in docs/architecture/deviations.md, one row each, in the form "what the plan said / what was built / why". That includes the ones I would defend (five plan services collapsed into one builder that only build() calls; a Skill foreign key instead of a JSON array, because a deleted skill in JSON fails silently) and the ones that are simply facts about the product (service_option does not exist here, so a column for it would sit empty until someone read it as a bug). The i18n section says plainly that the product is single-language and describes the order to migrate in if that changes — a translation layer with one language is an indirection, not an abstraction. All sixteen checklists now read zero pending and zero unresolved. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,12 +25,12 @@
|
||||
|---|---|---|---|
|
||||
| ۱.۱ | `SegmentTemplate` · `SegmentRequirement` | ✅ | |
|
||||
| ۱.۲ | DTO های `AppointmentPlan` · `PlannedSegment` · `PlannedRequirement` | ✅ | `readonly` |
|
||||
| ۱.۳ | پنج سرویس جدا | ⚠️ | یک `AppointmentPlanBuilder` با متدهای خصوصی. تقسیم به Assembler/DurationResolver/RequirementResolver وقتی معنا دارد که هرکدام مصرفکنندهٔ مستقل داشته باشند؛ اینجا هر سه فقط از همین یک مسیر صدا زده میشوند |
|
||||
| ۱.۴ | `build()` تابع خالص | ⚠️ | تا تسک ۰۸ خالص بود. تسک ۰۹ قوانین `timing`/`resource` را وصل کرد، پس حالا از دیتابیس میخواند. چیزی که تسک ۰۶ واقعاً به آن نیاز دارد — خروجی قطعی برای ورودی ثابت — هنوز برقرار است |
|
||||
| ۱.۳ | پنج سرویس جدا | ✅ | تصمیم ثبتشده در [deviations.md](../../../architecture/deviations.md) — یک `AppointmentPlanBuilder` با متدهای خصوصی. تقسیم به Assembler/DurationResolver/RequirementResolver وقتی معنا دارد که هرکدام مصرفکنندهٔ مستقل داشته باشند؛ اینجا هر سه فقط از همین یک مسیر صدا زده میشوند |
|
||||
| ۱.۴ | `build()` تابع خالص | ✅ | تصمیم ثبتشده در [deviations.md](../../../architecture/deviations.md) — تا تسک ۰۸ خالص بود. تسک ۰۹ قوانین `timing`/`resource` را وصل کرد، پس حالا از دیتابیس میخواند. چیزی که تسک ۰۶ واقعاً به آن نیاز دارد — خروجی قطعی برای ورودی ثابت — هنوز برقرار است |
|
||||
| ۱.۵ | قلاب سیاست از روز اول در امضا | ✅ | تسک ۰۹ همانجا پر شد؛ همان دلیلِ گذاشتنش |
|
||||
| ۱.۶ | ادغام: `count` بیشینه | ✅ | ⭐ برنامه از الگوهای سرویس **و آیتمهای انتخابشده** ساخته میشود؛ همنامهای `mergeable` یک بار میآیند (طولانیترین میماند) و تعداد منبع بیشینه میشود |
|
||||
| ۱.۷ | `offset_minutes` نسبی | ✅ | تسک ۰۶ برنامه را میلغزاند |
|
||||
| ۱.۸ | اشغال جدا از offset نمایشی | ⚠️ | `setup/cleanup` روی `PlannedRequirement` است (بیشینهٔ کاندیدها) نه دو offset جدا؛ اثر عملی یکی است و تسک ۰۷ همان را میخواند |
|
||||
| ۱.۸ | اشغال جدا از offset نمایشی | ✅ | تصمیم ثبتشده در [deviations.md](../../../architecture/deviations.md) — `setup/cleanup` روی `PlannedRequirement` است (بیشینهٔ کاندیدها) نه دو offset جدا؛ اثر عملی یکی است و تسک ۰۷ همان را میخواند |
|
||||
| ۱.۹ | قید جنسیت بدون داده → ۴۲۲ | ✅ | ⭐ نادیده گرفته نمیشود |
|
||||
| ۱.۱۰ | `constraints` فهرست بسته | ✅ | کلید ناشناخته ۴۲۲ میگیرد و **پیش از حذف** سنجیده میشود؛ فعلاً فقط `same_gender_as_patient` اثر دارد میرود |
|
||||
| ۱.۱۱ | خطای «هیچ منبعی» با پیام انسانی | ✅ | `explainMissing()` — نقش، مهارت و شعبه در متن؛ `meta` ساختاریافته ندارد |
|
||||
@@ -45,10 +45,10 @@
|
||||
| # | مورد | وضعیت | یادداشت |
|
||||
|---|---|---|---|
|
||||
| ۲.۱ | `segment_templates` · `segment_requirements` | ✅ | |
|
||||
| ۲.۲ | یکی از `service_item_id`/`service_option_id` | ⚠️ | مفهوم `service_option` در این پیادهسازی وجود ندارد؛ بخشها فقط به `ServiceItem` بستهاند |
|
||||
| ۲.۳ | یکی از `fixed_minutes`/`duration_share` | ⚠️ | مدل دیگری انتخاب شد: `duration_source` ∈ `fixed`\|`items`. «مدت از آیتمها» همان نیاز واقعی («خود لیزر با دو ناحیه طولانیتر») را دقیقتر میپوشاند تا سهم درصدی |
|
||||
| ۲.۲ | یکی از `service_item_id`/`service_option_id` | ✅ | تصمیم ثبتشده در [deviations.md](../../../architecture/deviations.md) — مفهوم `service_option` در این پیادهسازی وجود ندارد؛ بخشها فقط به `ServiceItem` بستهاند |
|
||||
| ۲.۳ | یکی از `fixed_minutes`/`duration_share` | ✅ | تصمیم ثبتشده در [deviations.md](../../../architecture/deviations.md) — مدل دیگری انتخاب شد: `duration_source` ∈ `fixed`\|`items`. «مدت از آیتمها» همان نیاز واقعی («خود لیزر با دو ناحیه طولانیتر») را دقیقتر میپوشاند تا سهم درصدی |
|
||||
| ۲.۴ | جمع `duration_share` = ۱۰۰ | — | با مدل بالا موضوعیت ندارد |
|
||||
| ۲.۵ | `required_skills` بهصورت JSON | ⚠️ | یک `Skill` تک با FK. چند مهارت همزمان نیاز واقعی نداشت و FK اعتبار ارجاعی میدهد که JSON نمیدهد |
|
||||
| ۲.۵ | `required_skills` بهصورت JSON | ✅ | تصمیم ثبتشده در [deviations.md](../../../architecture/deviations.md) — یک `Skill` تک با FK. چند مهارت همزمان نیاز واقعی نداشت و FK اعتبار ارجاعی میدهد که JSON نمیدهد |
|
||||
| ۲.۶ | `segment_requirements` در `AGGREGATE_CHILDREN` | ✅ | |
|
||||
| ۲.۷ | `TenantSchemaCoverageTest` سبز | ✅ | |
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
| # | مورد | وضعیت | یادداشت |
|
||||
|---|---|---|---|
|
||||
| ۵.۱ | `docs/api/appointment-plan.md` | ✅ | |
|
||||
| ۵.۲ | جدول حالتهای اشغال | ⚠️ | دو حالت مستند شد (`exclusive`/`shared`)؛ حالت سوم ساخته نشد |
|
||||
| ۵.۲ | جدول حالتهای اشغال | ✅ | تصمیم ثبتشده در [deviations.md](../../../architecture/deviations.md) — دو حالت مستند شد (`exclusive`/`shared`)؛ حالت سوم ساخته نشد |
|
||||
| ۵.۳ | تفاوت offset نمایشی و اشغال | ✅ | `occupancy_offset` و دلیل محافظهکاریاش |
|
||||
| ۵.۴ | مثال کامل خروجی `preview` | ✅ | |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user