Meeting (Lịch hẹn họp)

I. Tổng quan

Lưu ý: Các thuộc tính, quy tắc phân quyền và tính năng chung của đối tượng này được kế thừa từ tài liệu Objects (Đối tượng CRM).

1. Vấn đề

  • Nhân sự sale/CSKH thường xuyên phải lên lịch hẹn (Meeting) với khách hàng nhưng lịch trên CRM và lịch cá nhân (Google Calendar / Microsoft Outlook) bị rời rạc.
  • Việc quản lý lịch thủ công 2 nơi dễ dẫn đến quên lịch trình, nhầm khung giờ hoặc phải thao tác copy-paste thủ công gây mất thời gian.

2. Giải pháp

  • Cho phép người dùng trực tiếp tích hợp (Authorize) tài khoản Google Calendar hoặc Microsoft Outlook của họ vào hệ thống Adahub.
  • Bắt buộc tích hợp lịch cá nhân trước khi có quyền tạo các sự kiện Meeting trên hệ thống, giúp quy chuẩn hóa và đồng bộ 2 chiều.

3. Đối tượng

  • Tất cả người dùng (User) trên hệ thống (Sales, Manager… có nhu cầu thao tác giao tiếp với khách hàng).

4. Tầm nhìn/insight

  • Sau khi tích hợp, tương lai hệ thống CRM có thể đọc các block thời gian rảnh (Free/Busy slots) từ Google/MS để gợi ý lịch hẹn thông minh cho khách hàng book trực tiếp.

II. Yêu cầu chức năng

1. Danh sách tính năng

  • Tích hợp tài khoản Google Calendar (OAuth2).
  • Tích hợp tài khoản Microsoft Outlook (OAuth2).
  • Luồng ngắt kết nối (Hủy tích hợp).
  • Luồng kiểm tra ép buộc tích hợp khi khởi tạo Lịch hẹn mới.
  • Khởi tạo Lịch hẹn mới (Thêm mới Meeting) & Sinh link họp online.
  • Bảng danh sách Lịch hẹn (Các chế độ Views, Filter, Custom cột).
  • Xem nhanh Lịch hẹn (Quick view chi tiết, Liên kết đa đối tượng, Ghi chú timeline).
  • Giao diện Lịch sử Lịch hẹn tại màn hình chi tiết Đối tượng CRM (Trạng thái Sắp tới & Quá khứ).

2. Đặc tả chi tiết

User Story 1: Là một nhân viên, tôi muốn tự chủ động tích hợp lịch cá nhân của mình vào hệ thống từ trang Cài đặt để chuẩn bị cho công việc.

  • Use case 1.1 (Cách 1 - Tích hợp ở màn Cài đặt cá nhân):
    • Tiền điều kiện: User chưa tích hợp ứng dụng lịch nào, hoặc muốn ngắt cái cũ kết nối cái mới.
    • Luồng chính (Main flow):
      1. Truy cập màn Cài đặt -> tab Cài đặt cá nhân.
      2. Tại khu vực “Tích hợp lịch”, click dải nút Tích hợp lịch màu xanh.
      3. Hệ thống pop-up hiển thị 2 lựa chọn: Card Google CalendarMicrosoft Outlook.
      4. User click phân tích nền tảng. Hệ thống mở màn hình cấp quyền (OAuth Consent Screen) của GG/MS ở một Tab mới.
      5. User đăng nhập và cấp quyền thành công.
      6. Trở về màn Cài đặt hệ thống Adahub. Giao diện hiển thị 1 thẻ tài khoản đã kết nối thành công.

User Story 2: Là một nhân viên đang thao tác làm việc nhanh, tôi muốn hệ thống gợi ý tích hợp ngay lúc tạo Lịch hẹn (nếu tôi quên làm).

  • Use case 2.1 (Cách 2 - Tích hợp thông minh ở màn Detail object CRM):
    • Luồng chính (Main flow):
      1. User click nút tạo Lịch hẹn mới. Hệ thống check trạng thái = Chưa kết nối.
      2. Thay vì mở form tạo, trượt mở Popup Liên kết lịch ngay tại màn hình hiện tại.
      3. User tiến hành xác thực GG/MS. Sau khi trả Auth Code xong, hệ thống lưu và tự động mở tiếp luôn Popup Tạo lịch hẹn mới cho Use Case 3.1.

