forked from Yara724/api
121 lines
11 KiB
Markdown
121 lines
11 KiB
Markdown
# پیشنهاد مدل اشخاص در مرحله استعلام
|
||
|
||
وضعیت: پیادهسازیشده در ۱۴۰۵/۰۶/۲۲
|
||
دامنه: تمام جریانهای استعلام کاربر، کارشناس، پروندهساز و مرکز تماس
|
||
نسخه انگلیسی: [inquiry-participants-proposal.md](./inquiry-participants-proposal.md)
|
||
|
||
## interface پیادهسازیشده
|
||
|
||
فیلدهای نقشها و آبجکت اختیاری `vehicle` که در ادامه آمدهاند، مستقیماً در body تمام درخواستهای استعلام فعلی پذیرفته میشوند. این تغییر شامل فرم اولیه کاربر و mirror کارشناس/ثبتکننده در V2، جریان کارشناس V3، جریانهای پروندهساز V4/V5، مرکز تماس V6 و مسیرهای تکدرخواستی حضوری است. routeهای پلاک و VIN از قوانین مشترک اشخاص استفاده میکنند.
|
||
|
||
در دوره مهاجرت، فیلدهای قدیمی و تخت همچنان پذیرفته میشوند. پاسخها و جزئیات پرونده برای نقشهای عملیاتی، در صورت وجود داده، فیلدهای نرمالشده `participants`، `participantRoles`، `vehicle.registrationState` و `vehicle.previousPlateId` را نمایش میدهند.
|
||
|
||
## مسئله
|
||
|
||
قرارداد فعلی استعلام عمدتاً فقط راننده و شخصی با عنوان `insurer` را نگه میدارد. این مدل کامل نیست و نامگذاری نیز دقیق نیست: شخص، **بیمهگذار** است و **بیمهگر** شرکت بیمه است.
|
||
|
||
برای هر وسیله نقلیه در یک `Party` نقشهای هویتی زیر وجود دارد:
|
||
|
||
| نوع پرونده | نقشهای الزامی |
|
||
| ------------- | ------------------------------------------------------------ |
|
||
| `THIRD_PARTY` | راننده، مالک وسیله نقلیه، بیمهگذار شخص ثالث |
|
||
| `CAR_BODY` | راننده، مالک وسیله نقلیه، بیمهگذار شخص ثالث، بیمهگذار بدنه |
|
||
|
||
ممکن است یک شخص چند نقش را داشته باشد، اما سیستم نباید یکسان بودن آنها را فرض کند.
|
||
|
||
## پیشنهاد
|
||
|
||
پیش از اجرای استعلام، یک **مرحله کوتاه تعیین اشخاص** اضافه شود. ابتدا نسبت اشخاص پرسیده شود و اطلاعات فقط برای افراد متفاوت دریافت شود. دریافت بدون شرط اطلاعات کامل همه اشخاص مناسب نیست. همچنین افزودن فلگهای دوتایی متعدد مانند `driverIsOwner` و `ownerIsPolicyholder` باعث ابهام، تناقض و رشد سریع حالتها میشود.
|
||
|
||
بهجای آن، هر نقش یا اطلاعات یک شخص جدید را داشته باشد یا به نقش قبلی ارجاع دهد:
|
||
|
||
```json
|
||
{
|
||
"driver": {
|
||
"nationalCode": "0012345678",
|
||
"birthday": "1370/01/01",
|
||
"hasDrivingLicense": true,
|
||
"licenseNumber": "123456789",
|
||
"licenseType": "1"
|
||
},
|
||
"vehicleOwner": { "sameAs": "DRIVER" },
|
||
"thirdPartyPolicyholder": { "sameAs": "VEHICLE_OWNER" },
|
||
"carBodyPolicyholder": {
|
||
"nationalCode": "0098765432",
|
||
"birthday": "1365/02/03"
|
||
}
|
||
}
|
||
```
|
||
|
||
فیلد `carBodyPolicyholder` برای `THIRD_PARTY` مجاز نیست و برای `CAR_BODY` الزامی است. هر نقش باید فقط یکی از دو حالت «اطلاعات شخص» یا `sameAs` را داشته باشد. بکاند این ورودی را به فهرست اشخاص یکتا و اتصال نقشها به آنها تبدیل میکند.
|
||
|
||
فقط برای طرف زیاندیده در پرونده `THIRD_PARTY` میتوان نامشخص بودن بیمهگذار را بهصورت صریح با `"thirdPartyPolicyholder": { "unknown": true }` ارسال کرد. این حالت برای طرف مقصر پذیرفته نمیشود. در مسیر پلاک، استعلام بیمه شخص ثالث ــ چون به هویت بیمهگذار نیاز دارد ــ بهشکل قابلممیزی «عمداً اجرا نشد» ثبت میشود؛ استعلام مبتنی بر VIN همچنان بدون حدسزدن هویت قابل اجرا است. اعتبارسنجی راننده و مالک و استعلامهای هویت، مالکیت و گواهینامه همچنان انجام میشوند.
|
||
|
||
برای راننده، `hasDrivingLicense` الزامی است. اگر مقدار آن `true` باشد، هر دو فیلد `licenseNumber` و `licenseType` نیز الزامی هستند؛ اگر مقدار آن `false` باشد، استعلام گواهینامه عمداً اجرا نمیشود.
|
||
|
||
## انتقال مالکیت اخیر و پلاک قبلی
|
||
|
||
نقش اشخاص و شناسههای خودرو دو موضوع جدا هستند. اگر خودرو بهتازگی فروخته یا خریداری شده باشد، ممکن است اطلاعات رسمی یا بیمهنامه هنوز به پلاک قبلی متصل باشد. این وضعیت باید صریح ثبت شود و پلاک قبلی نباید جایگزین پلاک فعلی شود:
|
||
|
||
```json
|
||
{
|
||
"vehicle": {
|
||
"registrationState": "RECENTLY_TRANSFERRED",
|
||
"currentPlate": {
|
||
"leftDigits": "44",
|
||
"centerAlphabet": "ب",
|
||
"centerDigits": "111",
|
||
"ir": "22"
|
||
},
|
||
"previousPlate": {
|
||
"leftDigits": "55",
|
||
"centerAlphabet": "ج",
|
||
"centerDigits": "222",
|
||
"ir": "33"
|
||
},
|
||
"vin": "NAAM01E15HK123456"
|
||
}
|
||
}
|
||
```
|
||
|
||
مقدار پیشفرض `registrationState` برابر `CURRENT` است و برای این مسیر استثنایی مقدار `RECENTLY_TRANSFERRED` استفاده میشود. `previousPlate` فقط در حالت انتقال اخیر الزامی است. پلاک فعلی همچنان شناسه اصلی خودرو است. هماهنگکننده استعلام باید ابتدا پلاک فعلی را بررسی کند و اگر نتیجه ناموجود، قدیمی یا فاقد بیمهنامه مرتبط بود، پلاک قبلی را بهصورت خودکار استعلام کند.
|
||
|
||
پیش از پذیرش نتیجه پلاک قبلی، بکاند باید یکسان بودن VIN/شماره شاسی را بررسی کند. در صورت مغایرت، انتخاب خودکار متوقف و اصلاح اطلاعات یا بررسی دستی الزامی شود. هر دو پلاک و تمام تلاشهای استعلام برای ممیزی نگهداری شوند، اما پلاک قبلی هیچگاه نباید روی پلاک فعلی نوشته شود.
|
||
|
||
## ترتیب پیشنهادی فرم
|
||
|
||
1. پلاک فعلی دریافت و درباره انتقال مالکیت اخیر پرسیده شود. در صورت انتقال اخیر، پلاک قبلی و VIN/شماره شاسی نیز دریافت شوند.
|
||
2. اطلاعات هویتی و گواهینامه راننده دریافت شود.
|
||
3. پرسیده شود آیا مالک خودرو همان راننده است؛ فقط در صورت تفاوت، اطلاعات مالک دریافت شود.
|
||
4. برای بیمهگذار شخص ثالث یکی از «راننده»، «مالک» یا «شخص دیگر» انتخاب شود؛ فقط برای شخص دیگر فرم جدید نمایش داده شود.
|
||
5. در `CAR_BODY` همین انتخاب برای بیمهگذار بدنه انجام شود و امکان انتخاب هر شخص ثبتشده یا شخص دیگر وجود داشته باشد.
|
||
6. خلاصه اشخاص نمایش داده شود و سپس استعلامها اجرا شوند.
|
||
|
||
به این ترتیب مسیر رایج کوتاه میماند و همه ترکیبهای معتبر نیز پشتیبانی میشوند.
|
||
|
||
## محل منطق در بکاند
|
||
|
||
یک resolver مشترک برای اشخاص ساخته شود و تمام routeهای استعلام از آن استفاده کنند. interface این ماژول باید:
|
||
|
||
- نقشهای لازم را بر اساس نوع پرونده اعتبارسنجی و ارجاعهای نامعتبر یا حلقوی `sameAs` را رد کند؛
|
||
- شخص نهایی هر نقش را برگرداند؛
|
||
- هویت درست را به استعلام مرتبط بدهد: گواهینامه ← راننده، مالکیت ← مالک خودرو، بیمه شخص ثالث ← بیمهگذار شخص ثالث، بیمه بدنه ← بیمهگذار بدنه؛
|
||
- بر اساس یک قاعده مشخص، پلاک فعلی یا قبلی را انتخاب و نتیجه پلاک قبلی را با VIN/شماره شاسی تطبیق دهد؛
|
||
- استعلام هویت را برای هر شخص یکتا فقط یک بار اجرا کند؛
|
||
- اشخاص نرمالشده و نقشهای آنها را در `Party` مربوط ذخیره کند.
|
||
|
||
جریانهای V2 کاربر/کارشناس، V3، V4، V5 و V6 باید adapter همین قوانین مشترک باشند و منطق نسبت اشخاص را جداگانه پیادهسازی نکنند.
|
||
|
||
## سازگاری و انتشار تدریجی
|
||
|
||
1. در دوره گذار، ساختار جدید در کنار فیلدهای قدیمی پذیرفته شود.
|
||
2. `nationalCodeOfDriver` به راننده و `nationalCodeOfInsurer` به بیمهگذار شخص ثالث نگاشت شود. اگر `driverIsInsurer=true` است، هر دو نقش به یک شخص متصل شوند.
|
||
3. `plate` یا `plateId` قدیمی به پلاک فعلی نگاشت شود؛ پلاک قبلی فقط وقتی ثبت شود که صریحاً از کاربر دریافت شده باشد.
|
||
4. برای دادههای قدیمی، مالک خودرو یا بیمهگذار بدنه حدس زده نشود؛ مگر اینکه نتیجه استعلام ذخیرهشده آن را قطعی کند، نقش «نامشخص» باقی بماند.
|
||
5. پاسخ جزئیات و گزارش، اشخاص را بر اساس نقش نمایش دهد و در زمان مهاجرت فیلدهای قدیمی را نیز حفظ کند.
|
||
6. پس از مهاجرت همه فرانتاندها، قرارداد جدید برای پروندههای تازه الزامی و فیلدهای قدیمی deprecated شوند.
|
||
|
||
## تصمیم پیشنهادی
|
||
|
||
راهحل مناسب، **دریافت شرطی اطلاعات همراه با اتصال صریح نقشها** است. این روش بدون طولانی کردن مسیر اکثر کاربران، اطلاعات کامل فراهم میکند، از تناقض فلگها جلوگیری میکند و یک مدل یکسان برای همه جریانهای استعلام میسازد.
|