Bài toán

Thương hiệu cần một trò chơi ngắn, vui để khách tham gia ngay tại sự kiện: khách để lại số điện thoại, chơi một lượt vài giây và nhận quà nếu thắng. Ban tổ chức cần theo dõi số lượt chơi, tỉ lệ thắng/thua theo từng sản phẩm và xuất danh sách để trao quà, chăm sóc sau sự kiện.

Chức năng chính

  • Màn hình bắt đầu mang nhận diện Hanoimilk, nút "BẮT ĐẦU" có hiệu ứng thu hút.
  • Nhập số điện thoại bằng bàn phím số trên màn hình, kiểm tra định dạng số Việt Nam (10 số, bắt đầu bằng 0) trước khi cho chơi.
  • Chọn sản phẩm: sữa chua, sữa hộp, sữa tươi 100%.
  • Gameplay "ghép hình": ảnh sản phẩm được cắt thành 4 mảnh A–B–C–D, xáo trộn có hoạt ảnh; người chơi chọn lại đúng thứ tự trong 10 giây có đồng hồ đếm ngược.
  • Kết quả: màn hình BINGO với pháo giấy khi thắng; màn hình "Ôi, tiếc quá" khi sai hoặc hết giờ; nút chơi lại.
  • Âm thanh: nhạc nền và hiệu ứng chạm/thắng/thua (Web Audio).
  • Lưu kết quả an toàn: lượt chơi được đưa vào hàng đợi trong trình duyệt rồi đồng bộ lên server, nên không mất dữ liệu khi mạng chập chờn; API có chống CSRF (double-submit cookie); ghi nhận thông tin thiết bị truy cập.
  • Dashboard ban tổ chức: thẻ KPI (tổng lượt chơi, thắng, thua, tỉ lệ thắng), biểu đồ theo ngày, tỉ lệ thắng/thua, sản phẩm được chọn, tỉ lệ thắng theo sản phẩm; nhật ký lượt chơi có tìm theo số điện thoại, phân trang; tự làm mới 30 giây/lần; tải file CSV.

Công nghệ

  • Frontend: Vite + JavaScript thuần, CSS animation, tối ưu thao tác chạm (bỏ độ trễ 300 ms, chống "ghost click"), tự co giãn theo màn hình.
  • Backend: Node.js + Express, lưu kết quả ra file CSV và log truy cập.
  • Dashboard: Chart.js + chartjs-plugin-datalabels.
  • Triển khai: Docker (multi-stage build), GitLab CI build và đẩy image.

Điểm ưu việt

  • Gọn nhẹ, không cần cơ sở dữ liệu, chạy được trên một container nhỏ; dễ dựng nhanh cho từng sự kiện.
  • Trải nghiệm cảm ứng mượt, thời gian chơi ngắn (10 giây) phù hợp đông khách tại điểm bán.
  • Dữ liệu thu thập được dùng ngay: xem thống kê trực tiếp và xuất CSV để trao quà/chăm sóc khách.
  • Có lớp bảo vệ cơ bản (CSRF, kiểm tra dữ liệu đầu vào) và hàng đợi offline chống mất lượt chơi.