User Story 3: Là một nhân sự (Host), tôi muốn lên lịch một cuộc họp, mời người tham gia và sinh link Online Meet nhanh gọn.

  • Use case 3.1 (Tạo mới Lịch hẹn):
    • Tiền điều kiện: Đã tích hợp lịch.
    • Luồng chính (Main flow):
      1. Bấm nút Thêm lịch hẹn. Điền: Tên, Thời gian, Địa điểm, Mô tả.
      2. Cột Người tham gia: search nội bộ / Contact CRM. Gõ email ngoài và Enter để xác nhận luồng External.
      3. Click button Tạo cuộc họp online. Trực tiếp sinh link meet qua provider đã link mặc định.
      4. Cấu hình nhắc trước (VD: Trước 5 phút).
      5. Bấm Lưu. Hệ thống lưu database CRM và dùng Calendar API bắn thư mời đi.

User Story 4: Là một nhân sự, tôi muốn theo dõi tiến độ tổng quan toàn bộ lịch làm việc của mình, dễ dàng filter.

  • Use case 4.1 (Bảng danh sách Lịch hẹn):
    • Luồng chính:
      1. Click biểu tượng “Lịch hẹn” ở Sidebar. Render Bảng (Data Grid).
      2. User áp dụng các Saved Views (View 1, 2, 3…) hoặc filter lẻ (Nhân viên, Trạng thái, vv). Áp dụng ô Tìm kiếm (input) theo tên lịch hẹn.
      3. Pagination phía dưới có thể chỉnh qua lại các trang 1, 2, 3.

User Story 5: Nhằm tiết kiệm thời gian, tôi muốn bấm Xem lịch để check note và gắn Lịch vào nhiều thực thể (Đơn hàng, Khách) mà không cần load trang.

  • Use case 5.1 (Xem nhanh Lịch hẹn - Quick View):
    • Luồng chính:
      1. Click đúp 1 row, popup Xem Sượt (Quick View Modal) kéo từ phải sang.
      2. Giao diện chia khúc: Thông tin Card List, Object Links, Ghi chú Input Pin bottom.
      3. Lịch hẹn có thể chỉnh Text Title trực tiếp ở Header.
      4. Dễ dàng gán Meeting này vào nhiều Đơn/Cơ hội qua dropdown “Thêm liên kết”.
      5. Gõ text box dưới cùng -> Enter bay lên list Timeline ảo.

User Story 6: Là một nhân sự đang tương tác với hồ sơ khách hàng, tôi muốn check xem trước đây hoặc sắp tới có hẹn gặp khách vào ngày nào không ngay trên tab danh mục thông tin khách.

  • Use case 6.1 (Lịch sử Meeting tại màn Đối tượng / Contact Detail):
    • Luồng chính (Main flow):
      1. Lấy ví dụ ở màn Xem chi tiết Liên hệ (Contact Detail), User click sang tab Lịch hẹn.
      2. Giao diện tải ra một list các thẻ (Card) Lịch hẹn đã được gắn cố định với Contact này. Khối này đi kèm sẵn một nút + Tạo lịch hẹn mới trên đỉnh.
      3. Khối Card Lịch hẹn tự động được chia làm 2 bucket (nhóm) lớn: Sắp tới (Meeting trong tương lai) và Quá khứ (Chia rẽ nhánh theo từng tháng, ví dụ: Tháng 2, Tháng 1).
      4. Mặc định (Default View): Từng Card hiển thị dạng rút gọn gồm: Icon Meeting, Title, Avatar người tạo, Ngày diễn ra, và nút Tham gia trỏ link.
      5. (Expand View): Bấm mở rộng mũi tên V bên góc phải Card ra -> Lôi các Data ẩn như Địa chỉ, Thông báo trước, Text Editor mô tả. Cung cấp 2 button thao tác Nhanh: Chỉnh sửaXóa.
      6. (Delete action): Nếu bấm “Xóa” confirm -> Meeting bốc hơi nút bấm, chữ Title chuyển qua màu Xám nét gạch ngang (Strikethrough). Khạc nó vào khối bucket “Quá khứ”.
      7. (Edit action): Bấm “Chỉnh sửa” -> Thẻ này lập tức biến nháy thành giao diện Form điền y hệt modal Thêm Mới, có nút Lưu và cập nhật / Hủy Inline.
      8. Auto-Sort Hot-Update: User sửa đổi Ngày diễn ra (ví dụ dời từ lịch cũ sang lịch mới tương lai) -> Cột mốc Date bị đổi -> Lưu xong UI không cần F5 vẫn tự trượt cái thẻ đó bắn sang mục Bucket Tương lai “Sắp tới” cho đúng Rule.

