Sơ đồ Quy trình & Use Case toàn diện của TravelSys
Tổng quan và chi tiết hoá toàn bộ luồng vận hành của hệ sinh thái — cập nhật trọng tâm mới: nền tảng quản lý Host với nhật ký tương tác realtime Host↔Khách (chat, giọng nói, hình ảnh, AI) đóng vai trò bằng chứng có giá trị pháp lý/vận hành.
Kiến trúc tổng thể — cập nhật với lớp Nhật ký Tương tác
So với bản kiến trúc gốc, hệ thống bổ sung một lớp trung tâm mới: Nhật ký tương tác & bằng chứng (Conversation Layer) — nằm giữa các ứng dụng Client/Host và hệ thống Ký quỹ & Tranh chấp. Đây là nơi mọi hội thoại, xác nhận, bằng chứng thanh toán được ghi lại có cấu trúc, thay vì rải rác trong tin nhắn tự do.
4 vai trò chính trong hệ sinh thái
Use case của End Client và Host đều được mở rộng thêm nhóm hành vi liên quan tới Nhật ký tương tác (đánh dấu ★ MỚI). Đây là những use case nên ưu tiên thiết kế UI/UX kỹ nhất vì được dùng hàng ngày.
End Client — Khách du lịch
Tìm, đặt và theo dõi dịch vụ; giờ có thêm kênh trao đổi trực tiếp & minh bạch với Host.
- Tìm kiếm & lọc dịch vụ theo địa điểm/ngày/giá/loại hình
- Xem chi tiết listing, đọc đánh giá 2 chiều
- Gửi yêu cầu đặt chỗ (booking request)
- ★ Chat realtime riêng tư với Host — hỏi đáp trước/sau khi đặt
- ★ Gửi ảnh (chứng từ chuyển khoản, giấy tờ) / ghi âm voice trong chat
- Nhận thông báo real-time khi Host xác nhận / từ chối
- ★ Xem lại timeline bằng chứng: đã đặt trước, đã thanh toán, đã hoàn tiền
- Đánh giá Host sau chuyến đi
- ★ Báo cáo vấn đề / mở tranh chấp — đính kèm trực tiếp đoạn chat làm bằng chứng
Host — Chủ cơ sở / dịch vụ
Người dùng nền tảng hàng ngày, nhiều nhất — Inbox hội thoại là màn hình trung tâm, không phải danh sách listing.
- Đăng ký, xác minh danh tính (giấy phép KD / CCCD)
- Tạo/quản lý listing, giá theo mùa, tồn kho
- ★ Inbox hội thoại — trả lời tất cả yêu cầu/khách đang trò chuyện tại 1 nơi
- Xác nhận / từ chối yêu cầu đặt chỗ trong luồng chat
- ★ Gắn nhãn Action: "Đã nhận thanh toán" kèm ảnh chứng từ
- ★ Gắn nhãn Action: "Đã hoàn tiền" kèm số tiền, lý do
- ★ Xem lại toàn bộ timeline tương tác với 1 khách cụ thể
- Quản lý ký quỹ — nạp quỹ, xem lịch sử trích/nạp
- Phản hồi khi bị mở tranh chấp (dùng chính nhật ký chat để giải trình)
Admin / Vận hành
Đội ngũ nội bộ nền tảng — vai trò trọng tài, dùng nhật ký chat làm nguồn sự thật khi có tranh chấp.
- Kiểm duyệt hồ sơ Host mới, xác minh giấy tờ
- Giám sát chất lượng: GMV, tỷ lệ huỷ, NPS
- ★ Xét duyệt tranh chấp — truy xuất nguyên văn nhật ký chat + action đã gắn nhãn
- Ra quyết định, gửi lệnh trích quỹ ký quỹ khi Host sai
- ★ Giám sát AI: rà soát các Action do AI gợi ý nhưng bị Host bỏ qua/từ chối nhiều lần
- Phát hiện gian lận / lạm dụng cơ chế tranh chấp từ 2 phía
AI Agent (hệ thống)
Không phải actor có giao diện riêng — chạy nền, hỗ trợ 3 vai trò trên ngay trong luồng chat.
- Agent Client: tư vấn, tìm kiếm ngữ nghĩa (semantic search)
- Agent Host: tự sinh mô tả chuẩn SEO, gợi ý giá theo mùa
- ★ Speech-to-Text: chuyển voice message thành text có thể tìm kiếm
- ★ Vision/OCR: đọc ảnh chứng từ chuyển khoản → gợi ý số tiền, thời gian, mã GD
- ★ Gợi ý gắn nhãn Action từ nội dung tin nhắn — Host luôn phải xác nhận trước khi ghi log chính thức (tránh AI tự ý xác nhận sai)
- Phát hiện bất thường trong hội thoại (ngôn từ đe doạ, dấu hiệu lừa đảo) → cảnh báo đội CS
Từ tìm kiếm đến đánh giá — luồng đầy đủ (12 bước)
Sequence diagram dưới đây thêm hẳn 1 "lane" riêng cho Conversation Log để thấy rõ: không phải mọi tương tác đều chỉ nằm giữa Client↔Host — các mốc quan trọng (xác nhận, thanh toán, hoàn tiền) đều được ghi lại có cấu trúc vào hệ thống, không chỉ là chat tự do.
Nhật ký Tương tác & Bằng chứng (Host ↔ Client)
Mục tiêu cốt lõi được nêu ra: TravelSys không chỉ là nơi đặt chỗ, mà là nền tảng quản lý toàn diện cho Host — trong đó, hội thoại với khách không phải "tính năng phụ", mà là nhật ký vận hành có giá trị bằng chứng: ai đã xác nhận gì, khi nào, kèm bằng chứng gì.
4.1 — Kiến trúc realtime
Tách 2 luồng dữ liệu: tin nhắn "sống" (realtime, cần độ trễ thấp) đi qua Firestore (client SDK lắng nghe trực tiếp — Cloud Run không giữ WebSocket lâu dài nên không phù hợp); còn Action đã được Host xác nhận thì ghi xuống Postgres làm nguồn sự thật có cấu trúc, cùng pattern append-only đã dùng cho Deposit Ledger (mục 4.9 tài liệu gốc).
4.2 — Mô hình dữ liệu
3 entity mới (Conversation, Message,
ActionEvent) gắn vào BookingRequest đã có sẵn —
không phải viết lại module Booking Engine.
4.3 — Danh mục Action (nhãn gắn trong chat)
Đây là bảng cần Founder rà soát kỹ nhất — danh sách Action quyết định UI nút bấm trong chat, và quyết định Admin sẽ thấy gì khi xét tranh chấp. Có thể thêm/bớt/đổi tên.
| Action code | Nhãn hiển thị | Ai gắn được | Bằng chứng đính kèm | Ghi chú |
|---|---|---|---|---|
booking_requested |
Đã gửi yêu cầu | Hệ thống (tự động) | Snapshot booking | Tạo tự động khi client gửi request — không cần Host thao tác |
booking_confirmed |
Đã xác nhận đặt phòng | Host | — | Mở khoá thông tin liên hệ 2 chiều |
booking_rejected |
Đã từ chối yêu cầu | Host | Lý do (text, tuỳ chọn) | Nhả soft-hold tồn kho ngay lập tức |
prepayment_received |
Đã nhận tiền đặt trước | Host | Ảnh chuyển khoản (khuyến khích) | AI gợi ý số tiền/thời gian từ ảnh — Host xác nhận |
balance_received |
Đã nhận đủ số tiền còn lại | Host | Ảnh chuyển khoản (khuyến khích) | Có thể lặp lại nếu thanh toán nhiều lần |
refund_issued |
Đã hoàn tiền | Host | Ảnh chuyển khoản + lý do (bắt buộc) | Không thể sửa/xoá sau khi lưu (append-only) |
check_in_confirmed |
Đã nhận phòng | Host hoặc Client | Ảnh (tuỳ chọn) | Có thể do 1 trong 2 bên xác nhận trước |
check_out_confirmed |
Đã trả phòng | Host hoặc Client | — | Điều kiện để mở tính năng đánh giá 2 chiều |
issue_reported |
Báo cáo sự cố | Host hoặc Client | Ảnh/mô tả | Mức nhẹ — chưa kích hoạt quy trình tranh chấp chính thức |
dispute_opened |
Mở tranh chấp | Client hoặc Host | Toàn bộ Conversation Log | Mở giai đoạn tự thoả thuận (mục 4.9, v2.0) — KHÔNG khoá log ngay; chỉ khoá khi escalate lên bước trung gian |
dispute_resolved |
Tranh chấp đã xử lý | Admin | Quyết định + số tiền bồi thường (nếu có) | Có mức trần bồi thường, không vô hạn (mục 4.9) |
4.4 — Kịch bản chi tiết
4.5 — Xử lý đa phương tiện (Text · Voice · Image)
Quan trọng cho Host lớn tuổi/không rành công nghệ (nguyên tắc cốt lõi #1 của tài liệu gốc: "không yêu cầu kiến thức kỹ thuật") — Host có thể nói thay vì gõ, chụp ảnh thay vì nhập liệu.
Từ nhật ký chat rời rạc → gói bằng chứng có cấu trúc
Tài liệu kiến trúc gốc (mục 4.9) mô tả bằng chứng tranh chấp là "ảnh, tin nhắn, booking log" — nhưng không nói rõ định dạng. Với Conversation Layer, Admin không phải đọc lại hàng chục tin nhắn rời rạc — mà xem 1 timeline đã được cấu trúc hoá theo từng booking.
Minh hoạ: màn hình Admin xem xét tranh chấp
Gọi thoại realtime Host↔Client — mục 4.11
Sau khi Nhật ký Tương tác (mục 4) đi vào code, bước tiếp theo được thống nhất: gọi thoại trực tiếp trong app cho các tình huống cần nhanh hơn gõ chữ (hỏi gấp trước giờ nhận phòng, xử lý sự cố tại chỗ). Đồng thời chốt không dùng Convex cho lớp realtime nói chung.
| Đề xuất | Quyết định | Lý do |
|---|---|---|
| LiveKit (gọi thoại Host↔Client) | ✅ Đã code & test | LiveKit Agents là framework Python — khớp thẳng FastAPI, không tạo runtime thứ 2. Hạ tầng production-grade (cấp WebRTC cho ChatGPT voice mode, Salesforce Agentforce). |
| File storage (ảnh/voice trong chat) | ✅ Google Cloud Storage | Đúng định hướng tập trung hệ sinh thái Google — đã có abstraction layer local/gcs, đổi bằng 1 biến môi trường. |
| AI voice agent (Host Copilot nói chuyện thay Host) | ⏸ Tiện ích mở rộng | Giữ đúng định hướng đã thống nhất: chỉ phát triển khi có Host thực sự cần, không xây trước khi có người dùng thật. LiveKit Agents (Python) đã sẵn sàng cắm vào khi cần. |
Kiến trúc — backend chỉ cấp token, không truyền tải audio
Kịch bản chi tiết — Client gọi Host
livekit-api — ký một
webhook giả lập đúng cách LiveKit server ký thật, verify thành công trước khi viết endpoint.
Test luôn cả đường lỗi: người ngoài hội thoại không lấy được token, chữ ký webhook sai bị từ
chối (401), và UI hiển thị đúng thông báo khi chưa cấu hình LIVEKIT_API_KEY
(503, không crash).
Toàn bộ entity — bản gốc + 3 entity mới
Nhìn tổng thể để thấy rõ: Conversation/Message/ActionEvent chỉ "cắm thêm" vào giữa
BookingRequest và Dispute đã có sẵn —
không đụng vào cụm User/Listing hay cụm Ký quỹ.
Nhật ký Tương tác chuyển từ "sau này" thành "cốt lõi"
Vì Founder xác nhận đây là mục tiêu chính của hệ sinh thái (không phải tính năng phụ), đề xuất đẩy phần lõi (chat text + gắn nhãn Action thủ công) lên ngay Phase 1 — còn phần AI xử lý voice/image vẫn ở Phase 3 như cũ, vì AI là "tăng tốc" chứ không phải điều kiện để chat hoạt động.
| Phase | Trước (roadmap gốc) | Sau (cập nhật) |
|---|---|---|
| Phase 0 Nền móng |
Kiến trúc DB, thiết kế UX, chọn 1 vertical | + Thiết kế schema Conversation/Message/ActionEvent song song (mục 4.2) |
| Phase 1 MVP |
Client tìm & gửi yêu cầu, Host xác nhận/từ chối, trao đổi liên hệ sau xác nhận | ★ Bổ sung Chat text realtime (Firestore) + gắn nhãn 6 Action cơ bản (confirmed/rejected/payment_received/refund_issued/check_in/check_out) — chưa cần AI |
| Phase 2 Ký Quỹ & Tranh chấp |
Đối tác ký quỹ, Deposit Ledger, quy trình xét duyệt tranh chấp | Không đổi nghiệp vụ — nhưng Admin console xét duyệt giờ đọc trực tiếp Conversation Log (mục 05) thay vì hỏi thủ công 2 bên |
| Phase 3 AI Agent v1 |
Chatbot tư vấn client, Host copilot sinh mô tả/SEO | ★ Bổ sung Speech-to-Text cho voice message + Vision/OCR đọc ảnh chứng từ + gợi ý gắn nhãn Action (mục 4.5) |
| Phase 4-6 | SEO/Scale, mở rộng dịch vụ/khu vực, vận hành bền vững | Không đổi — Conversation Layer thiết kế đa ngôn ngữ ngay từ Phase 1 nên không chặn Phase 5 |
8 quyết định Founder nên rà soát trước khi code
Tài liệu này là bản nháp để bạn đánh giá & thay đổi — dưới đây là những điểm có nhiều hơn 1 cách làm hợp lý, nên cố tình để mở thay vì tự quyết định thay bạn.
Firestore hay tự build WebSocket trên Cloud Run?
Đề xuất Firestore vì Cloud Run không giữ kết nối lâu dài tốt. Nhưng nếu sau này cần logic phức tạp hơn (VD: mã hoá đầu-cuối), có thể cần đổi hướng.
Danh mục 11 Action (mục 4.3) đã đủ chưa?
Có cần thêm cancelled_by_client, no_show,
extra_charge_requested (phụ phí phát sinh) không?
Có cho phép sửa/thu hồi tin nhắn thường không?
✅ Đã quyết định & code (v2.1): Action vẫn append-only tuyệt đối. Tin nhắn chat thường (chưa gắn Action) thì CÓ cho sửa/thu hồi — nhưng chỉ đúng tin CUỐI CÙNG, và chỉ khi người nhận chưa đọc tới đó. Nội dung gốc không mất khỏi hệ thống (soft-delete), Admin vẫn thấy bản gốc khi xét tranh chấp — xem mục 4.10 tài liệu tổng quan.
Giới hạn & chi phí lưu trữ voice/image?
Giới hạn thời lượng voice (VD: 60s)? Lưu file gốc bao lâu — vĩnh viễn (chi phí Cloud Storage tăng dần) hay có chính sách archive sau N tháng?
Khi nào "issue_reported" tự leo thang thành "dispute_opened"?
Có ngưỡng thời gian tự động không (VD: Host không phản hồi issue trong 48h → gợi ý client mở tranh chấp), hay luôn cần client bấm thủ công?
Giới hạn lượt AI xử lý miễn phí / Host / tháng?
Speech-to-Text và Vision API tính phí theo lượt gọi — cần khung miễn phí bao nhiêu lượt trước khi tính vào chi phí vận hành (liên quan mục 7 ước tính chi phí tài liệu gốc)?
Đa ngôn ngữ trong Conversation Log?
Khách quốc tế chat tiếng Anh, Host trả lời tiếng Việt — có cần dịch tự động 2 chiều ngay trong khung chat không, hay để giai đoạn sau (đi cùng đa ngôn ngữ Phase 5)?
Có cần "read receipt" (đã xem) để tính response_rate không?
Một phần đã quyết định (v2.1):
Read receipt đơn giản (2 cột thời điểm đọc cuối, không phải per-message) đã có — nhưng
hiện chỉ dùng để gate việc sửa/thu hồi tin nhắn cuối, chưa dùng để tính lại
response_rate. Founder vẫn cần chốt: có nên đổi công thức
response_rate sang dựa trên thời điểm đọc thay vì thời điểm
trả lời không, giờ đã có dữ liệu để làm việc đó nếu muốn.
3 quyết định mới phát sinh (v1.9–v2.2, tháng 09/2026)
3 tham số dưới đây đang dùng giá trị mặc định hợp lý trong code — Founder chưa xác nhận, đổi được ở đúng 1 chỗ trong code khi đã quyết định.
Tỉ lệ đảm bảo ký quỹ (coverage ratio) nên là bao nhiêu?
Rule hiện tại (v1.9): số dư ký quỹ phải ≥ 1.0× tổng nghĩa vụ đang treo (giá trị
booking đang hoạt động × trần bồi thường 50%) — mới cho phép xác nhận booking mới.
1.0 là mặc định thận trọng, áp dụng như nhau cho MỌI host. Có nên nới cho host uy tín
cao (VD 0.7×) và siết với host mới (VD 1.5×) không?
DEFAULT_COVERAGE_RATIO trong deposit_service.py.
Cửa sổ tự thoả thuận trước khi tự động escalate là bao nhiêu ngày?
Mặc định 3 ngày (v2.0): nếu 1 tranh chấp nằm ở bước "tự thoả thuận" quá lâu mà
không ai xử lý, hệ thống tự chuyển sang bước trung gian. 3 ngày có đủ cho 2 bên thật
sự trao đổi chưa, hay nên dài/ngắn hơn tuỳ loại dịch vụ (homestay dài ngày vs vé/tour
ngắn hạn)? DEFAULT_SELF_NEGOTIATION_DAYS trong
dispute_service.py.
Cửa sổ "đánh giá gần đây" nên là bao nhiêu ngày?
Mặc định 180 ngày (v2.2): hồ sơ Host/Client hiển thị SONG SONG điểm toàn thời gian
và điểm trong 180 ngày gần nhất, để 1 sai lầm cũ không đè mãi lên hồ sơ. 180 ngày
(~6 tháng) có phải khoảng thời gian phù hợp với nhịp độ dùng thực tế của Host/Client
không? REVIEW_RECENT_WINDOW_DAYS trong
review_service.py.