Giới thiệu dự án

Theo số liệu từ Trung tâm Internet Việt Nam (VNNIC), tính đến đầu năm 2021, Việt Nam có 68,72 triệu người sử dụng Internet, chiếm tới 70,3% dân số. Sự bùng nổ của hạ tầng số kéo theo sự thay đổi sâu sắc trong hành vi người tiêu dùng, đặc biệt ở lĩnh vực du lịch và lưu trú trực tuyến (Online Travel Agencies - OTA). Mô hình căn hộ dịch vụ và homestay trở thành xu hướng lưu trú nổi bật của giới trẻ nhờ không gian riêng tư, tiện nghi linh hoạt và chi phí hợp lý. Tuy nhiên, các giải pháp công nghệ hiện hành đang bộc lộ những rào cản lớn:

  • Thiếu tính kết nối cộng đồng: Các nền tảng thương mại truyền thống thuần túy cung cấp danh sách bất động sản tĩnh, tách rời khỏi tương tác xã hội thực tế và trải nghiệm chân thực của người dùng.
  • Hiệu năng tìm kiếm hạn chế: Các hệ thống cơ sở dữ liệu quan hệ (RDBMS) thuần túy gặp tắc nghẽn hiệu năng khi xử lý tìm kiếm toàn văn (full-text search) kết hợp lọc đa chiều theo vị trí địa lý.
  • Độ tin cậy của thông tin: Người thuê nhà khó kiểm chứng độ xác thực của các bài đánh giá do thiếu liên kết mạng lưới bạn bè (social graph) hỗ trợ kiểm tra chéo độ tin cậy.

Xuất phát từ bối cảnh đó, đề tài "Xây dựng Hệ thống quản lý cộng đồng đặt và cho thuê căn hộ HomeLike" do sinh viên Nguyễn Sỹ Quang Anh (Khoa CNTT 1, Học viện Công nghệ Bưu chính Viễn thông - PTIT) thực hiện dưới sự hướng dẫn của ThS. Nguyễn Mạnh Sơn đã ra đời nhằm giải quyết bài toán giao thoa giữa mạng xã hội và nền tảng đặt phòng trực tuyến.

+-------------------------------------------------------------------------+
|                          HỆ THỐNG HOMELIKE                              |
+------------------------------------+------------------------------------+
|       MÔ HÌNH MẠNG XÃ HỘI          |        MÔ HÌNH ĐẶT PHÒNG           |
|  - Feed bài viết & Đánh giá        |  - Tìm kiếm toàn văn Elasticsearch |
|  - Graph quan hệ Follower/Followed |  - Bản đồ tương tác LeafletJS      |
|  - Tương tác Like, Comment, Share  |  - Thanh toán & Trả tiền lời PayPal|
+------------------------------------+------------------------------------+

Mục tiêu dự án

  1. Thiết kế và cài đặt kiến trúc tích hợp giữa mạng xã hội chia sẻ trải nghiệm lưu trú và sàn giao dịch đặt/cho thuê homestay theo thời gian thực.
  2. Tối ưu hóa công cụ tìm kiếm dữ liệu căn hộ bằng engine phân tán Elasticsearch dựa trên thuật toán tính điểm mức độ liên quan TF/IDF.
  3. Trực quan hóa vị trí địa lý của bất động sản trên bản đồ số thông qua thư viện mã nguồn mở LeafletJS kết hợp dữ liệu OpenStreetMap.
  4. Hiện thực hóa luồng thanh toán hai chiều (Orders & Payouts API) an toàn, tự động hóa qua cổng quốc tế PayPal.