3. Danh sách nghiệp vụ

  • Quy tắc Single-link: Mỗi User gắn 1 provider ở 1 thời điểm. Hết hạn Token sinh Exception bắt re-auth.
  • Validation Form Khởi tạo:
    • Tên mặc định: Bỏ trống -> Mặc định: Cuộc hẹn .
    • Thời gian hẹn form: Mở lên -> gán Start Time = Giờ hiện tại (làm tròn lên nấc 30 phút). End Time = Start + 30 phút.
    • Nhắc lịch hẹn: Fixed options [5p, 15p, 30p, 1h, 1d, 2d]. Default là 5p.
  • Nghiệp vụ Bảng Grid List: Limit 10 item/trang. Bất kỳ thay đổi Filter (Filter custom, gõ Text Search), bắt buộc Trigger Force Reset về CurrentPage = 1.
  • Nghiệp vụ Xem Nhanh & Mapping Relations: Rút gọn Label dài hiển thị +n Object Link dư thừa.
  • Nghiệp vụ Lịch sử Meeting (Timeline Logic):
    • Chỉ báo Button “Tham gia” (Join Link): Bấm thì mở link ra Tab trình duyệt mới. Nếu cuộc hẹn offline không có link meet -> Render ẩn đi Label Link và Ẩn luôn Button Tham gia này.
    • Phân cụm nhóm “Sắp tới”: Gom tất cả Meeting List có Thời điểm hết thúc (End Date Time) >= Thời điểm Now hiện tại.
    • Phân cụm nhóm “Quá khứ”: Gom Meeting List có End Date Time < Thời điểm Now HOẶC Cờ Status == Cancelled/Deleted trong Database CRM. Thẻ tháng Format text Tháng MM.

4. Giao diện

  • [Tài liệu Mockup tham chiếu: UI Card Timeline Default, UI Expanded Card, UI Form Edit Inline Update, UI Bố cục Khung Layout Của Nhóm/Bucket]

III. Yêu cầu phi chức năng

  • Tối ưu Search Query ở danh sách Lịch Hẹn nếu lượng Event quá lớn trong DataBase.

IV. Dependency (liên quan & phụ thuộc)

  • Gọi Google Maps API tại trường Địa chỉ.
  • Tích hợp 2 nhánh Auth: Google Cloud Project Console (Google Calendar API) và Azure AD (Microsoft Graph API).

V. API Contract (dev viết)

[TODO: Schema Specs]


VI. Test case (BA hoặc tester viết)

  • TC1: Test chức năng Edit Hot-Update tại Lịch sử Tab Chi Tiết Đối Tượng. Thay đổi ngày diễn ra của 1 sự kiện Quá Khứ (Tháng trước) qua Tuần Tiếp Theo (Tương lai), và xem Panel Card có tự nhảy bucket đúng chuẩn mà không lỗi React Hydration/F5 không. 0