چرا Citizenship را مستقیم روی Person نگذاشتم
یک تصمیم کوچک مدلسازی که جلوی اشتباههای معماری بزرگ در سیستم Identity را میگیرد.
موقع بازطراحی Identity Service الگوی تکراری دیدم: خیلی از سیستمها فرض میکنند شخص دقیقاً یک Citizenship دارد.
Person
└── citizenship_country_id
کوئری ساده. فهم آسان. فرض پنهان: یک ملیت برای همیشه.
واقعیت
- Multiple citizenship در بسیاری از مناطق عادی است
- Citizenship دوم میتواند بعداً در زندگی بیاید
- ملیت اصلی میتواند عوض شود؛ بعضیها renounce میشوند
اینها سناریوهای مشروعاند — نه edge caseهای عجیبی که تا ابد عقب بیندازید.
صفت در برابر رابطه
تبدیل رابطه به attribute یکی از رایجترین میانبرهای طراحی است — و یکی از گرانترینها برای بازگرداندن.
مدلی که استفاده کردم
Person
│
├── Citizenship #1
├── Citizenship #2
└── Citizenship #3
در زبان دیتابیس:
Person
│
└── PersonCitizenship
│
└── Country
هر تابعیت میتواند داشته باشد:
| فیلد | چرا وجود دارد |
|---|---|
| Country | کدام دولت |
| Acquisition date | تاریخچه / audit |
| Status | فعال، سلبشده، در انتظار |
| Primary flag | UX و حوزهٔ قضایی پیشفرض |
چرا مهم است
۱. واقعیت را منعکس میکند
آدم میتواند یک تابعیت داشته باشد — یا چند تا. مدل باید هر دو را نشان دهد.
۲. از migration گران جلوگیری میکند
کشف دیرهنگام چندتابعیتی یعنی جراحی اسکیما زیر بار. مدلکردن رابطه از اول ارزانتر است.
۳. مرز روشنتر
تابعیت فقط یک ستون نیست. رابطه بین شخص و کشور است.
مثال: یک شخص، دو دولت
درس کوچک مدلسازی
گاهی یک attribute مفهوم غنیتری را مخفی کرده. تابعیت یکی از آن مفاهیم در سیستم من بود.
هدف طراحی
نه «هر edge case را روز اول پشتیبانی کن» — از فرضهایی که همهجا درست نیستند دوری کن. یک تابعیت یا چند تا: هر دو باید جا شوند.
تا اینجا قوس مدلسازی اول کتاب را دیدید: Person / User → Contacts → Citizenship. بعد: Dual Session — اول Device، بعد Account — و Refresh Token Familyهایی که theft را قابلکشف میکنند.
فصل بعد
نسخهٔ canonical. همچنین در Medium.