feat(doctor): prevent duplicate doctor imports based on medical system code

This commit is contained in:
hamed
2026-07-11 19:56:58 +03:30
parent 6c67d522ba
commit 23590370b2
3 changed files with 44 additions and 0 deletions
+9
View File
@@ -39,6 +39,10 @@
- اگر وجود داشته باشد و `owner_status != claimed`**به‌روزرسانی** می‌شود (`200`).
- اگر وجود داشته باشد و `owner_status == claimed`**رد** می‌شود (`200`, `skipped: "claimed"`)
تا دادهٔ مالک واقعی بازنویسی نشود.
- **تکرار بین منابع:** اگر پزشکی با همان `medical_system_code` ولی `source` متفاوت
(مثلاً ثبت دستی در پنل) وجود داشته باشد → **رد** می‌شود (`200`, `skipped: "duplicate"`
نه رکورد جدیدی ساخته می‌شود و نه رکورد موجود بازنویسی می‌شود. `uuid` همان رکورد موجود
برگردانده می‌شود (تست: `DoctorImportTest::testManualDoctorWithSameCodeIsNeverDuplicated`).
---
@@ -108,6 +112,11 @@
{ "success": true, "data": { "uuid": "…", "created": false, "skipped": "claimed" } }
```
### `200 OK` (رد به‌دلیل کد نظام پزشکی تکراری با منبع دیگر)
```json
{ "success": true, "data": { "uuid": "…", "created": false, "skipped": "duplicate" } }
```
### `422` (اعتبارسنجی)
```json
{ "success": false, "data": null, "errors": [ { "code": "…", "message": "کد نظام پزشکی الزامی است", "field": "medical_system_code" } ] }
@@ -65,6 +65,15 @@ class DoctorImportService
return new DoctorImportResult($doctor, false, 'claimed');
}
if ($doctor === null) {
// جلوگیری از تکرار بین منابع: اگر همین کد نظام پزشکی با هر source دیگری
// (مثلاً ثبت دستی) وجود دارد، ایمپورت نه می‌سازد و نه بازنویسی می‌کند.
$existing = $doctorRepo->findOneBy(['medicalSystemCode' => $code]);
if ($existing !== null) {
return new DoctorImportResult($existing, false, 'duplicate');
}
}
if ($doctor === null) {
// کاربر جانشینِ یکتا و غیرفعال؛ شناسهٔ مصنوعی قطعی از روی کد نظام پزشکی
$synthetic = 'imp_' . substr(md5($source . ':' . $code), 0, 14); // ≤ ۱۸ کاراکتر، ASCII، یکتا
+26
View File
@@ -164,6 +164,32 @@ class DoctorImportTest extends ApiTestCase
$this->assertSame('مطب دکتر صفورا حجازی نیا', $doctor->getAddresses()->first()->getName());
}
public function testManualDoctorWithSameCodeIsNeverDuplicated(): void
{
$admin = $this->createUser(['ROLE_USER', 'ROLE_ADMIN']);
$code = $this->freshCode();
$owner = $this->createUser(['ROLE_USER', 'ROLE_DOCTOR']);
$manual = new Doctor($owner, 'پزشک دستی');
$manual->setMedicalSystemCode($code);
$this->em->persist($manual);
$this->em->flush();
$data = $this->authJson('POST', '/api/v1/admin/doctors/import', $admin, $this->importPayload($code));
$this->assertSame(200, $this->responseCode());
$this->assertFalse($data['data']['created']);
$this->assertSame('duplicate', $data['data']['skipped']);
$this->assertSame($manual->getUuid(), $data['data']['uuid']);
$this->em->clear();
$count = $this->em->getRepository(Doctor::class)->count(['medicalSystemCode' => $code]);
$this->assertSame(1, $count);
$doctor = $this->em->getRepository(Doctor::class)->findOneBy(['medicalSystemCode' => $code]);
$this->assertSame('پزشک دستی', $doctor->getName());
$this->assertSame('manual', $doctor->getSource());
}
public function testValidationErrors(): void
{
$admin = $this->createUser(['ROLE_USER', 'ROLE_ADMIN']);