پرش به محتویات

داده و 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ها.