feat: add optional inventory package association to service items and implement audit logging
- Added `inventory_package_uuid` and `inventory_package_title` fields to the `ServiceItem` interface. - Updated API documentation to reflect new fields in service item responses. - Implemented methods in `ClinicServiceController` to handle inventory package associations. - Created `ServiceItemAuditLog` entity and repository for tracking changes to service items. - Added functionality to log changes to service items, including inventory package associations. - Implemented tests for attaching/detaching inventory packages and auditing changes. - Created database migrations for new fields and audit log table.
This commit is contained in:
@@ -151,7 +151,46 @@ refresh مستقیم هم کار کند، بنابراین فیلترکردن س
|
||||
**خطاها:** `404 ERR_SERVICE_NOT_FOUND` — هم برای uuid ناموجود و هم برای سرویس متعلق به tenant دیگر
|
||||
(وجود سرویس نباید لو برود) · `401` بدون احراز هویت.
|
||||
|
||||
> `section_name` تازه به `ServiceItem::toArray()` اضافه شده و در **همهی** پاسخهای این فایل هست، نه فقط این endpoint.
|
||||
> `section_name`، `inventory_package_id`، `inventory_package_uuid` و `inventory_package_title` در **همهی**
|
||||
> پاسخهای سرویس این فایل هستند، نه فقط این endpoint. دو فیلد آخر توسط کنترلر اضافه میشوند (نه `toArray()`)
|
||||
> و پکیجها با یک کوئری batch واکشی میشوند تا فهرست سرویسها به N+1 نیفتد.
|
||||
|
||||
---
|
||||
|
||||
## GET /api/v1/service-item/{uuid}/audit-logs
|
||||
|
||||
تاریخچهی تغییرات یک خدمت — تازهترین رویداد اول، حداکثر ۱۰۰ ردیف.
|
||||
|
||||
**Permission:** `IS_AUTHENTICATED_FULLY` + پنل Basic+ · فقط سرویسهای همان مطب/کلینیک.
|
||||
|
||||
**Response 200:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"uuid": "...",
|
||||
"field": "price_rials",
|
||||
"operation": "update",
|
||||
"old_value": "700000",
|
||||
"new_value": "850000",
|
||||
"actor_name": "دکتر رضایی",
|
||||
"created_at": 1718000000
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**فیلدهای رهگیریشده** (`ServiceItemAuditService::TRACKED`): `name`، `price_rials`، `active`،
|
||||
`duration_minutes`، `bookable`، `insurance_covered`، `inventory_package`.
|
||||
|
||||
- هر فیلدِ تغییریافته **یک ردیف جدا** میسازد؛ فیلد بدون تغییر ردیف نمیسازد.
|
||||
- `operation`: `create` (هنگام ساخت خدمت، فقط یک ردیف روی فیلد `name`) یا `update`.
|
||||
- مقادیر بهصورت رشته ذخیره میشوند: بولینها `"1"`/`"0"`، مبالغ ریال، و `null` یعنی «بدون مقدار».
|
||||
ترجمهی نمایشی سمت پنل انجام میشود (`FIELD_LABELS` و `auditValue` در `ServiceDetailPage.tsx`).
|
||||
- جدول `service_item_audit_logs` با `ON DELETE CASCADE` به `service_items` وصل است.
|
||||
|
||||
**خطاها:** `404 ERR_SERVICE_NOT_FOUND` · `401`.
|
||||
|
||||
---
|
||||
|
||||
@@ -186,6 +225,7 @@ refresh مستقیم هم کار کند، بنابراین فیلترکردن س
|
||||
| insurance_price_rials | integer\|null | ❌ — **deprecated.** سهم تقریبی بیمار؛ از فرم سرویس حذف شد. محاسبهی دقیق سهم بیمار از `TenantServiceCoverage` انجام میشود |
|
||||
| duration_minutes | integer\|null | ❌ — «زمان متوسط» انجام خدمت به دقیقه (`""`/`null` = بدون مقدار) |
|
||||
| bookable | boolean | ❌ (پیشفرض false) — «نمایش در نوبتدهی». فقط سرویسهای `bookable=true` در حالت نوبتدهی سرویسی قابلانتخاباند |
|
||||
| inventory_package_uuid | UUID\|null | ❌ — پکیج کالای مصرفی این خدمت ([inventory.md](inventory.md)). `null`/`""` یعنی قطع اتصال. پکیج باید متعلق به همان مطب/کلینیک باشد وگرنه `422 ERR_VALIDATION_001` با فیلد `inventory_package_uuid` |
|
||||
|
||||
> `bookable` در `PATCH /api/v1/service-item/{uuid}` هم به همین شکل پذیرفته میشود.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user