Phương pháp tiếp cận và Phạm vi

  • Phương pháp: Tách biệt hoàn toàn Frontend (ReactJS SPA) và Backend (Ruby on Rails RESTful API), đảm bảo nguyên tắc Stateless, kiến trúc phân lớp hướng dịch vụ và chuẩn mực bảo mật JSON Web Token (JWT).
  • Phạm vi hệ thống: Ứng dụng web phục vụ 3 nhóm tác nhân chính (Khách hàng, Chủ căn hộ, Quản trị viên); tập trung vào thị trường homestay/căn hộ lưu trú ngắn ngày tại Việt Nam; xử lý giao dịch thanh toán trực tuyến và luồng quản lý nội dung số tương tác.

Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Tiêu chí Nền tảng OTA truyền thống (Agoda, Booking) Nhóm mạng xã hội (Facebook Groups) Hệ thống HomeLike
Tìm kiếm & Định vị Tốt trên RDBMS/Bộ lọc cố định Kém, phụ thuộc thuật toán newsfeed Xuất sắc (Elasticsearch TF/IDF + LeafletJS)
Tính tương tác xã hội Không có hoặc rất hạn chế Cao nhưng phân tán, thiếu quy chuẩn Cao (Social Feed gắn trực tiếp Entity căn hộ)
Bảo chứng chất lượng Đánh giá ẩn danh, dễ bị thao túng Dễ lừa đảo, không kiểm soát giao dịch Minh bạch qua Social Network Graph
Quy trình thanh toán Tự động, phí trung gian cao (15-25%) Thủ tục chuyển khoản thủ công, rủi ro Tích hợp tự động PayPal Orders & Payouts

Phân loại yêu cầu người dùng theo mô hình MoSCoW

  • Must Have (Bắt buộc): Đăng nhập/Đăng ký xác thực JWT; Quản lý hồ sơ cá nhân; Đăng tải bài viết kèm link gắn căn hộ; Tìm kiếm căn hộ toàn văn bản; Hiển thị vị trí trên bản đồ LeafletJS; Đặt phòng và thanh toán qua PayPal Orders API; Quản lý duyệt căn hộ/người dùng bởi Admin.
  • Should Have (Nên có): Theo dõi/Hủy theo dõi người dùng (Follow/Unfollow); Bình luận đa cấp; Phân tách phí phụ thu quá số người quy định (extra_fee_each_person); Rút tiền cho chủ nhà qua PayPal Payouts API.
  • Could Have (Có thể có): Lọc nâng cao theo tiện ích (Facility) và thẻ phân loại (Tag); Gợi ý căn hộ dựa trên bài đăng có lượt tương tác cao.
  • Won't Have (Chưa thực hiện): Triển khai phân tán nhiều cụm Node Elasticsearch (Cluster sharding ngang) trong phiên bản thử nghiệm.

Thiết kế kiến trúc và Cơ sở dữ liệu

Hệ thống hoạt động theo mô hình Client-Server hiện đại, phân tách trách nhiệm rõ ràng:

[ Client: ReactJS SPA ] 
        |  ^  (HTTPS / RESTful JSON / Bearer JWT)
        v  |
[ Web Server Gateway / Nginx ]
        |
[ Application Server: Ruby on Rails (Puma) ]
   |                  |                   |
   v                  v                   v
[ MySQL Database ] [ Elasticsearch Engine ] [ PayPal Gateway ]
(ACID Transaction)  (Inverted Index)         (Orders/Payouts)
+--------------------------------------------------------------------+
|                         LƯỢC ĐỒ CƠ SỞ DỮ LIỆU                      |
+--------------------------------------------------------------------+
| [User] 1---1 [FullName]                                            |
|   | 1                                                              |
|   +---n [RefreshToken]                                             |
|   +---n [Relationship] (follower / followed)                       |
|   +---n [User_Role] n---1 [Role]                                   |
|   +---n [Post] 1---n [Comment]                                     |
|   |       | 1                                                      |
|   |       +---n [Likes]                                            |
|   |       +---n [Post_Item] n---1 [Item] (Căn hộ cho thuê)         |
|   |                                  | 1                           |
|   +---n [Order] 1---1 [Payment]      +---1 [Apartment]             |
|           | 1                        |       | 1                   |
|           +---1 [Payout]             |       +---n [Address]       |
|                                      |       +---n [Apartment_Fac] |
|                                      +---n [Review]                |
|                                      +---n [Item_Tag] n---1 [Tag]  |
+--------------------------------------------------------------------+

Thiết kế bảng dữ liệu cốt lõi

  1. User: id (PK), username, password_digest, email, follower_count, following_count, phone_number, avatar_url.
  2. Apartment: id (PK), title, size, initial_allowance, max_allowance, extra_fee_each_person, rent_address.
  3. Item (Đại diện cho trạng thái niêm yết): id (PK), apartment_id (FK), rate, status, price, initial_start_date, initial_rent_date, description, is_out_of_stock.
  4. Order: id (PK), customer_id (FK), item_id (FK), total, extra_price, total_paid, start_rent_date, end_rent_date, customer_quantity, status.
  5. Relationship: id (PK), follower_id (FK), followed_id (FK).

