[DDD] Thiết kế Chi tiết Trang Nhập SĐT (Quên Mật khẩu)
Tài liệu này mô tả thiết kế kỹ thuật chi tiết cho trang Nhập Số Điện Thoại trong hệ thống Quên Mật khẩu (Phone Entry Forgot Password Page). Trang này cho phép người dùng nhập số điện thoại để yêu cầu OTP đặt lại mật khẩu. Hệ thống được thiết kế để đảm bảo bảo mật cao với các biện pháp chống lạm dụng cho người dùng bất động sản tại Việt Nam.
1. Tổng quan (Overview)
1.1. Bối cảnh và Vấn đề
Người dùng trong hệ thống bất động sản Prima Brok thường xuyên quên mật khẩu do tính chất công việc di động và sử dụng nhiều thiết bị khác nhau. Việc khôi phục tài khoản cần được thực hiện nhanh chóng và an toàn để không ảnh hưởng đến hoạt động kinh doanh.
Các thách thức cụ thể:
- Bảo mật cao với UX đơn giản: Cần đảm bảo quy trình xác thực nghiêm ngặt nhưng không phức tạp cho người dùng
- Xác thực qua số điện thoại: Sử dụng số điện thoại làm phương thức xác thực chính phù hợp với thói quen người Việt
- Chống lạm dụng: Ngăn chặn các cuộc tấn công brute force và spam OTP
- Tính nhất quán: Đảm bảo trải nghiệm thống nhất với hệ thống đăng nhập hiện tại
- Validation chính xác: Validate số điện thoại Việt Nam theo format chuẩn
- Responsive design: Hoạt động mượt mà trên mọi thiết bị từ mobile đến desktop
1.2. Mục tiêu & Phi mục tiêu (Goals and Non-Goals)
Mục tiêu (Goals)
Trang Nhập Số Điện Thoại (PhoneEntryForgotPage):
- Thu thập và validate số điện thoại theo format Việt Nam (+84)
- Tích hợp country code selector với focus vào +84
- Gửi OTP qua SMS với rate limiting để chống lạm dụng
- Navigation trở về trang đăng nhập
- Error handling cho các trường hợp không tìm thấy user
Bảo mật và Performance:
- Giới hạn tần suất: Tối đa 3 OTP/giờ cho mỗi số điện thoại
- Lọc & kiểm tra dữ liệu đầu vào
- Giao tiếp API an toàn
- Xác thực định dạng số điện thoại
- Xử lý lỗi không tiết lộ thông tin
Phi mục tiêu (Non-Goals)
- Khôi phục mật khẩu qua email (chỉ focus vào SMS)
- Tùy chọn khôi phục đăng nhập xã hội
- Xác thực đa yếu tố với ứng dụng xác thực
- Xác minh OTP
- Logic đặt lại mật khẩu
2. Kiến trúc Tổng thể (Overall Architecture)
Trang PhoneEntryForgotPage được thiết kế như một single-purpose component với form validation mạnh mẽ và API integration an toàn.
Sequence Diagram - Luồng hoạt động Trang Quên mật khẩu
3. Thiết kế Chi tiết (Detailed Design)
3.1. Luồng Người dùng - Nhập Số Điện Thoại
-
Tải Trang:
- Tập trung vào trường nhập số điện thoại
- Mã quốc gia mặc định +84 (Việt Nam)
- Tải tiêu đề trang và mô tả từ i18n
-
Tương tác Nhập Số Điện Thoại::
- Chỉ chấp nhận số (tự động định dạng)
- Xác thực thời gian thực với mẫu regex
- Độ dài tối đa 11 ký tự
- Hiển thị lỗi xác thực ngay lập tức
-
Chọn Mã Quốc gia:
- Menu thả xuống với các quốc gia phổ biến
- Mặc định và làm nổi bật +84 (Việt Nam)
- Cập nhật số điện thoại kết hợp khi thay đổi
-
Xác thực Biểu mẫu:
- Xác thực phía máy khách với Zod schema
- Regex số điện thoại Việt Nam: ^(+?84|0)([3|5|7|8|9])([0-9]8)$
- Phản hồi thời gian thực cho người dùng
-
Gửi Biểu mẫu:
- Vô hiệu hóa nút trong quá trình tải
- Kết hợp mã quốc gia + số điện thoại
- Gọi API với định dạng FormData
- Hiển thị trạng thái tải với spinner
- Xử lý phản hồi thành công/lỗi
-
Điều hướng:
- Thành công: Điều hướng đến
/confirm-forgot-password?phone={encodedPhone} - Nút quay lại: Điều hướng đến
/login - Lỗi: Ở lại trang, hiển thị thông báo lỗi
- Thành công: Điều hướng đến
3.2. Thiết kế API (API Design)
API Endpoint
Yêu cầu OTP - POST /auth/api/v1/forgot-password
Request Format:
// FormData submission from your existing code
const formData = new FormData();
formData.append('phone_number', fullPhone);
await axiosInstance.post('/auth/api/v1/forgot-password', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
Response Success (200):
{
"success": true,
"message": "OTP sent successfully",
"data": {
"phone_number": "+84909172413",
"expires_in": 300,
"can_resend_after": 60
}
}
Response Error (422):
{
"detail": [
{
"loc": [
"string",
0
],
"msg": "string",
"type": "string"
}
]
}
4. Các yếu tố phi chức năng (Non-Functional Requirements)
4.1. Hiệu suất (Performance)
- Tải trang: < 2 giây cho lần tải đầu tiên
- Xác thực biểu mẫu: thời gian thực < 100 ms
- API Response: OTP send request < 3 giây
- Kích thước Bundle: Component code splitting để giảm initial bundle
- Sử dụng Bộ nhớ: Cleanup event listeners và timers khi unmount
4.2. Bảo mật (Security)
- Xác thực Đầu vào: Xác thực phía máy khách và máy chủ
- Giới hạn Tần suất: 3 yêu cầu mỗi giờ cho mỗi số điện thoại
- Bảo vệ CSRF: Bảo vệ dựa trên token cho gửi biểu mẫu
- Làm sạch Dữ liệu: SLàm sạch đầu vào số điện thoại
- Xử lý lỗi: Không tiết lộ thông tin nhạy cảm trong thông báo lỗi
- HTTPS: Tất cả API calls phải qua HTTPS
4.3. Khả năng mở rộng (Scalability)
- Chỉ mục Cơ sở dữ liệu: Chỉ mục phù hợp cho tra cứu số điện thoại và truy vấn hết hạn
- Bộ nhớ đệm: Dữ liệu giới hạn tần suất được lưu trong Redis
- Dịch vụ SMS: Tích hợp nhà cung cấp SMS có thể mở rộng (Twilio/AWS SNS)
- Giám sát: Giám sát thời gian phản hồi API và tỷ lệ lỗi
4.4. Trải nghiệm người dùng (UX)
- Thiết kế Thích ứng: Mobile-first approach, breakpoints tại 768px, 1024px
- Trạng thái Tải: Spinner tải trong các cuộc gọi API
- Xử lý Lỗi: Thông báo lỗi thân thiện với gợi ý hành động
- Khả năng Tiếp cận: Tuân thủ WCAG 2.1 AA, điều hướng bàn phím, hỗ trợ trình đọc màn hình
- Quốc tế hóa: Hỗ trợ cho các ngôn ngữ vi/en/ko
- Thông báo toast: Thông tin thành công/thất bại qua Sonner
4.5. Tương thích (Compatibility)
- Trình duyệt: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
- Thiết bị:: Desktop, tablet (768px+), mobile (320px+)
- Trình đọc Màn hình: NVDA, JAWS, VoiceOver support
5. Rủi ro và Phương án giảm thiểu (Risks and Mitigation)
| Rủi ro | Mức độ ảnh hưởng | Khả năng xảy ra | Phương án giảm thiểu |
|---|---|---|---|
| Lỗi gửi SMS | Cao | Trung bình | - Nhiều nhà cung cấp SMS - Cơ chế thử lại - Phương thức thông báo dự phòng |
| Vượt qua giới hạn tần suất | Cao | Thấp | - Nhiều lớp xác thực - Giới hạn dựa trên IP - Tích hợp CAPTCHA |
| Lỗi xác thực số điện thoại | Trung bình | Trung bình | - Kiểm thử regex toàn diện - Hỗ trợ nhiều định dạng - Thông báo lỗi rõ ràng |
| Độ trễ phản hồi API | Trung bình | Thấp | - Xử lý timeout - Trạng thái tải -Cơ chế thử lại |
6. Kế hoạch Testing (Testing Strategy)
6.1. Kiểm thử Đơn vị
- Xác thực Biểu mẫun: Kiểm tra với các định dạng số điện thoại khác nhau
- Hàm Tiện ích: Kiểm tra hàm combineCountryCodeAndPhoneNumber
- Logic Componen: TKiểm tra thay đổi trạng thái và xử lý lỗi
- Mục tiêu Độ phủ: 85% độ phủ dòng mã
6.2. IKiểm thử Tích hợp
- Tích hợp API: Mô phỏng phản hồi API cho các trường hợp thành công/lỗi
- Điều hướng: Kiểm tra chuyển hướng sau khi gửi thành công
- Thông báo Toast: Kiểm tra hiển thị thông báo toast
6.3. Kiểm thử Đầu cuối
- Luồng Tích cực: Nhập số hợp lệ → toast thành công → điều hướng đúng URL
- Xác thực: Nhập số không hợp lệ → hiển thị lỗi
- Giới hạn Tần suất: Kiểm tra hành vi khi vượt quá giới hạn
- Đa trình duyệt: Kiểm thử trên Chrome, Firefox, Safari
7. Triển khai và Giám sát
7.1. Chiến lược Triển khai
- Biến môi trường: Thông tin xác thực nhà cung cấp SMS, cấu hình giới hạn tần suất
- Cờ tính năng: Triển khai từng bước tính năng quên mật khẩu
- Di chuyển cơ sở dữ liệu: Tạo bảng với chỉ mục phù hợp
7.2. Giám sát và Phân tích
- Theo dõi lỗi: Sentry cho lỗi phía máy khách
- Giám sát API: Theo dõi tỷ lệ chuyển đổi từ nhập số điện thoại → xác thực OTP
- Hành vi người dùng: Theo dõi tỷ lệ chuyển đổi từ nhập số điện thoại → xác thực OTP
- Hiệu năng: Giám sát thời gian tải trang và phản hồi API
Tài liệu tham khảo: