SkyDish là nền tảng đặt và giao đồ ăn theo mô hình marketplace, xây dựng trên kiến trúc microservices Node.js để phục vụ bốn vai trò chính: Khách hàng, Quản trị Nhà hàng, Tài xế giao hàng và Super Admin. Hệ thống kết hợp API REST, cổng realtime Socket.IO và frontend React để bảo đảm trải nghiệm đặt món xuyên suốt từ onboarding tới giao thành công.
- Giới thiệu nhanh
- Kiến trúc & Dịch vụ
- Công nghệ chính
- Yêu cầu hệ thống & phụ thuộc
- Cấu trúc repository
- Biến môi trường
- Thiết lập & vận hành local
- Microservices & endpoint
- Realtime Gateway
- Frontend
- Testing & linting
- Troubleshooting
- Demo & tài liệu
- Khách hàng: đăng ký/đăng nhập, khám phá nhà hàng, đặt đơn, theo dõi trạng thái, gửi phản hồi.
- Quản trị Nhà hàng: quản lý hồ sơ, bật/tắt hoạt động, CRUD menu, nhận và cập nhật đơn.
- Tài xế giao hàng: quản lý tài khoản, nhận nhiệm vụ, cập nhật lộ trình, xem thống kê.
- Super Admin: duyệt nhà hàng/tài xế, xem khách hàng và đơn, proxy dữ liệu để vận hành tập trung.
Toàn bộ dịch vụ giao tiếp qua REST + JWT, phát sự kiện qua Redis/Socket.IO, thanh toán qua Stripe và thông báo qua Twilio/Resend.
Frontend (React) ──> API Gateway (per service URL)
│
├─ Auth Service (4000)
├─ Restaurant Service (5002)
├─ Order Service (5005)
├─ Delivery Service (5003)
├─ Payment Service (5004)
└─ Realtime Gateway (5050) ⇄ Redis (6379)
MongoDB Atlas/Cluster (chia sẻ cho từng service)
| Service | Port (mặc định) | Mô tả chính | Công nghệ nổi bật |
|---|---|---|---|
| Auth Service | 4000 | Đăng ký/đăng nhập cho khách hàng, quản trị, cấp JWT và quản lý hồ sơ | Node.js, Express, MongoDB, bcrypt |
| Restaurant Service | 5002 | Onboarding nhà hàng, menu, trạng thái mở cửa, API Super Admin proxy | Node.js, Express, MongoDB, Multer |
| Order Service | 5005 | Tạo đơn, theo dõi trạng thái, quản lý phản hồi | Node.js, Express, MongoDB, Stripe webhook consumer |
| Delivery Service | 5003 | Đăng ký tài xế, phân công giao, thống kê và quản lý tài xế | Node.js, Express, MongoDB |
| Payment Service | 5004 | Tạo Payment Intent, webhook từ Stripe, gửi thông báo | Node.js, Express, Stripe SDK, Swagger |
| Realtime Gateway | 5050 | Chuẩn hóa kết nối Socket.IO, pub/sub Redis, phát sự kiện nội bộ | Node.js, Socket.IO, Redis |
| Frontend (Khách hàng/Admin) | 3000 | Ứng dụng React chính cho khách, nhà hàng, super admin | React, Vite/CRA, JWT storage |
| Frontend (Delivery) | 3001 | Ứng dụng riêng cho tài xế | React |
- Ngôn ngữ & runtime: Node.js 20, JavaScript/TypeScript (service phụ), React 18.
- Framework: Express.js, Socket.IO.
- Database: MongoDB + Mongoose.
- Auth: JWT (HS256), bcrypt/bcryptjs.
- Realtime: Socket.IO Gateway + Redis pub/sub.
- Thanh toán: Stripe PaymentIntent + webhook.
- Thông báo: Twilio SMS, Resend Email.
- Triển khai cục bộ: Docker & docker-compose.
- Tài liệu API: Swagger cho Payment Service, nội bộ Document/system-documentation.md (IEEE 830/29148).
- Node.js v18+ và npm (dùng khi chạy frontend/dịch vụ riêng lẻ).
- Docker Desktop + docker-compose plugin.
- Tài khoản MongoDB Atlas hoặc URI Mongo local.
- Stripe dashboard để lấy khóa
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET. - Twilio & Resend (tùy chọn) cho SMS/Email.
- OpenCage API key nếu cần geocoding.
/
├── backend/
│ ├── auth-service/
│ ├── restaurant-service/
│ ├── order-service/
│ ├── payment-service/
│ └── realtime-gateway/
├── delivery-service/
│ ├── backend/
│ └── frontend/
├── frontend/
├── Document/
│ └── system-documentation.md # PRD, UML, ERD, DFD, ...
├── docker-compose.yml
├── README.md
├── .env
└── ...
MONGO_URI=mongodb+srv://...
JWT_SECRET=your_jwt_secret
JWT_EXPIRES_IN=7d
AUTH_PORT=4000
REST_PORT=5002
DELIVERY_PORT=5003
PAY_PORT=5004
ORDER_PORT=5005
REALTIME_PORT=5050
REALTIME_URL=http://26.32.188.49:5050
REDIS_URL=redis://26.32.188.49:6379
SERVICE_INTERNAL_KEY=super-admin-internal-key
AUTH_SERVICE_URL=http://26.32.188.49:4000
RESTAURANT_SERVICE_URL=http://26.32.188.49:5002
DELIVERY_SERVICE_URL=http://26.32.188.49:5003
ORDER_SERVICE_URL=http://26.32.188.49:5005
EMAIL_PREFER_SMTP=true
SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=your_gmail@example.com
SMTP_PASS=your_gmail_app_password
NOTIFY_FROM_EMAIL="Food Delivery <your_gmail@example.com>"
SUPER_ADMIN_PORTAL_URL=http://26.32.188.49:3000/super-admin/dashboard
RESTAURANT_ONBOARDING_URL=http://26.32.188.49:3000/restaurant/activate- Payment Service:
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET. - Notifications:
TWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN,TWILIO_PHONE_NUMBER,RESEND_API_KEY. - Order/Realtime chia sẻ:
SHARED_JWT_SECREThoặcORDER_SERVICE_JWT_SECRET. - Frontend: file
frontend/.envvớiVITE_API_BASE_URL,VITE_REALTIME_URL, v.v. (tùy nhu cầu). - Delivery frontend/backend: thiết lập tương tự trong
delivery-service/*/.env.
- Sao chép repo:
git clone ... && cd food-delivery-microservices. - Tạo file
.envtại root theo mẫu trên. - (Tùy chọn) Cập nhật
docker-compose.ymlnếu muốn ánh xạ cổng khác.
docker compose up --buildCompose sẽ khởi động Mongo (nếu cấu hình), Redis, Realtime Gateway và toàn bộ dịch vụ Node.js. Đảm bảo cổng 3000/3001/4000/5002/5003/5004/5005/5050 trống.
# ví dụ với Auth Service
cd backend/auth-service
npm install
npm run devLặp lại cho từng dịch vụ; nhớ cung cấp .env riêng (có thể dùng chung giá trị từ .env root).
POST /api/auth/register/customer– đăng ký khách.POST /api/auth/login– đăng nhập đa vai trò.GET /api/auth/customer/profile– lấy hồ sơ khách (JWT).PATCH /api/auth/customer/profile– cập nhật hồ sơ (JWT).GET /api/auth/admin/customers– liệt kê khách (Admin JWT).PATCH /api/auth/admin/customers/:id/status– khóa/mở khách (Admin JWT).
Nhà hàng:
POST /api/restaurants/registerPOST /api/restaurants/loginGET /api/restaurants/profile(JWT)PUT /api/restaurants/update(JWT)PUT /api/restaurants/availability(JWT)GET /api/restaurants/all(Public)GET /api/restaurants/:id(Public)
Món ăn:
POST /api/food-items/create(Restaurant JWT, hỗ trợ upload/link ảnh)GET /api/food-items/(Restaurant JWT)PUT /api/food-items/:id(Restaurant JWT)PUT /api/food-items/availability/:id(Restaurant JWT)DELETE /api/food-items/:id(Restaurant JWT)GET /api/food-items/all(Public)GET /api/food-items/restaurant/:restaurantId(Public)
Super Admin:
POST /api/superadmin/register|loginGET /api/superadmin/restaurantsGET /api/superadmin/restaurant/:idPUT /api/superadmin/restaurant/:idPATCH /api/superadmin/restaurant/:id/approvePATCH /api/superadmin/restaurant/:id/rejectDELETE /api/superadmin/restaurant/:id- Proxy:
/api/superadmin/customers|drivers|orders
POST /api/orders(Customer)GET /api/orders(Customer/Restaurant/Driver/Admin/SuperAdmin)GET /api/orders/:id(vai trò giống trên)PATCH /api/orders/:id(Customer/Restaurant/Admin/SuperAdmin)PATCH /api/orders/:id/status(Restaurant/Driver/Admin/SuperAdmin)DELETE /api/orders/:id(Customer/Restaurant/Admin/SuperAdmin)POST /api/orders/:id/feedback(Customer)GET /api/orders/feedback/restaurant(Restaurant/Admin/SuperAdmin)
Auth tài xế:
POST /api/auth/registerPOST /api/auth/loginGET /api/auth/profile(JWT)
Giao hàng:
POST /api/delivery/createGET /api/delivery(danh sách cá nhân)GET /api/delivery/stats/summaryGET /api/delivery/availableGET /api/delivery/order/:orderIdGET /api/delivery/:idPUT /api/delivery/:id/statusDELETE /api/delivery/:id
Quản trị tài xế:
GET /api/admin/drivers(Admin JWT)PATCH /api/admin/drivers/:id/statusPATCH /api/admin/drivers/:id/activity
POST /api/payment/process– tạo thanh toán.POST /api/payment/webhook– Stripe webhook (raw body).- Swagger UI:
http://26.32.188.49:5004/api-docs.
Mỗi
orderIdlà duy nhất trong Payment Service; webhook cập nhật trạng thái Paid/Failed và có thể kích hoạt SMS/Email.
- Base URL:
http://26.32.188.49:5050. GET /health– kiểm tra sẵn sàng.POST /internal/events– dịch vụ nội bộ phát sự kiện.- Header:
x-service-key: ${SERVICE_INTERNAL_KEY} - Body:
{ "event": "...", "payload": {...}, "rooms": ["user:123"], "broadcast": true }
- Header:
Client (frontend) kết nối Socket.IO bằng JWT, tham gia room user:{id}, role:{role}. Order/Delivery Service gửi sự kiện nội bộ tới gateway ⇒ Redis pub/sub ⇒ client nhận cập nhật trạng thái theo thời gian thực.
cd frontend
npm install
npm startTruy cập http://26.32.188.49:3000. Các trang quan trọng:
/auth/login,/auth/register/restaurant/*cho quản trị nhà hàng/super-admin/dashboarddành cho Super Admin
cd delivery-service/frontend
npm install
npm startTruy cập http://26.32.188.49:3001. Đảm bảo cấu hình VITE_API_BASE_URL trỏ về Delivery Service.
npm test
npm run lintcd frontend
npm testDelivery frontend/backend sử dụng lệnh tương tự trong thư mục riêng.
- CORS lỗi: đảm bảo mỗi service
app.use(cors({ origin: "http://26.32.188.49:3000", credentials: true })). - Mongo không kết nối: whitelist IP (Atlas) hoặc dùng
0.0.0.0/0cho dev. - Stripe webhook: chạy
stripe listen --forward-to 26.32.188.49:5004/api/payment/webhook. - Realtime không push: kiểm tra
REDIS_URLvàSERVICE_INTERNAL_KEYđồng nhất giữa gateway và dịch vụ phát sự kiện. - Email không gửi: bật
EMAIL_PREFER_SMTP=true, dùng Gmail App Password, kiểm tra logactivation.deliveryStatus. - Link email mở không được trên mobile: đặt
SUPER_ADMIN_PORTAL_URLvàRESTAURANT_ONBOARDING_URLbằng IP nội bộ máy dev và đảm bảo cùng mạng Wi-Fi.
- Repo gốc: https://github.com/thungnguyen/FoodDelivery
- Tài liệu hệ thống (IEEE 830/29148):
Document/system-documentation.md– bao gồm PRD, Use Case, UML, ERD, DFD và tham chiếu nguồn.
- Biến môi trường:
DRONE_MONGO_URI/DELIVERY_DB_URI(DBdelivery_db),MAPTILER_API_KEY(map tile),ORS_API_KEY(định tuyến). - Collections mới:
drone_hubs,drones,drone_deliveries,drone_tracking_logs(có index 2dsphere + timestamp). - API nội bộ (delivery-service):
GET/POST /api/drones,PUT /api/drones/:id,POST /api/drone/update-location,GET/POST /api/drone-deliveries,POST /api/drone-deliveries/:id/logs,GET/POST /api/hubs. - Địa chỉ chuẩn hóa: khách hàng & nhà hàng lưu
address.{street, ward, district, city, fullAddress, location}để phục vụ geocode và lộ trình drone. - Gợi ý migrate legacy: map các trường text cũ (
location,locationCoords) sangaddress.fullAddressvà backfill tọa độ qua geocoder trước khi bật tìm kiếm/route.
Chúc bạn triển khai SkyDish thuận lợi!