YeChai Tài liệu

Kiến trúc hệ thống

Bốn ứng dụng, một API và một cơ sở dữ liệu PostgreSQL.

Sơ đồ tổng thể

                    ┌─────────────────────────────┐
   Khách hàng  ───▶ │  apps/citizen  (web PWA)    │ ─┐
                    │  apps/citizen-mobile (Expo) │  │
                    └─────────────────────────────┘  │
                                                     │  HTTPS, cookie phiên
                    ┌─────────────────────────────┐  │
   Nhân viên   ───▶ │  apps/admin  (web, /admin)  │ ─┤
                    └─────────────────────────────┘  │
                                                     ▼
                    ┌─────────────────────────────┐
                    │  apps/api  (Fastify 5)      │
                    │  /api/v1/app/*   (khách)    │
                    │  /api/v1/admin/* (nhân viên)│
                    └──────────────┬──────────────┘
                                   │ Drizzle ORM
                                   ▼
                    ┌─────────────────────────────┐
                    │  PostgreSQL                 │
                    └─────────────────────────────┘

Bốn ứng dụng

AppCông nghệCổng khi chạy localAi dùng
apps/citizenReact 19 + Vite, PWA5173Khách hàng
apps/citizen-mobileExpo 57 / React Native 0.86—Khách hàng
apps/adminReact 19 + Vite, base /admin/5176Nhân viên
apps/apiFastify 5 + TypeScript3001Chạy nền

Bốn package dùng chung

PackageVai trò
packages/contractsSchema Zod và kiểu dữ liệu dùng chung cho mọi app. Là nguồn sự thật cho tên trạng thái và luật kiểm tra.
packages/clientThư viện gọi API, gồm cả polling.
packages/uiComponent, token thiết kế và font.
packages/citizen-domainLogic hiển thị thuần, dùng chung cho bản web và bản di động của app khách.

Một origin công khai, hai app web

Gateway scripts/serve-apps.mjs phục vụ cả hai app web trên một cổng công khai:

  • / và các đường dẫn khác → app người dân.
  • /admin/* → trang quản trị.
  • /api/*, /healthz, /readyz → chuyển tiếp sang API.

Nhờ vậy phiên đăng nhập và cookie hoạt động thống nhất trên cùng một tên miền, không vướng vấn đề CORS giữa hai app.

Hai app web dùng chung một cơ sở dữ liệu

/api/v1/app/* và /api/v1/admin/* là hai cây route tách biệt trong cùng một tiến trình API, nhưng dùng cùng một cơ sở dữ liệu và một số bảng chung như orders, sessions, photos. Vì vậy đơn của khách và màn Đặt lịch của nhân viên luôn nhìn thấy cùng một bản ghi.

Luồng dữ liệu của một đơn

BướcGhi vào đâuAi đọc
Khách đặt lịchorders với status = pendingĐiều phối thấy trong màn Đặt lịch
Điều phối duyệt và chọn xeorders.status = confirmed, ghi vehicleTypeIdKhách thấy trạng thái mới
Tạo phiên thu gomcollection_sessions + gán sessionId, status = scheduledNgười thu gom và điều phối
Bắt đầu phiênstatus = collectingKhách thấy "Đã bắt đầu thu gom"
Nhập phiếucollection_session_entries theo từng loạiPhiên kiểm tra đọc lại
Khách xác nhậncust_ok_at trên đơnMở khoá bước nhập phiếu
Chuyển kiểm tracollection_inspectionsNhân viên kiểm tra
Hoàn tất kiểm trainspection_invoices, inspection_payouts, sổ giáMàn Hoá đơn và Tài chính
Chi trảinvoice_payout_logs, status = paidKhách nhận thông báo

Xem thêm

Trong trang này