Refactor doctor name handling across the application

- Removed the "دکتر" prefix from doctor names in various components and API responses to ensure consistency and clarity.
- Updated the AppointmentDetailPage, CommentsPage, DashboardPage, RatingsPage, SecretariesPage, and other relevant files to reflect the changes in doctor name formatting.
- Adjusted API documentation to align with the new naming conventions.
- Implemented validation to prevent the creation of clinics without a name and restricted users to a single clinic.
- Added tests to verify that doctor names are stored without titles and that clinic creation adheres to the new validation rules.
This commit is contained in:
hamed
2026-07-19 16:09:55 +03:30
parent 7761c37a3e
commit b05aeaf58b
30 changed files with 260 additions and 71 deletions
+6 -6
View File
@@ -356,7 +356,7 @@ List all doctors with pagination.
"data": [
{
"uuid": "...",
"title": "دکتر علی احمدی",
"title": "علی احمدی",
"degree": "متخصص",
"gender": "male",
"doctor_rate": 4.5,
@@ -565,7 +565,7 @@ List appointments filtered by date and/or doctor. Sorted by `slot_start ASC`.
"patient_name": "محمد رضایی",
"patient_mobile": "09123456789",
"doctor_uuid": "doctor-uuid",
"doctor_name": "دکتر علی احمدی",
"doctor_name": "علی احمدی",
"slot_start": 1718438400,
"slot_end": 1718439600,
"appointment_date": "2025-06-15",
@@ -764,7 +764,7 @@ List all settlement requests.
"data": [
{
"uuid": "...",
"user": { "uuid": "...", "real_name": "دکتر علی احمدی" },
"user": { "uuid": "...", "real_name": "علی احمدی" },
"amount_rials": 1000000,
"status": "pending",
"bank_account": { "bank_name": "بانک ملت", "owner_name": "..." },
@@ -845,7 +845,7 @@ Paginated. Each item:
{
"uuid": "...",
"id": 45,
"name": "دکتر علی احمدی",
"name": "علی احمدی",
"gender": "man",
"medical_code": "12345",
"is_active": true,
@@ -912,7 +912,7 @@ Paginated. Each item:
"status": "confirmed",
"patient_name": "علی رضایی",
"doctor_uuid": "...",
"doctor_name": "دکتر علی احمدی"
"doctor_name": "علی احمدی"
}
```
> `slot_start`/`slot_end` Unix timestamp (ثانیه).
@@ -1160,7 +1160,7 @@ List pre-registration requests. **Permission:** `ROLE_ADMIN`
{
"uuid": "...",
"type": "independent_doctor",
"name": "دکتر احمدی",
"name": "احمدی",
"mobile": "09121234567",
"info": "متخصص داخلی",
"status": "pending",
+3 -3
View File
@@ -236,7 +236,7 @@ Book an appointment slot.
"success": true,
"data": {
"uuid": "appt-uuid-...",
"doctor": { "uuid": "...", "name": "دکتر علی احمدی" },
"doctor": { "uuid": "...", "name": "علی احمدی" },
"user": { "uuid": "...", "mobile": "..." },
"slot_start": 1718438400,
"slot_end": 1718439600,
@@ -321,7 +321,7 @@ Get appointment detail.
"uuid": "appt-uuid-...",
"doctor": {
"uuid": "...",
"name": "دکتر علی احمدی",
"name": "علی احمدی",
"specialties": [
{ "uuid": "...", "name": "اورولوژی عمومی" }
]
@@ -435,7 +435,7 @@ Get all appointments for the authenticated user.
"data": [
{
"uuid": "...",
"doctor": { "uuid": "...", "title": "دکتر علی احمدی" },
"doctor": { "uuid": "...", "title": "علی احمدی" },
"slot_start": 1718438400,
"slot_end": 1718439600,
"status": "confirmed",
+1 -1
View File
@@ -580,7 +580,7 @@ Submit a pre-registration request (doctor or clinic). Public endpoint — no aut
```json
{
"type": "independent_doctor",
"name": "دکتر علی احمدی",
"name": "علی احمدی",
"mobile": "09121234567",
"info": "متخصص داخلی، ۱۰ سال سابقه"
}
+1 -1
View File
@@ -252,7 +252,7 @@
"uuid": "b244b506-...",
"invoice_uuid": "15498c14-...",
"visit_date": 1784440200,
"doctor_name": "دکتر تست",
"doctor_name": "تست",
"insurance_id": 176,
"insurance_name": "تامین اجتماعی",
"insurance_kind": "base",
+2 -2
View File
@@ -29,7 +29,7 @@ List published blog posts.
"slug": "ashnayi-ba-bimari-diabat",
"summary": "خلاصه مطلب...",
"image": "https://...",
"author": { "uuid": "...", "real_name": "دکتر احمدی" },
"author": { "uuid": "...", "real_name": "احمدی" },
"tags": [{ "id": 1, "name": "دیابت" }],
"status": "published",
"city": { "id": "123", "name": "یاسوج" },
@@ -84,7 +84,7 @@ Get a single blog post by slug.
"summary": "خلاصه...",
"body": "<p>محتوای کامل...</p>",
"image": "https://...",
"author": { "uuid": "...", "real_name": "دکتر احمدی" },
"author": { "uuid": "...", "real_name": "احمدی" },
"tags": [{ "id": 1, "name": "دیابت" }],
"status": "published",
"created_at": 1717000000,
+2 -2
View File
@@ -34,7 +34,7 @@ Send an invitation to a doctor (by mobile number) to join a clinic.
```json
{
"mobile": "09123456789",
"name": "دکتر علی احمدی",
"name": "علی احمدی",
"specialty": "قلب و عروق"
}
```
@@ -58,7 +58,7 @@ Send an invitation to a doctor (by mobile number) to join a clinic.
"invited_at": 1717000000,
"expires_at": 1717259200,
"token_used": false,
"doctor": { "uuid": "...", "name": "دکتر علی احمدی" },
"doctor": { "uuid": "...", "name": "علی احمدی" },
"clinic": { "uuid": "...", "name": "کلینیک الوند" }
}
}
+14 -3
View File
@@ -8,7 +8,18 @@
Create a new clinic.
**Permission:** `AUTH` — any authenticated user becomes the clinic owner
**Permission:** `AUTH` — any authenticated user becomes the clinic owner, and is
granted `ROLE_CLINIC` on success.
**One clinic per user.** `ClinicRepository::findByUser()` (which resolves the
caller's working context) is a `findOneBy`, so a second clinic would be
unreachable data — the request is rejected instead.
**Errors:**
| Code | HTTP | توضیح |
|------|------|-------|
| ERR_VALIDATION_001 | 422 | `name` خالی است (field: `name`) |
| ERR_CONFLICT_001 | 409 | این کاربر از قبل مالک یک کلینیک است |
### Request Body (`application/json`)
```json
@@ -295,7 +306,7 @@ Get doctors associated with a clinic.
{
"id": "1207",
"uuid": "...",
"name": "دکتر آرمان رضایی",
"name": "آرمان رضایی",
"gender": "man",
"degree": "specialist",
"img": [],
@@ -401,7 +412,7 @@ List the permission rows of every doctor in the clinic.
"uuid": "ce200cde-826d-11f1-b923-c282b864cdcc",
"clinic_uuid": "41e325c4-e825-4067-8438-5d828ecaee09",
"doctor_uuid": "bcabb3a8-cae3-45ec-876c-548f9c1e1569",
"doctor_name": "دکتر تست",
"doctor_name": "تست",
"active": true,
"permissions": { "version": 1, "resources": { "...": {} } },
"created_at": 1784352916,
+2 -2
View File
@@ -82,7 +82,7 @@ unclaimed ──claim/transfer شروع──▶ pending_transfer ──موفق
"data": {
"status": "claimed",
"claim": { "uuid": "…" },
"doctor": { "uuid": "…", "name": "دکتر فرخنده حسینی" }
"doctor": { "uuid": "…", "name": "فرخنده حسینی" }
}
}
```
@@ -127,7 +127,7 @@ unclaimed ──claim/transfer شروع──▶ pending_transfer ──موفق
{
"uuid": "…",
"status": "completed",
"doctor": { "uuid": "…", "name": "دکتر فرخنده حسینی" },
"doctor": { "uuid": "…", "name": "فرخنده حسینی" },
"mobile_masked": "0912***4567",
"verification_method": "apiir_personinfo+shahkar",
"failure_reason": null,
+1 -1
View File
@@ -50,7 +50,7 @@
```json
{
"name": "دکتر فرخنده حسینی",
"name": "فرخنده حسینی",
"medical_system_code": "145657",
"source": "irimc",
"source_ref": "https://membersearch.irimc.org/member/profile?id=…",
+6 -6
View File
@@ -24,7 +24,7 @@ Create a doctor profile for the authenticated user.
### Request Body (`application/json`)
```json
{
"title": "دکتر علی احمدی",
"title": "علی احمدی",
"gender": "male",
"medical_system_code": "12345",
"degree": "متخصص",
@@ -36,7 +36,7 @@ Create a doctor profile for the authenticated user.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `title` | string | ✅ | Full name with title |
| `title` | string | ✅ | نام پزشک **بدون** عنوان. پیشوند «دکتر» سمت سرور با `PersianText::stripDoctorTitle()` حذف می‌شود؛ نمایش عنوان کار لایهٔ UI است. |
| `gender` | string | ❌ | `"male"` or `"female"` |
| `medical_system_code` | string | ❌ | Nظام پزشکی code |
| `degree` | string | ❌ | Academic degree |
@@ -51,7 +51,7 @@ Create a doctor profile for the authenticated user.
"success": true,
"data": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"title": "دکتر علی احمدی",
"title": "علی احمدی",
"gender": "male",
"medical_system_code": "12345",
"degree": "متخصص",
@@ -93,7 +93,7 @@ Get doctor detail with clinics.
"data": {
"data": {
"uuid": "550e8400-...",
"name": "دکتر علی احمدی",
"name": "علی احمدی",
"gender": "man",
"medical_system_code": "12345",
"degree": "specialist",
@@ -153,7 +153,7 @@ Get doctor detail for clinic owner — only doctors who are members of the authe
"data": {
"data": {
"uuid": "...",
"title": "دکتر علی احمدی",
"title": "علی احمدی",
"specialties": [...],
"clinics": [{ "uuid": "...", "name": "کلینیک نور", "address": "...", "telephone": "..." }]
}
@@ -219,7 +219,7 @@ List doctors with pagination and filters.
"data": [
{
"uuid": "...",
"name": "دکتر علی احمدی",
"name": "علی احمدی",
"gender": "man",
"degree": "specialist",
"img": [],
+1 -1
View File
@@ -437,7 +437,7 @@ GET /api/v1/patient/{uuid}/appointments
"ends_at": 1754001800,
"status": "confirmed",
"version": 1,
"doctor_name": "دکتر ژیلا فتحی",
"doctor_name": "ژیلا فتحی",
"service_name": null,
"price_rials": null,
"created_at": 1754000000
+1 -1
View File
@@ -271,7 +271,7 @@ Get all pending comments waiting for review.
{
"uuid": "...",
"body": "...",
"doctor": { "uuid": "...", "title": "دکتر علی احمدی" },
"doctor": { "uuid": "...", "title": "علی احمدی" },
"user": { "uuid": "...", "real_name": "..." },
"status": "pending",
"created_at": 1717000000
+5 -5
View File
@@ -380,7 +380,7 @@ Get yearly earnings dashboard for a representation.
#### Request Body
```json
{ "mobile": "0935...", "name": "دکتر ...", "gender": "man", "degree": "...", "medical_system_code": "...", "specialties": [1,2] }
{ "mobile": "0935...", "name": "...", "gender": "man", "degree": "...", "medical_system_code": "...", "specialties": [1,2] }
```
| Field | Type | Required |
|-------|------|----------|
@@ -452,7 +452,7 @@ Get yearly earnings dashboard for a representation.
"patient_name": "...",
"patient_mobile": "0912...",
"doctor_uuid": "...",
"doctor_name": "دکتر ...",
"doctor_name": "...",
"slot_start": 1718000000,
"slot_end": 1718001800,
"appointment_date": "2025-06-15",
@@ -491,7 +491,7 @@ Get yearly earnings dashboard for a representation.
"success": true,
"data": [
{
"uuid": "...", "id": 12, "name": "دکتر ...", "gender": "man", "degree": "...",
"uuid": "...", "id": 12, "name": "...", "gender": "man", "degree": "...",
"medical_code": "...", "mobile": "0912...", "email": null,
"is_active": true, "rate": 3.5, "specialties": [],
"profile_image": null, "created_at": "2026-06-18T..."
@@ -621,7 +621,7 @@ Get yearly earnings dashboard for a representation.
"success": true,
"data": [
{
"uuid": "...", "name": "دکتر ...",
"uuid": "...", "name": "...",
"appointments": { "today": 0, "week": 1, "month": 4, "total": 18 },
"representation_income_rials": 363636,
"subscription_status": "active"
@@ -642,7 +642,7 @@ Get yearly earnings dashboard for a representation.
"success": true,
"data": [
{
"uuid": "...", "appointment_uuid": "...", "doctor_name": "دکتر ...",
"uuid": "...", "appointment_uuid": "...", "doctor_name": "...",
"gross_rials": 2000000, "tax_rials": 45455, "sms_fee_rials": 1500000,
"commission_percent": 20, "representation_share_rials": 90909,
"created_at": "2026-06-24T..."
+4 -4
View File
@@ -160,7 +160,7 @@ Create a secretary for a doctor.
"uuid": "sec-uuid-...",
"user_name": "علی محمدی",
"mobile_number": "09123456789",
"doctor_name": "دکتر احمد رضایی",
"doctor_name": "احمد رضایی",
"doctor_uuid": "...",
"owner_type": "doctor",
"clinic_uuid": null,
@@ -215,7 +215,7 @@ Get secretary detail.
"mobile_number": "09123456789",
"active": true,
"permissions": { ... },
"doctor": { "uuid": "...", "title": "دکتر علی احمدی" },
"doctor": { "uuid": "...", "title": "علی احمدی" },
"created_at": 1717000000
}
}
@@ -325,7 +325,7 @@ Get all secretaries for a specific doctor.
"uuid": "...",
"user_name": "علی محمدی",
"mobile_number": "09...",
"doctor_name": "دکتر احمد رضایی",
"doctor_name": "احمد رضایی",
"doctor_uuid": "...",
"is_active": true,
"permissions": { ... },
@@ -368,7 +368,7 @@ Get all secretaries across **all doctors** of a clinic.
"secretary_uuid": "...",
"user_name": "علی محمدی",
"mobile_number": "09...",
"doctor_name": "دکتر احمد رضایی",
"doctor_name": "احمد رضایی",
"doctor_uuid": "...",
"is_active": true,
"permissions": { ... },
+1 -1
View File
@@ -62,7 +62,7 @@ Send an SMS using an approved template.
"mobile": "09123456789",
"template_uuid": "tmpl-uuid-...",
"vars": {
"name": "دکتر علی احمدی",
"name": "علی احمدی",
"date": "۱۵ خرداد ۱۴۰۴"
},
"provider": "kavenegar"