feat: implement service mode completion for nobat724_front
- Add task for completing service mode in clinicpro with detailed objectives and acceptance criteria. - Create architecture documentation for task 00b, outlining involved components and necessary changes. - Develop checklist for task 00b to ensure all requirements are met. - Document implementation notes for task 00b, emphasizing API contract checks and design system adherence. - Update task documentation for task 00b, specifying goals and current issues with service mode.
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
# دیتابیس — تسک ۰۰
|
||||
|
||||
## تغییر `appointments` — دو ستون تهیپذیر
|
||||
|
||||
```sql
|
||||
ALTER TABLE appointments
|
||||
ADD COLUMN service_total_minutes SMALLINT NULL,
|
||||
ADD COLUMN service_buffer_minutes SMALLINT NULL;
|
||||
```
|
||||
|
||||
| ستون | معنی | چرا لازم است |
|
||||
|---|---|---|
|
||||
| `service_total_minutes` | مدت محاسبهشدهٔ ترکیب سرویسها در لحظهٔ ثبت | `slot_end - slot_start` عدد را دارد ولی نمیگوید عمدی بود یا دستی؛ و برای نوبت رزرو (که `slot_start = slot_end`) هیچجا مدت را نگه نمیداریم |
|
||||
| `service_buffer_minutes` | `buffer_minutes` مؤثر در لحظهٔ ثبت | تغییر بافر در تنظیمات نباید معنای نوبتهای ثبتشده را عوض کند |
|
||||
|
||||
هر دو **تهیپذیر** و هر دو در حالت اسلاتی `NULL` میمانند. هیچ ستون موجودی حذف، تغییر
|
||||
نوع یا تغییر معنا نمیدهد.
|
||||
|
||||
⛔ `slot_start` و `slot_end` و `active_slot_key` و `is_reserve` دستنخورده. خط سرخ.
|
||||
|
||||
### چرا نه یک ستون JSON
|
||||
|
||||
وسوسه: یک `service_meta JSON` با همهچیز. رد شد چون تسک ۱۴ (گزارش دقت برنامه) روی
|
||||
`plan_total_minutes` تجمعی میزند و JSON را نمیتواند `AVG` کند. دو ستون `SMALLINT`
|
||||
ارزانترند و تسک ۰۷ ستون `plan_total_minutes` را کنارشان اضافه میکند
|
||||
(اسم متفاوت، معنی متفاوت: آن یکی مدت برنامهٔ چندبخشی است).
|
||||
|
||||
## ایندکس
|
||||
|
||||
هیچ ایندکس جدیدی. `idx_appointments_doctor_slot` و `idx_appointments_tenant_slot` موجود
|
||||
همهٔ کوئریهای این تسک را پوشش میدهند.
|
||||
|
||||
## `appointment_service_items` — بدون تغییر schema
|
||||
|
||||
جدول واسط ManyToMany موجود. تنها تغییر، **رفتاری** است:
|
||||
|
||||
```php
|
||||
// Appointment — متد جدید، بدون دست زدن به متدهای موجود
|
||||
/** جایگزینی کامل سرویسها؛ serviceItem تکی هم با اولی همگام میشود. */
|
||||
public function replaceServiceItems(array $items): self
|
||||
{
|
||||
$this->serviceItems->clear();
|
||||
foreach ($items as $item) {
|
||||
if (!$this->serviceItems->contains($item)) { $this->serviceItems->add($item); }
|
||||
}
|
||||
$this->serviceItem = $items[0] ?? null; // ← سازگاری با مصرفکنندهٔ تکی
|
||||
$this->updatedAt = time();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return string[] uuid سرویسهای فعلی، به ترتیب */
|
||||
public function currentServiceUuids(): array
|
||||
{
|
||||
$uuids = array_map(fn($i) => $i->getUuid(), $this->serviceItems->toArray());
|
||||
if ($uuids === [] && $this->serviceItem !== null) { $uuids = [$this->serviceItem->getUuid()]; }
|
||||
return $uuids;
|
||||
}
|
||||
```
|
||||
|
||||
همگامسازی `serviceItem` تکی اجباری است: `AppointmentsPage`، `ReserveAppointmentsPage`،
|
||||
`nobat724_front` و `clinic-pro-tauri` هر چهار روی `service_item` تکی خواندهاند. رهاکردنش
|
||||
یعنی نوبت با سرویسهای جدید ولی نام سرویس قدیمی در لیست.
|
||||
|
||||
## کدهای خطای جدید
|
||||
|
||||
در `src/Shared/Constant/ErrorCodes.php`:
|
||||
|
||||
```php
|
||||
public const ERR_SERVICE_DURATION_MISMATCH = 'ERR_APPOINTMENT_010';
|
||||
// پیام: مدت این نوبت با مجموع مدت سرویسهای انتخابی نمیخواند
|
||||
|
||||
public const ERR_WRONG_BOOKING_MODE = 'ERR_APPOINTMENT_011';
|
||||
// پیام: این عملیات با روش نوبتدهی این محیط سازگار نیست
|
||||
```
|
||||
|
||||
شمارهٔ بعدی دامنهٔ `APPOINTMENT` را از خود فایل بگیر، این دو عدد حدسیاند.
|
||||
هر دو کد در تسکهای ۰۶ و ۰۷ هم استفاده میشوند، پس نامشان عمومی است نه مخصوص این تسک.
|
||||
|
||||
## Migration
|
||||
|
||||
```bash
|
||||
ddev exec php bin/console doctrine:migrations:diff --no-interaction
|
||||
ddev exec php bin/console doctrine:migrations:migrate --no-interaction
|
||||
```
|
||||
|
||||
## backfill
|
||||
|
||||
```bash
|
||||
ddev exec php bin/console app:appointment:backfill-service-duration # dry-run
|
||||
ddev exec php bin/console app:appointment:backfill-service-duration --force
|
||||
```
|
||||
|
||||
برای هر نوبت `pending`/`confirmed` **آیندهٔ** یک محیط سرویسی که `service_total_minutes`
|
||||
ندارد:
|
||||
|
||||
```
|
||||
service_total_minutes = (slot_end - slot_start) / 60
|
||||
service_buffer_minutes = buffer_minutes فعلیِ همان برنامه
|
||||
```
|
||||
|
||||
مقدار از خودِ نوبت گرفته میشود، **نه از مدت سرویسها** — چون نوبت موجود ممکن است با
|
||||
مدت دستی ثبت شده باشد و بازمحاسبه یعنی تغییر گذشته.
|
||||
|
||||
نوبتهای اسلاتی و نوبتهای گذشته رد میشوند. idempotent.
|
||||
|
||||
## fixture های تست خط سرخ
|
||||
|
||||
```
|
||||
tests/Appointment/fixtures/slot-mode-contract.json # پاسخ appointment-slots
|
||||
tests/Appointment/fixtures/month-availability-contract.json # پاسخ month-availability
|
||||
tests/Appointment/fixtures/slot-calculator-signatures.php # امضای متدهای عمومی
|
||||
```
|
||||
|
||||
⛔ این سه فایل بعد از این تسک **read-only** اند. هیچ تسکی اجازهٔ بهروزرسانیشان را ندارد.
|
||||
اگر تستی قرمز شد، کد باید برگردد نه fixture. این جمله را در بالای هر سه فایل بهعنوان
|
||||
کامنت بنویس.
|
||||
|
||||
fixture ها با تاریخ ثابت ساخته میشوند (`2026-01-05` مثلاً)، نه `time()` — وگرنه فردا قرمز.
|
||||
|
||||
## طبقهبندی tenant
|
||||
|
||||
هیچ entity جدیدی. `appointments` از قبل جفت tenant دارد.
|
||||
`TenantSchemaCoverageTest` باید بدون تغییر سبز بماند.
|
||||
Reference in New Issue
Block a user