Searched for "driver-portal" — Viewed driver-portal.types.ts:1-55
Searched for "driver" — Viewed DriverPortalPage.tsx:115-140
Searched for "system_epod" — Viewed 20260505000003_epod_chat_triggers.sql:1-204
Vị trí của Driver (Tài xế / Giao vận ePOD) trong codebase VinhPhatERP được thiết kế theo mô hình Domain-Driven Subsystem hoàn chỉnh, đóng vai trò là cầu nối vật lý cuối cùng giữa Nhà xưởng (Admin) và Khách hàng (Customer).
Dưới đây là bức tranh toàn cảnh về vị trí, kiến trúc và cách thức hoạt động của Driver trong mã nguồn:
1. Bản Đồ File & Cấu Trúc Mã Nguồn (Directory Blueprint)
src/
├── domain/logistics/
│ └── driver-portal.types.ts # Domain Types: JourneyStatus, DriverShipment, JourneyLog
├── api/
│ └── driver-portal.api.ts # REST/Supabase queries: fetchDriverShipments, updateJourney
├── application/shipments/
│ └── useDriverPortal.ts # React Query hooks: useMyDriverEmployee, useDriverShipments
├── app/router/
│ └── driverRoutes.tsx # Route config: /driver-portal (Lazy loaded)
└── features/
├── driver-portal/
│ ├── DriverPortalLayout.tsx # Mobile-first Layout cho tài xế
│ ├── DriverPortalPage.tsx # Danh sách phiếu giao hàng của tài xế
│ ├── DriverRoute.tsx # Route Guard: Kiểm tra profile.role === 'driver'
│ ├── constants.ts # Labels, thông báo Tiếng Việt
│ └── components/
│ ├── ShipmentCard.tsx # Thẻ chuyến hàng (Địa chỉ, gọi điện, mở Maps, Chat)
│ ├── JourneyStepButton.tsx# 5 nút cập nhật mốc hành trình
│ └── ProofModal.tsx # Chụp ảnh bằng chứng & ký ePOD
└── chat/
└── (Tham gia chat 3 bên: Admin ↔ Driver ↔ Customer theo entity_type='shipment')
2. Vị Trí Trong 5 Tầng Kiến Trúc
1. Tầng Phân Quyền & Định Danh (Auth & Role Guard)
- Role chuẩn: profile.role === 'driver' (trong bảng public.profiles).
- Liên kết nhân sự: Tài khoản đăng nhập được liên kết với bảng employees (phòng ban giao vận) qua hook useMyDriverEmployee().
- Bảo vệ tuyến đường: DriverRoute.tsx chỉ cho phép người dùng có role 'driver' truy cập vào không gian /driver-portal, ngăn chặn truy cập trái phép vào trang quản trị Admin.
2. Tầng Quy Trình Giao Hàng & Hành Trình (Journey & ePOD State Machine)
Tài xế là người điều khiển luồng trạng thái 5 bước của chuyến hàng (JourneyStatus):
| Bước | Trạng thái (Code) | Mô tả |
|---|---|---|
| 1 | pending_pickup | Chưa lấy hàng |
| 2 | picked_up | Đã lấy hàng từ kho |
| 3 | in_transit | Đang trên đường giao |
| 4 | arrived | Đã đến nơi giao |
| 5 | delivered_confirmed | Đã giao — khách ký nhận ePOD |
3. Tầng Tự Động Hóa Database (Triggers & Realtime Sync)
File migration: 20260505000003_epod_chat_triggers.sql
- Kích hoạt tự động khi tài xế cập nhật hành trình: Trigger trg_epod_journey_to_chat tự động ghi nhận vào bảng shipment_journey_logs và bắn tin nhắn hệ thống vào phòng Chat của chuyến hàng.
- Kích hoạt tự động khi khách ký nhận điện tử: Trigger trg_epod_signature_to_chat tạo tin nhắn system_epod (Banner màu xanh lá) thông báo giao hàng thành công đến điều phối viên và khách hàng.
4. Tầng Tương Tác Chat (Shipment Chat Subsystem)
Entity Type: entity_type: 'shipment', entity_id: shipment.id.
Mô hình Chat 3 bên:
- Tài xế (driver): Mở Chat từ thẻ ShipmentCard để trao đổi nhanh với khách hoặc báo tình hình cho xưởng.
- Khách hàng (customer): Xem vị trí tài xế, nhắn tin dặn dò giờ nhận hàng.
- Điều phối viên (admin): Theo dõi toàn bộ lịch sử và tiến độ giao hàng.
Quy tắc phân định bên Trái / Bên Phải:
| Portal | Tin nhắn từ Tài xế | Tin nhắn từ Khách / Điều phối |
|---|---|---|
| Driver Portal | BÊN PHẢI (Xanh) | BÊN TRÁI (Trắng) |
| Admin / Customer Portal | BÊN TRÁI, định danh: "Nguyễn Văn A (Tài xế)" | BÊN PHẢI (Xanh) |
5. Tầng Thông Báo Đẩy (Web Push / Mobile Lock Screen)
- Thiết bị của tài xế (thường là Smartphone chạy PWA / Android Chrome / iOS Safari) đăng ký subscription vào push_subscriptions.
- Khi Admin điều phối gán đơn hàng mới hoặc khách hàng nhắn tin dặn dò, Edge Function send-web-push gửi push trực tiếp đến điện thoại tài xế để nhận việc ngay lập tức kể cả khi đang khóa màn hình.
3. Các Điểm Cần Lưu Ý Khi Nâng Cấp Liên Quan Đến Driver
- Giao diện thuần Mobile / 1-Handed Operation: Mọi thao tác trên Driver Portal được thiết kế dạng nút bấm to bản, dễ chạm bằng một tay khi đang di chuyển.
- Offline & Low-Network Resiliency: Khi tài xế vào vùng sóng yếu (tầng hầm, kho bãi), việc chụp ảnh bằng chứng giao hàng hoặc gửi tin nhắn cần lưu cache cục bộ và đồng bộ tự động khi có mạng.
- Phân biệt rõ 2 loại Chat Room: Cần phân biệt chính xác giữa phòng chat hỗ trợ và phòng chat nghiệp vụ giao hàng.
| entity_type | Loại phòng chat | Thành phần tham gia |
|---|---|---|
| 'customer' | Phòng chat hỗ trợ 1-1 | Khách hàng và Xưởng |
| 'shipment' | Phòng chat nghiệp vụ giao hàng | Khách hàng, Xưởng và Tài xế |
Lưu ý kiến trúc quan trọng: Khi phát triển tính năng liên quan đến Driver, phải luôn xác định đúng entity_type của phòng chat. Sử dụng 'shipment' cho các cuộc hội thoại có sự tham gia của tài xế, và 'customer' cho kênh hỗ trợ thông thường. Nhầm lẫn hai loại này sẽ dẫn đến tài xế xuất hiện trong phòng chat hỗ trợ sai ngữ cảnh, hoặc khách hàng không nhận được tin nhắn cập nhật hành trình giao hàng.