Root cause of "دکتر دکتر …" (and ellipsis-truncated "…نی") in admin: IRIMC
names already contain the «دکتر» title, while the panel renders «دکتر {name}».
Convention is to store the bare name.
- DoctorImportService: normalize name via PersianText::stripDoctorTitle
(also fixes ي/ی, ك/ک, half-space)
- PersianText::stripDoctorTitle now strips consecutive «دکتر دکتر …» prefixes
- app:doctors:fix-irimc-names: one-off backfill for existing source='irimc'
rows (dry-run supported) — fixed 340 rows
- app:doctors:purge: FK-safe full wipe of doctors + all dependent tables +
orphan surrogate users, for a clean test DB (dry-run default, --force to
apply, prod-guarded)
- tests: PersianTextTest cases for the title stripping; DoctorImportTest
asserts stored name has no «دکتر» prefix
- docs/api/doctor-import.md: name convention + the two new commands
Verified: import "دکتر صفورا حجازی نیا" → stored "صفورا حجازی نیا" → panel
shows single «دکتر صفورا حجازی نیا».
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 line
4.7 KiB
JSON
1 line
4.7 KiB
JSON
{"nodes": [{"id": "users_hamed_pj_my_pj_clinic_pro_clinicpro_src_shared_util_persiantext_php", "label": "PersianText.php", "file_type": "code", "source_file": "src/Shared/Util/PersianText.php", "source_location": "L1"}, {"id": "util_persiantext_persiantext", "label": "PersianText", "file_type": "code", "source_file": "src/Shared/Util/PersianText.php", "source_location": "L12"}, {"id": "util_persiantext_persiantext_normalize", "label": ".normalize()", "file_type": "code", "source_file": "src/Shared/Util/PersianText.php", "source_location": "L14"}, {"id": "util_persiantext_persiantext_samename", "label": ".sameName()", "file_type": "code", "source_file": "src/Shared/Util/PersianText.php", "source_location": "L40"}, {"id": "util_persiantext_persiantext_stripdoctortitle", "label": ".stripDoctorTitle()", "file_type": "code", "source_file": "src/Shared/Util/PersianText.php", "source_location": "L46"}], "edges": [{"source": "users_hamed_pj_my_pj_clinic_pro_clinicpro_src_shared_util_persiantext_php", "target": "util_persiantext_persiantext", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/Shared/Util/PersianText.php", "source_location": "L12", "weight": 1.0}, {"source": "util_persiantext_persiantext", "target": "util_persiantext_persiantext_normalize", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/Shared/Util/PersianText.php", "source_location": "L14", "weight": 1.0}, {"source": "util_persiantext_persiantext", "target": "util_persiantext_persiantext_samename", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/Shared/Util/PersianText.php", "source_location": "L40", "weight": 1.0}, {"source": "util_persiantext_persiantext", "target": "util_persiantext_persiantext_stripdoctortitle", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/Shared/Util/PersianText.php", "source_location": "L46", "weight": 1.0}], "raw_calls": [{"caller_nid": "util_persiantext_persiantext_normalize", "callee": "class_exists", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L16", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_normalize", "callee": "\\Normalizer", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L17", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_normalize", "callee": "strtr", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L20", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_normalize", "callee": "strtr", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L31", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_normalize", "callee": "array_combine", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L31", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_normalize", "callee": "trim", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L36", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_normalize", "callee": "preg_replace", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L36", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_samename", "callee": "self", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L42", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_samename", "callee": "self", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L42", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_stripdoctortitle", "callee": "self", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L48", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_stripdoctortitle", "callee": "trim", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L50", "receiver": null}, {"caller_nid": "util_persiantext_persiantext_stripdoctortitle", "callee": "preg_replace", "is_member_call": false, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/src/Shared/Util/PersianText.php", "source_location": "L50", "receiver": null}]} |