داده و Migration درخواست OTP
Migration 000001_identity_otp_challenges.sql Table و Constraintهای OTP Challenge را میسازد. این صفحه دلیل طراحی و الزامات نگهداری را توضیح میدهد؛ SQL اجراشده در Repository بکاند منبع حقیقت Schema است.
داده ذخیرهشده
| گروه | ستونهای اصلی | هدف |
|---|---|---|
| شناسه | id |
UUIDv7 مرتبپذیر زمانی |
| Mobile | mobile_e164, masked_mobile |
مقصد Normalized و نمایش امن |
| Secret | otp_digest |
HMAC-SHA256؛ بدون Plaintext |
| Idempotency | idempotency_key_hash, request_fingerprint |
Replay و تشخیص Conflict |
| Abuse Signal | device_hash, client_ip_hash |
Rate Limit بدون نگهداری ورودی خام |
| Lifecycle | status, failed_attempts, timestampها |
انقضا، مصرف و Invalid شدن |
Constraintها
- UUID باید Version 7 باشد.
- Mobile باید E.164 ایران با Prefix
+989باشد. - تمام Digest و Hashها دقیقا 32 Byte هستند.
- Status فقط
ACTIVE،CONSUMED،EXPIREDیاINVALIDATEDاست. - تعداد تلاش ناموفق بین 0 و 5 قرار دارد.
- زمان انقضا و Resend بعد از زمان ایجاد هستند.
- ستون زمان مصرف و Invalid شدن با Status مربوط سازگار است.
- Hash Idempotency Key یکتا است.
Indexها
Indexهای (mobile_e164, created_at)، (device_hash, created_at)، (client_ip_hash, created_at) و created_at Queryهای Rate Limit و Retention را پشتیبانی میکنند. هر تغییر Limit یا Query باید Query Plan و اثر Write Amplification این Indexها را دوباره بررسی کند.
حریم خصوصی و Retention
Mobile یک داده شخصی است و فقط برای نیاز احراز هویت نگهداری میشود. Hash کردن Device و IP ناشناسسازی قطعی نیست؛ این مقادیر همچنان داده حساس عملیاتی هستند. مدت Retention و Job حذف هنوز در محصول تصویب نشده است و پیش از Production باید با Security و Product تعیین و پیادهسازی شود.
Migration و Rollback
Migration در Startup خودکار اجرا میشود. Down Migration فقط برای محیط امن و پیش از داده واقعی است؛ Rollback Image در عملیات عادی Schema را Down نمیکند. تغییرهای بعدی باید Migration جدید و Backward-compatible بسازند.
آزمون Integration
- اجرای Migration روی PostgreSQL واقعی؛
- Constraintهای Mobile، Digest، Status و Timestamp؛
- Idempotency همسان و Conflict متفاوت؛
- اعمال Atomic تمام Limitها در Concurrency؛
- Invalid شدن Challenge قبلی؛
- اثبات نبود OTP Plaintext در Rowها و Errorها.