feat(insurance): redesign insurance management page to match Figma
Rebuild the /admin/insurance-pricing contracts UI to the Figma "مدیریت بیمه" design and inject the coverage/franchise/ceiling fields the design omitted. Backend: - Add contract-level `kind` column to TenantInsurance (basic|supplementary), defaulting to the catalog type; migration Version20260715093358. - POST/PATCH /billing/tenant-insurances now accept effective_from, effective_to, kind; PATCH also toggles is_active without clobbering the user-set effective_to (unlike DELETE/deactivate). - List returns the latest version of every insurance (active + inactive) via TenantInsuranceRepository::findLatestByTenant, for the فعال/غیرفعال toggle. Frontend: - New InsuranceModal (ui/Modal + SearchableSelect + PersianDateInput) with the seven fields; submit "ثبت بیمه". - TenantInsuranceContracts rebuilt: header + search box, desktop table (ردیف/نام/کد/نوع/وضعیت/عملیات) and mobile cards, status toggle -> PATCH. - utils: isoToUnix/unixToIso helpers for contract dates. Tests: TenantInsuranceContractApiTest (create/edit/toggle/list, 5 cases), InsuranceModal + TenantInsuranceContracts vitest suites, docs/api updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+10
-2
@@ -353,7 +353,7 @@ entity جاری از `#[CurrentUser]` resolve میشود: نقش `ROLE_DOCTOR
|
||||
قرارداد یک پزشک/کلینیک با یک بیمه: درصد پوشش، فرانشیز، سقف تعهد سالانه، نسخهبندی و وضعیت فعال. مبنای محاسبهی سهم در سیستم صورتحساب (`docs/architecture/insurance-billing-system.md`). tenant از `#[CurrentUser]` (`ROLE_DOCTOR`→doctor، `ROLE_CLINIC`→clinic). جدول `tenant_insurances`.
|
||||
|
||||
### GET `/api/v1/billing/tenant-insurances`
|
||||
لیست قراردادهای فعال tenant جاری.
|
||||
لیست قراردادهای tenant جاری — **آخرین نسخهٔ هر بیمه، فعال یا غیرفعال** (برای toggle فعال/غیرفعال در UI مدیریت بیمه). `insurance_kind` = `kind` قرارداد در صورت تعیین، وگرنه نوع بیمه از کاتالوگ.
|
||||
|
||||
**Permission:** `AUTH` (doctor/clinic)
|
||||
|
||||
@@ -372,6 +372,7 @@ entity جاری از `#[CurrentUser]` resolve میشود: نقش `ROLE_DOCTOR
|
||||
"coverage_percent": 70,
|
||||
"franchise_rials": 0,
|
||||
"annual_ceiling_rials": null,
|
||||
"kind": "basic",
|
||||
"effective_from": 1718900000,
|
||||
"effective_to": null
|
||||
}
|
||||
@@ -390,12 +391,19 @@ entity جاری از `#[CurrentUser]` resolve میشود: نقش `ROLE_DOCTOR
|
||||
| `coverage_percent` | float | درصد پوشش (۰–۱۰۰) |
|
||||
| `franchise_rials` | int | فرانشیز ثابت سهم بیمار |
|
||||
| `annual_ceiling_rials` | int \| null | سقف تعهد (null = بینهایت) |
|
||||
| `kind` | string \| null | نوع بیمه قرارداد (`basic`/`supplementary`); خالی → پیشفرض نوع کاتالوگ |
|
||||
| `effective_from` | int \| null | تاریخ شروع قرارداد (Unix)؛ null → اکنون |
|
||||
| `effective_to` | int \| null | تاریخ پایان قرارداد (Unix)؛ null → نامحدود |
|
||||
|
||||
پاسخ `201`: `{ success, data: { …contract } }`.
|
||||
خطاها: `404 ERR_NOT_FOUND_001` بیمه یافت نشد · `422 ERR_VALIDATION_001` insurance_id الزامی · `403 ERR_FORBIDDEN_001` پروفایل یافت نشد.
|
||||
|
||||
### PATCH `/api/v1/billing/tenant-insurances/{uuid}`
|
||||
ویرایش `coverage_percent` / `franchise_rials` / `annual_ceiling_rials`. فقط قرارداد متعلق به tenant جاری.
|
||||
ویرایش فیلدهای قرارداد (همه اختیاری، فقط کلیدهای موجود اعمال میشوند). فقط قرارداد متعلق به tenant جاری.
|
||||
|
||||
**Body:** `coverage_percent` · `franchise_rials` · `annual_ceiling_rials` · `kind` · `effective_from` · `effective_to` · `is_active`.
|
||||
|
||||
- `is_active` (bool): toggle فعال/غیرفعال. برخلاف `DELETE`، مقدار `effective_to`ِ تعیینشدهٔ کاربر را دستنخورده نگه میدارد (برای reactivate).
|
||||
|
||||
### DELETE `/api/v1/billing/tenant-insurances/{uuid}`
|
||||
غیرفعالسازی نرم (soft) — `is_active=false` و `effective_to=now`. داده حذف نمیشود.
|
||||
|
||||
Reference in New Issue
Block a user