Thiết kế bảo mật và cơ chế xác thực JWT

Quy trình xác thực người dùng áp dụng chiến lược mã hóa kép hai token:

  • access_token: Có thời gian sống ngắn (15 phút), lưu trữ trên bộ nhớ tạm (in-memory) hoặc header của client để truy cập các tài nguyên bảo vệ.
  • refresh_token: Có thời gian sống dài (7 ngày), lưu trữ an toàn trong bảng RefreshToken (kèm trạng thái thu hồi) nhằm cấp phát lại token mới mà không yêu cầu đăng nhập lại, giảm nguy cơ giả mạo phiên làm việc.

Implementation và kết quả

Quy trình phát triển và Công nghệ tích hợp

Dự án được triển khai theo quy trình lặp dựa trên phương pháp Agile/Scrum. Mã nguồn Backend được xây dựng hoàn toàn trên nền tảng Ruby on Rails (Ruby 3.x, Rails 6.x) kết hợp MySQL 8.0Elasticsearch 7.x. Phía Frontend sử dụng ReactJS 17.x (Hooks, Context API, React-Router) kết hợp LeafletJS 1.7.x.

Thuật toán tính điểm liên quan trong Elasticsearch (TF/IDF Engine)

Khi người dùng thực hiện truy vấn tìm kiếm căn hộ, Elasticsearch sử dụng inverted index và chấm điểm dựa trên công thức phối hợp TF/IDF và độ dài trường:

$$\text{Score}(q, d) = \sum_{t \in q} \text{IDF}(t) \cdot \text{TF}(t, d) \cdot \text{norm}(d)$$

Trong đó:

  • Term Frequency (TF): $\text{TF}(t, d) = \sqrt{\text{frequency}(t, d)}$ (Đo lường tần suất từ khóa $t$ xuất hiện trong văn bản $d$).
  • Inverse Document Frequency (IDF): $\text{IDF}(t) = 1 + \ln\left(\frac{\text{numDocs}}{\text{docFreq}(t) + 1}\right)$ (Phạt các từ khóa quá phổ biến, tăng điểm cho các từ khóa hiếm).
  • Field-length norm: $\text{norm}(d) = \frac{1}{\sqrt{\text{numFieldTerms}}}$ (Ưu tiên các kết quả khớp ở tiêu đề ngắn hơn là nội dung mô tả dài).
# app/services/apartment_search_service.rb
class ApartmentSearchService
  def initialize(query_params)
    @keyword = query_params[:keyword]
    @min_price = query_params[:min_price]
    @max_price = query_params[:max_price]
  end

  def execute
    search_definition = {
      query: {
        bool: {
          must: [
            {
              multi_match: {
                query: @keyword,
                fields: ['title^3', 'description', 'address.city^2', 'address.district'],
                fuzziness: 'AUTO'
              }
            }
          ],
          filter: [
            { range: { price: { gte: @min_price || 0, lte: @max_price || 100_000_000 } } },
            { term: { is_out_of_stock: false } }
          ]
        }
      }
    }
    Elasticsearch::Model.client.search(index: 'items', body: search_definition)
  end
end

Tích hợp bản đồ trực quan với LeafletJS trên ReactJS

Để giảm thiểu chi phí thương mại đắt đỏ của Google Maps API, hệ thống sử dụng thư viện LeafletJS (kích thước nén chỉ 38KB), liên kết lớp ngói bản đồ (map tiles) từ OpenStreetMap:

// src/components/ApartmentMap.jsx
import React, { useEffect } from 'react';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';

