Domain و جریان درخواست OTP
Use Case RequestOTP یک Mobile معتبر را به Challenge کوتاهعمر تبدیل میکند و فقط پس از پذیرش پایدار آن، درخواست تحویل را به Adapter میدهد.
مدل دامنه
Mobile
: Value Object شماره موبایل ایران که ورودیهای پشتیبانیشده را به قالب E.164 مانند +989121234567 تبدیل و نسخه Maskشده امن تولید میکند.
OTPChallenge
: Aggregate دارای شناسه UUIDv7، Digest کد، Hash سیگنالهای کنترل سوءاستفاده، زمان انقضا، زمان ارسال مجدد و وضعیت چرخه عمر.
OTPRequestRatePolicy
: Policy محدودیت Mobile، Device، IP و Service که Repository باید بهصورت Atomic اعمال کند.
جریان موفق
Transaction Boundary
Lockهای Advisory بر Scopeهای موثر گرفته میشوند، شمارندههای Rate Limit و Idempotency بررسی میشوند، Challenge فعال قبلی Invalid و Challenge جدید در یک Transaction ثبت میشود. Plaintext OTP هرگز وارد Command ذخیرهسازی نمیشود.
تحویل Development پس از Commit انجام میشود. این مرز برای Adapter واقعی SMS کافی نیست، چون شکست Provider میتواند Challenge ذخیرهشده ولی تحویلنشده بسازد. پیش از ملیپیامک باید Transactional Outbox به Transaction ایجاد Challenge اضافه شود.
مسیرهای جایگزین
- Mobile نامعتبر پیش از ساخت Challenge رد میشود.
- درخواست همسان با Idempotency Key قبلی بدون OTP جدید Replay میشود.
- درخواست متفاوت با همان Key Conflict است.
- عبور از هر Limit با
Retry-Afterرد میشود. - خطای Repository یا Delivery پاسخ عمومی
503میدهد و جزئیات داخلی فقط در Log پاکسازیشده میماند.
آزمون لازم
- Parse تمام قالبهای Mobile پذیرفته و ردشده؛
- یکتایی Replay و Conflict؛
- Invalid شدن Challenge فعال قبلی؛
- مرز انقضا و Resend؛
- شکست Random Generator، Repository و Delivery؛
- نبود Plaintext OTP در مدل Persistشده و Logهای غیر Development.