feat: enhance doctor import process with source profile ID for improved idempotency and deduplication

This commit is contained in:
hamed
2026-07-19 20:19:35 +03:30
parent 74577c2ff6
commit e670b38821
11 changed files with 593 additions and 13 deletions
+15 -5
View File
@@ -52,12 +52,19 @@ class DoctorImportService
$name = \App\Shared\Util\PersianText::stripDoctorTitle((string) $data['name']);
$code = trim((string) ($data['medical_system_code'] ?? $data['medicalSystemCode']));
$source = trim((string) ($data['source'] ?? 'irimc')) ?: 'irimc';
$ref = $data['source_ref'] ?? $data['profile_url'] ?? null;
// شناسهٔ authoritative پروفایل مبدأ؛ کلید اصلی idempotency (بر کد مقدم است).
$profileId = SourceProfileId::fromRef($ref);
$doctorRepo = $this->em->getRepository(Doctor::class);
$userRepo = $this->em->getRepository(User::class);
// idempotency: همان پزشکِ منبع → به‌روزرسانی، نه ساخت تکراری
$doctor = $doctorRepo->findOneBy(['source' => $source, 'medicalSystemCode' => $code]);
// idempotency: اول با شناسهٔ پروفایل (پایدار حتی اگر کد عوض شده باشد)،
// سپس با (source, medical_system_code). یک پروفایل هرگز دو رکورد نمی‌سازد.
$doctor = $profileId !== null
? $doctorRepo->findOneBy(['source' => $source, 'sourceProfileId' => $profileId])
: null;
$doctor ??= $doctorRepo->findOneBy(['source' => $source, 'medicalSystemCode' => $code]);
$created = false;
// پروفایل تصاحب‌شده را با ایمپورت مجدد بازنویسی نکن (مالک واقعی اولویت دارد)
@@ -75,8 +82,10 @@ class DoctorImportService
}
if ($doctor === null) {
// کاربر جانشینِ یکتا و غیرفعال؛ شناسهٔ مصنوعی قطعی از روی کد نظام پزشکی
$synthetic = 'imp_' . substr(md5($source . ':' . $code), 0, 14); // ≤ ۱۸ کاراکتر، ASCII، یکتا
// کاربر جانشینِ یکتا و غیرفعال؛ شناسهٔ مصنوعی قطعی از شناسهٔ پایدارِ پروفایل
// (یا کد، اگر پروفایل شناسه ندارد) تا با تغییر کد، جانشین تکراری ساخته نشود.
$identity = $profileId ?? $code;
$synthetic = 'imp_' . substr(md5($source . ':' . $identity), 0, 14); // ≤ ۱۸ کاراکتر، ASCII، یکتا
$user = $userRepo->findOneBy(['mobileNumber' => $synthetic]);
if ($user === null) {
$user = new User($synthetic);
@@ -105,7 +114,8 @@ class DoctorImportService
$doctor->setMedicalSystemCode($code);
$doctor->setManagedBy($importedBy->getId());
if (array_key_exists('source_ref', $data) || array_key_exists('profile_url', $data)) {
$doctor->setSourceRef($data['source_ref'] ?? $data['profile_url'] ?? null);
$doctor->setSourceRef($ref);
$doctor->setSourceProfileId($profileId);
}
if (!empty($data['gender'])) $doctor->setGender($data['gender']);
if (!empty($data['degree'])) $doctor->setDegree($data['degree']);