const ApartmentMap = ({ apartments, centerCoords }) => {
  useEffect(() => {
    const map = L.map('map-container').setView([centerCoords.lat, centerCoords.lng], 13);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    }).addTo(map);

    apartments.forEach((apt) => {
      const customPopup = `
        <div class="p-2">
          <h4 class="font-bold">${apt.title}</h4>
          <p class="text-red-500 font-semibold">${apt.price.toLocaleString('vi-VN')} VNĐ/ngày</p>
          <a href="/apartments/${apt.id}" class="text-blue-600 underline">Xem chi tiết</a>
        </div>
      `;
      L.marker([apt.latitude, apt.longitude])
        .addTo(map)
        .bindPopup(customPopup);
    });

    return () => map.remove();
  }, [apartments, centerCoords]);

  return <div id="map-container" style={{ height: '550px', width: '100%' }} />;
};

export default ApartmentMap;

Kết quả kiểm thử và Đánh giá hiệu năng

+--------------------------------------------------------------------+
|                 SO SÁNH THỜI GIAN ĐÁP ỨNG TRUY VẤN                 |
+--------------------------------------------------------------------+
| 1000 requests | MySQL LIKE Query        [=========>] 840ms         |
|               | Elasticsearch TF/IDF    [==>] 112ms                |
+--------------------------------------------------------------------+

Dữ liệu Benchmark và Kiểm thử tải

  • Tốc độ phản hồi tìm kiếm: Trên tập dữ liệu 15.000 bản ghi căn hộ, truy vấn phức tạp kết hợp từ khóa và bộ lọc vị trí bằng Elasticsearch chỉ mất trung bình 112ms, trong khi truy vấn SQL truyền thống bằng mệnh đề LIKE %...% mất 840ms (tăng tốc độ truy xuất hơn 7,5 lần).
  • Tối ưu tải trang Frontend (SPA): Nhờ cơ chế Virtual DOM diffing của ReactJS và đóng gói bundle thông qua Webpack, dung lượng tải xuống lần đầu đạt 420KB (gzipped). Các thao tác chuyển trang chỉ tiêu thụ băng thông cho JSON payload trung bình 18KB/request, mang lại trải nghiệm mượt mà không bị reload trắng màn hình.
  • Kiểm thử tích hợp cổng thanh toán (UAT): Thực hiện 120 kịch bản thanh toán qua PayPal Sandbox (bao gồm: giao dịch hợp lệ, số dư không đủ, hủy ngang giữa chừng, lỗi xác thực callback IPN). Tỷ lệ ghi nhận trạng thái đơn hàng chính xác đạt 100%, không xảy ra tình trạng trừ tiền sai lệch (ghost transactions).

Đổi mới và đóng góp

  1. Hội tụ mô hình Mạng xã hội và Sàn giao dịch Bất động sản: Khác biệt với mô hình truyền thống, HomeLike cho phép một bài viết (Post) liên kết trực tiếp với một hoặc nhiều thực thể căn hộ (Item) thông qua quan hệ trung gian PostItem. Người dùng có thể đọc bài trải nghiệm thực tế từ bạn bè đang theo dõi (Relationship), nhấn xem trực tiếp căn hộ được gắn thẻ và tiến hành đặt phòng ngay trên giao diện mạng xã hội.
  2. Cơ chế định giá và quản lý phụ phí linh hoạt: Bổ sung thuật toán tính toán phụ phí tự động dựa trên số lượng khách vượt mức quy chuẩn ban đầu: $$\text{TotalPaid} = (\text{Price} \times \text{Days}) + \max(0, \text{CustomerQuantity} - \text{InitialAllowance}) \times \text{ExtraFeeEachPerson} \times \text{Days}$$
  3. Tối ưu hóa chi phí hạ tầng bản đồ số: Việc thay thế các API thương mại đóng gói bằng giải pháp LeafletJS kết hợp OpenStreetMap giúp loại bỏ hoàn toàn chi phí phát sinh khi khối lượng yêu cầu định vị tăng cao, nâng cao tính khả thi trong việc thương mại hóa giải pháp ở giai đoạn đầu khởi nghiệp.

Ứng dụng thực tế và triển khai

Kịch bản sử dụng thực tế

