Incident Postmortem • Production Defect
Khắc Phục Lỗi Xóa Trắng Giỏ Hàng, Mất Add-On & 'Room(s) null' Sau Khi Login Member
Phân tích nguyên nhân gốc rễ (RCA) đã được xác minh thực nghiệm và chi tiết bản vá phòng vệ: Ngăn chặn cơ chế nạp trang ghi đè xóa sạch giỏ hàng Guest khi đăng nhập Member, bảo toàn dữ liệu tiện ích add-on cho nhiều phòng, và triệt tiêu lỗi hiển thị 'Room(s) null'.
- ✦ VERIFIED & CONFIRMED FIX
- Target:
https://www.example.com/en/booking-journey?step=1 - Asset:
commons.1.37.0-v53319.min.js • chunk 223 / 271 - Date: 14/10/2026
01. Incident Overview & Impact Analysis
Severity
Ảnh hưởng trực tiếp đến toàn bộ phễu chuyển đổi Guest → Member và doanh thu phụ trợ Add-on.
Impact Scope
100% người dùng đặt từ 2 phòng trở lên khi thực hiện đăng nhập tài khoản thành viên tại Step 1.
Fix Readiness
:::success VERIFIED IN PROD RUNTIME
Bi-directional Storage Sync, Dual-Schema Cart Normalizer & Rehydration Safe Guards.
:::
Rollout Timeline
Triển khai AEM ClientLib Hotfix qua Adobe Cloud Manager Dispatcher & CDN flush.
Bối cảnh nghiệp vụ
Trên hệ thống đặt phòng trực tuyến, phễu chuyển đổi khách vãng lai (Guest) thành hội viên Member ngay trong quá trình đặt phòng (Booking Journey) là một trong những chỉ số tăng trưởng (growth KPI) quan trọng nhất. Khách hàng thường tìm kiếm 2 phòng, lựa chọn loại phòng và giá, đồng thời chọn thêm các tiện ích gia tăng (Add-on items như đưa đón sân bay, bữa sáng) tại step=1. Tại đây, hệ thống khuyến khích khách đăng nhập tài khoản Member để nhận ưu đãi thành viên và tự động kích hoạt tải lại trang (page reload).
Hiện tượng lỗi (Verified Symptoms)
- Dữ liệu giỏ hàng bị xóa sạch (Cart Obliterated): Ngay sau khi trang reload hậu đăng nhập, toàn bộ dữ liệu phòng đã chọn và các dịch vụ add-on biến mất hoàn toàn khỏi giỏ hàng.
- Gãy vỡ giao diện tiêu đề: Tiêu đề tóm tắt phòng bị lỗi chuỗi thành
"Room(s) null"(hoặc"Apartment null"khi mở popup chỉnh sửa). - Sụt giảm Dropdown Add-on: Danh sách chọn phòng áp dụng add-on bị co cụm bất thường chỉ còn 1 lựa chọn thay vì duy trì đủ 2 phòng như lúc tìm kiếm.
Tác động kinh doanh
Lỗi này phá vỡ hoàn toàn trải nghiệm người dùng, làm sụt giảm nghiêm trọng tỷ lệ chuyển đổi hội viên mới, thất thoát doanh thu Upsell Add-on và đẩy tỷ lệ bỏ dở thanh toán (Cart Abandonment) tăng cao.
02. Investigation Trace & Scope Isolation
1. Bất đối xứng kiến trúc lưu trữ Dual-Storage (sessionStorage vs localStorage)
Khi khách đặt phòng với tư cách Guest, giỏ hàng được lưu trữ tạm thời tại sessionStorage.yourCartSession. Tại thời điểm này, localStorage.yourCart (dành cho giỏ hàng lưu của Member từ API backend getSavedCart) hoàn toàn rỗng ([]).
2. Điểm tử huyệt: Cơ chế khởi tạo nạp trang ghi đè xóa sạch giỏ hàng
Tại tiến trình nạp trang Booking Journey (Offset ~2377249 & 2379370 trong commons.min.js), logic khởi tạo đọc p = JSON.parse(localStorage.getItem("yourCart")) || [] và h = JSON.parse(sessionStorage.getItem("yourCartSession")) || []. Trong nhánh điều hướng chính, code thực hiện:
Do khách vừa login từ Guest, p là mảng rỗng [], lệnh này trực tiếp ghi đè xóa sổ toàn bộ dữ liệu giỏ hàng của Guest.
3. Bỏ qua cập nhật tiêu chí tìm kiếm dẫn tới "Room(s) null"
Do p bị rỗng (p.length === 0), khối mã cập nhật tiêu chí tìm kiếm x.rooms = p.length; t.updateBookingSearchCriteria(x) bị bỏ qua hoàn toàn. Kết quả là this.totalApartment nhận giá trị null. Khi hàm apartmentContent (Offset ~1153791) thực hiện .replace("{apartment}", this.totalApartment), chuỗi hiển thị bị tiêm giá trị null trực tiếp thành "Room(s) null".
4. Lệch pha khóa định danh trong hàm sắp xếp giỏ hàng (sortCartItem)
Tại Offset ~2649511, hàm sortCartItem chuyển sang sắp xếp theo "actualApartmentNumber" (1-indexed) ngay khi cookie thành viên ia_oQKaJKhTFC xuất hiện, trong khi giỏ hàng ban đầu của Guest chỉ có "apartmentNumber" (0-indexed). Thuộc tính bị undefined khiến lodash.sortBy() làm đảo lộn thứ tự index, khiến dropdown add-on không khớp được phòng số 2 và tự động co cụm về 1 option.
03. Root Cause Code Inspection
Nguyên nhân gốc rễ đã được xác minh thực tế 100%:
- Cơ chế nạp trang đơn phương ghi đè giỏ hàng bằng
localStorage.yourCartrỗng của Member làm bốc hơi toàn bộ giỏ hàng của Guest - Vòng lặp cập nhật search criteria bị bỏ qua khiến
this.totalApartmentnhậnnullvà render thànhRoom(s) null - Lệch pha schema trong
sortCartItemkhiến dropdown add-on bị co cụm về 1 phòng
04. Proposed Fix & Defensive Architecture
Bản vá phòng vệ toàn diện 3 tầng:
- Tầng 1 (Storage Handover): Ngăn chặn ghi đè mảng rỗng, chuyển giao dữ liệu hai chiều giữa
sessionStoragevàlocalStorage - Tầng 2 (Display Rehydration Guard): Thêm guard clause cho
apartmentContent, đảm bảo luôn hiển thị số lượng phòng hợp lệ - Tầng 3 (Schema Normalizer): Chuẩn hóa đồng bộ
apartmentNumbervàactualApartmentNumbercho mọi item giỏ hàng
05. Verification Matrix (Baseline vs Patched)
06. Rollout & Dispatcher Cache Invalidation
Phase 01 - AEM ClientLib Hotfix Deployment
Thay thế bundle commons.1.37.0-v53319.min.js tại đường dẫn AEM ClientLib /etc.clientlibs/booking/clientlibs/commons*.js bằng mã nguồn đã vá.
Phase 02 - Xóa Cache Dispatcher & CDN Cloudflare
Thực hiện invalidate cache trên Adobe Cloud Manager Dispatcher và Cloudflare CDN đối với URL bundle commons để toàn bộ người dùng nhận ngay bản vá mới.
Phase 03 - Kiểm thử E2E Đa Thiết Bị
Xác nhận luồng chuyển đổi Guest → Member cho kịch bản đặt 2 phòng và 3 phòng kèm Add-on trên Desktop Chrome, Safari iOS và Chrome Android.