feat(treatment): select treatment behaviour by practice domain, not by if-branch
Everything that differs between specialties as data is already stored as data. What is left is behaviour — when a case opens, what happens once a session ends — so it becomes a TreatmentWorkflow resolved through a tagged-service registry. The booking path calls one collaborator and never names a specialty; adding dentistry is a new class, not an edit to confirmation. A clinic that has chosen no practice domain still gets working multi-session courses: DefaultTreatmentWorkflow answers for null and for any code without a dedicated implementation, keeping "unset means behave as today, not error". LaserTreatmentWorkflow is deliberately empty beyond claiming `beauty` — it is the seam where laser-specific behaviour will land without disturbing anyone else. Session due dates are anchored to the previous session's actual finish, so a patient who comes twenty days late shifts the rest of their course instead of getting the next session while it can still do nothing. Only the next session is recomputed; later ones keep their estimate because they are anchored to nothing yet. Attachment targets the first session without an appointment rather than the first open one: a patient booking again mid-course was otherwise matched to the session that already had a booking, and the second appointment went nowhere. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,12 +31,18 @@ be able to switch them back on.
|
||||
"code": "beauty",
|
||||
"name": "کلینیک زیبایی",
|
||||
"sort_order": 0,
|
||||
"active": true
|
||||
"active": true,
|
||||
"has_workflow": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`has_workflow` میگوید آیا پیادهسازیِ `TreatmentWorkflow` مخصوصِ این کد ثبت شده یا حوزه
|
||||
فقط رفتار پیشفرض میگیرد. حوزهٔ بیworkflow کار میکند — دورههای چندجلسهایاش باز
|
||||
میشوند — ولی رفتار اختصاصی ندارد، و پنل ادمین پلتفرم باید همین را نشان دهد نه اینکه
|
||||
مدیر حدس بزند.
|
||||
|
||||
**Errors:**
|
||||
| Code | HTTP | توضیح |
|
||||
|------|------|-------|
|
||||
|
||||
@@ -130,6 +130,49 @@ Real 422 responses:
|
||||
|
||||
---
|
||||
|
||||
## Opening a case — what happens on confirm
|
||||
|
||||
There is no endpoint that opens a treatment case; it happens as a side effect of confirming an
|
||||
appointment, in `AppointmentConfirmationService::onConfirmed`:
|
||||
|
||||
```
|
||||
نوبت تأیید شد
|
||||
→ PatientSession ساخته میشود (مالی، مثل همیشه)
|
||||
→ اگر سرویسِ نوبت پروتکل فعال دارد:
|
||||
TreatmentWorkflowRegistry::for(clinic.practice_domain.code)->openCase(...)
|
||||
```
|
||||
|
||||
The booking core never names a specialty. A `TreatmentWorkflow` is selected by the clinic's practice
|
||||
domain code through a tagged-service registry, so adding dentistry is a new class rather than a
|
||||
change in the booking path. `LaserTreatmentWorkflow` handles `beauty`;
|
||||
`DefaultTreatmentWorkflow` answers for everything else, including a clinic that has chosen no domain
|
||||
at all — `null` means "behave as today", never an error.
|
||||
|
||||
What opening a case does:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| پروندهٔ باز موجود | برگردانده میشود؛ پروندهٔ دوم برای همان بیمار و همان سرویس ساخته نمیشود |
|
||||
| نواحی | برگهای دستهٔ سرویس، با نامشان، در همان لحظه کپی میشوند |
|
||||
| جلسات | همهٔ گامهای پروتکل ساخته میشوند، همه `planned` |
|
||||
| نوبت | به **اولین جلسهٔ بدون نوبت** میچسبد و آن جلسه `booked` میشود |
|
||||
| سررسید | جلسهٔ رزروشده ساعت نوبت را میگیرد؛ بقیه `null` میمانند |
|
||||
|
||||
Failure to open a case is logged and swallowed — the appointment is booked and possibly paid for, and
|
||||
losing that is worse than losing the case file, which can be rebuilt.
|
||||
|
||||
### Session due dates
|
||||
|
||||
`due_at` of session *n* is `finished_at` of session *n−1* plus that step's `offset_days`. Only the
|
||||
**next** session is recomputed when one finishes; sessions further out keep their earlier estimate,
|
||||
because a number that is not yet anchored to anything real does not get more accurate by being
|
||||
recalculated.
|
||||
|
||||
A no-show does not burn the session: its status becomes `no_show`, its appointment link is cleared,
|
||||
`total_sessions` is untouched, and the same session comes back to the front of the booking queue.
|
||||
|
||||
---
|
||||
|
||||
## DELETE `/api/v1/service-item/{uuid}/treatment-protocol`
|
||||
|
||||
Turn the switch off — the protocol, its steps and its staff list are removed and the service is
|
||||
|
||||
Reference in New Issue
Block a user