+-----------------------------------------------------------------------------+
|                           KỊCH BẢN NGƯỜI DÙNG THỰC TẾ                       |
+-----------------------------------------------------------------------------+
| [Chủ nhà (Merchant)]                                                        |
|   -> Đăng ký tài khoản -> Khởi tạo Căn hộ & Tiện ích -> Đính kèm Ảnh        |
|                                                                             |
| [Người có ảnh hưởng (KOL / User)]                                           |
|   -> Đăng bài trải nghiệm -> Gắn link căn hộ vào Post                       |
|                                                                             |
| [Khách thuê (Customer)]                                                     |
|   -> Xem Feed bài viết -> Nhấp xem căn hộ trên Bản đồ -> Đặt phòng & Trả tiền |
|                                                                             |
| [Hệ thống tự động]                                                          |
|   -> Xác thực Orders API -> Cập nhật Đơn thuê -> Thanh toán qua Payouts API |
+-----------------------------------------------------------------------------+
  • Chủ căn hộ (Merchant): Tạo danh mục căn hộ chi tiết, quản lý trạng thái phòng trống theo thời gian thực và nhận thanh toán tự động qua PayPal Payouts sau khi đơn đặt hoàn tất.
  • Người trải nghiệm (KOL/Influencer): Đăng tải các bài viết review chuyến đi, gắn thẻ trực tiếp link căn hộ để giới thiệu đến mạng lưới người theo dõi (Followers).
  • Khách du lịch (Customer): Khám phá homestay qua bài đánh giá của mạng lưới bạn bè tin cậy, tra cứu vị trí địa lý trực quan qua bản đồ số LeafletJS và thực hiện đặt phòng với cam kết giao dịch an toàn.

Yêu cầu triển khai hệ thống (Deployment Architecture)

  • Hạ tầng máy chủ tối thiểu: 2 vCPU, 4GB RAM, 40GB SSD (hệ điều hành Ubuntu Server 20.04 LTS).
  • Phần mềm nền tảng: Docker Engine 20.10+, Docker Compose, Nginx Reverse Proxy, Ruby 3.0.x, Node.js 16.x, MySQL 8.0, Elasticsearch 7.14.x.
  • Khả năng mở rộng: Hệ thống backend hoàn toàn vô trạng thái (Stateless API), dễ dàng mở rộng theo chiều ngang (Horizontal Scaling) bằng cách bổ sung các container Puma phía sau bộ cân bằng tải Nginx Load Balancer khi lưu lượng truy cập gia tăng.

Hạn chế và hướng phát triển

Hạn chế hiện tại

  • Quy mô hạ tầng Elasticsearch: Phiên bản thử nghiệm mới chỉ cấu hình 1 Primary Shard và 1 Replica Shard trên một node duy nhất, chưa triển khai cụm Cluster phân tán đa máy chủ để kiểm thử khả năng chịu lỗi tối đa.
  • Phương thức thanh toán nội địa: Mới chỉ tích hợp cổng quốc tế PayPal, chưa tích hợp các cổng thanh toán nội địa phổ biến tại Việt Nam như VNPay, MoMo, ZaloPay.
  • Thuật toán gợi ý cá nhân hóa: Việc hiển thị bài viết và căn hộ hiện tại chủ yếu dựa trên quan hệ theo dõi trực tiếp và độ mới thời gian, chưa có hệ thống gợi ý tự động (Recommendation System) dựa trên học máy (Machine Learning).

Hướng phát triển trong tương lai

  1. Xây dựng Recommendation Engine: Áp dụng thuật toán Lọc cộng tác (Collaborative Filtering) để tự động phân tích hành vi người dùng, từ đó gợi ý các căn hộ phù hợp với sở thích cá nhân.
  2. Mở rộng nền tảng Mobile App: Xây dựng ứng dụng di động đa nền tảng bằng React Native, đồng bộ toàn bộ luồng dữ liệu thông qua hệ thống RESTful API hiện có.
  3. Tích hợp bản đồ ngoại tuyến và định vị nâng cao: Ứng dụng công nghệ Geofencing để tự động gửi thông báo gợi ý homestay khi người dùng di chuyển đến một địa điểm du lịch cụ thể.

Đối tượng hưởng lợi

  • Sinh viên & Học viên: Cung cấp tài liệu tham khảo hoàn chỉnh về quy trình phân tích thiết kế hướng đối tượng (OOAD), kiến trúc tích hợp giữa Rails API, ReactJS SPA và công cụ tìm kiếm Elasticsearch.
  • Lập trình viên (Developers): Nắm vững cách thức xây dựng cơ chế xác thực kép Access/Refresh Token JWT, kỹ thuật lập trình bản đồ tương tác với LeafletJS và luồng xử lý cổng thanh toán PayPal hai chiều.
  • Chủ doanh nghiệp & Host Homestay: Sở hữu mô hình chuyển đổi số tinh gọn giúp tiếp cận khách hàng tiềm năng thông qua sức mạnh lan tỏa của mạng xã hội, giảm thiểu đáng kể chi phí hoa hồng so với các sàn thương mại điện tử lớn.
  • Nhà nghiên cứu (Researchers): Tài liệu thực nghiệm minh chứng tính hiệu quả của thuật toán TF/IDF trong bài toán tối ưu hóa tìm kiếm bất động sản du lịch trên nền dữ liệu quan hệ kết hợp chỉ mục phân tán.

Câu hỏi thường gặp

1. Yêu cầu phần cứng và môi trường để triển khai hệ thống là gì?

Để vận hành ổn định môi trường thử nghiệm hoặc sản xuất quy mô nhỏ, máy chủ cần tối thiểu 2 vCPU, 4GB RAM (trong đó phân bổ 1.5GB Heap Size cho Elasticsearch JVM), 40GB dung lượng ổ cứng SSD, chạy hệ điều hành Linux (Ubuntu Server 20.04 LTS khuyến nghị), cài đặt Ruby 3.0, Rails 6.1, Node.js 16, MySQL 8.0 và Elasticsearch 7.14.

2. Hệ thống xử lý bài toán quá tải khi lượng người dùng tìm kiếm đồng thời tăng cao như thế nào?

Nhờ việc tách biệt tác vụ tìm kiếm ra khỏi MySQL và giao cho Elasticsearch xử lý, cơ sở dữ liệu chính không bị nghẽn I/O khi có hàng ngàn truy vấn cùng lúc. Khi tải tăng cao, quản trị viên có thể tăng số lượng Replica Shard trong Elasticsearch và nâng cấp máy chủ ứng dụng Rails độc lập mà không cần cấu trúc lại mã nguồn.

3. Việc tích hợp cổng thanh toán PayPal có đảm bảo an toàn thông tin thẻ ngân hàng của người dùng không?

Hệ thống sử dụng cơ chế Client-Side SDK kết hợp Server Verification của PayPal. Toàn bộ thông tin thẻ tín dụng/tài khoản ngân hàng được nhập và xử lý trực tiếp trên giao diện bảo mật của PayPal, máy chủ HomeLike không bao giờ lưu trữ hay tiếp xúc với thông tin nhạy cảm này, tuân thủ tuyệt đối chuẩn bảo mật thanh toán quốc tế PCI-DSS.

4. Chi phí duy trì hệ thống ước tính là bao nhiêu?

Nhờ việc tận dụng các công nghệ mã nguồn mở hoàn toàn miễn phí bản quyền (Ruby on Rails, ReactJS, LeafletJS, OpenStreetMap, MySQL Community Edition, Elasticsearch Open-Source), chi phí duy trì hàng tháng chỉ bao gồm phí thuê máy chủ đám mây (Cloud VPS) khoảng 10 - 20 USD/tháng cho quy mô khởi điểm.


Kết luận

Đồ án tốt nghiệp "Xây dựng Hệ thống quản lý cộng đồng đặt và cho thuê căn hộ HomeLike" của sinh viên Nguyễn Sỹ Quang Anh đã giải quyết trọn vẹn và thực chất bài toán số hóa dịch vụ lưu trú homestay trong thời kỳ bùng nổ kinh tế số. Bằng cách kết hợp linh hoạt mô hình tương tác mạng xã hội với nền tảng đặt phòng trực quan, đồ án không chỉ giải quyết bài toán kỹ thuật phức tạp về hiệu năng tìm kiếm với Elasticsearch và bản đồ LeafletJS, mà còn mở ra hướng tiếp cận kinh doanh sáng tạo, gia tăng sự tin tưởng và gắn kết cộng đồng du lịch trực tuyến. Hệ thống sở hữu kiến trúc vững chắc, tính khả thi cao và sẵn sàng cho các giai đoạn nâng cấp, thương mại hóa trong tương lai.