Cherry là hệ thống đặt đồ ăn nhanh được thiết kế theo kiến trúc microservices trên .NET 8, chia thành 4 phase tiến hóa dần để phục vụ mục tiêu học & kiểm thử:
- Mỗi phase bổ sung thêm service (Product → Coupon/Cart → Auth/Order → Email/Reward + Gateway + Web).
- Mỗi phase có file Docker Compose riêng để chạy gọn nhẹ.
- Mỗi service có project xUnit tests đi kèm; script hỗ trợ chạy test theo phase.
- Hạ tầng dùng chung SQL Server (mỗi domain một database) và Ocelot Gateway (phase 4).
README này tập trung giúp QA/dev dựng nhanh môi trường, chạy hệ thống, thực thi & lọc test, và hiểu luồng chính để kiểm thử, kèm playbook ngắn gọn để debug/logs.
| Phase | Thành phần chính | Compose file | Port chính | Lệnh nhanh |
|---|---|---|---|---|
| 1 | ProductAPI + SQL | docker/phases/docker-compose.phase1.yml |
5002, 1433 | ./scripts/run-phase.sh 1 |
| 2 | + CouponAPI, ShoppingCartAPI | docker/phases/docker-compose.phase2.yml |
5002-5004, 1433 | ./scripts/run-phase.sh 2 |
| 3 | + AuthAPI, OrderAPI | docker/phases/docker-compose.phase3.yml |
5001-5005, 1433 | ./scripts/run-phase.sh 3 |
| 4 | Full: + EmailAPI, RewardAPI, Gateway, Web | docker/phases/docker-compose.phase4.yml |
5000-5008, 1433 | ./scripts/run-phase.sh 4 |
Chi tiết từng phase: xem README_PHASES.md và docs/phases/*.
[User/QA]
↓
[Cherry.Web] (5008)
↓
[API Gateway - Ocelot] (5000)
↓
├─ AuthAPI (5001) - JWT, cấp token
├─ ProductAPI (5002) - CRUD sản phẩm
├─ CouponAPI (5003) - Mã giảm giá
├─ ShoppingCartAPI (5004) - Giỏ hàng
├─ OrderAPI (5005) - Checkout, gọi Email/Reward
├─ EmailAPI (5006) - Log/gửi email
└─ RewardAPI (5007) - Tích điểm thưởng
↓
[SQL Server 2019]
Luồng kiểm thử chính: duyệt sản phẩm → thêm giỏ → áp mã giảm giá → checkout (OrderAPI) → EmailAPI ghi log → RewardAPI cộng điểm. Tất cả request user đi qua Gateway (phase 4).
System flow theo phase
- Phase 1: ProductAPI CRUD + SQL → kiểm thử logic sản phẩm, giá, tồn kho.
- Phase 2: + CouponAPI, ShoppingCartAPI → kiểm thử áp mã giảm giá, cộng/trừ số lượng giỏ.
- Phase 3: + AuthAPI, OrderAPI → kiểm thử đăng ký/đăng nhập, JWT, phân quyền, checkout (gọi cross-service).
- Phase 4: + EmailAPI, RewardAPI, Gateway, Web → kiểm thử end-to-end qua Gateway/Web, log email, tích điểm.
- 📚 Overview
- 🧭 Phase Roadmap (tóm tắt)
- 🧩 Architecture / System Flow
- ⚙️ Environment Setup
- 🚀 Run Locally
- 🧪 Testing
- 🔁 CI/CD
- 🗂️ Folder Structure
⚠️ Known Issues / Limitations
git clone https://github.com/<your-org>/FastFoodOrder.git
cd FastFoodOrder- Docker & Docker Compose
- .NET 8 SDK (để chạy test và build)
- Git, Bash shell (script
.shviết cho Unix shell; Windows nên dùng WSL/Git Bash) - Ports trống: 1433 (SQL), 5000-5008 (service/Gateway/Web)
- Optional: Azure Service Bus (nếu muốn bật message queue cho Email/Reward; default để trống)
- Lưu ý secret: password SQL mặc định
YourStrong@Password123, JWT/ServiceBus dùng config mặc định trong từng service (chỉ hợp cho local).
- Chọn phase cần chạy:
./scripts/run-phase.sh 1 # Phase 1
./scripts/run-phase.sh 4 # Full systemScript sẽ bật đúng compose file, đợi service healthy và in URL.
- Kiểm tra nhanh (ví dụ phase 4):
curl -f http://localhost:5000 # Gateway alive
curl -f http://localhost:5002/swagger/index.html- Dừng khi xong:
./scripts/stop-phase.sh <phase_number>Chọn xoá volumes nếu muốn reset dữ liệu.
- Re-build images (tùy chọn):
./scripts/build-phase.sh <phase_number> <version_tag>docker-compose -f docker/phases/docker-compose.phase4.yml up -d
docker-compose -f docker/phases/docker-compose.phase4.yml logs -f- Gateway:
http://localhost:5000 - Web app:
http://localhost:5008 - Auth/Product/Coupon/Cart/Order/Email/Reward Swagger:
http://localhost:5001-5007/swagger - SQL Server:
localhost:1433(SA password mặc định:YourStrong@Password123) - Logs:
docker-compose -f docker/phases/docker-compose.phase<phase>.yml logs -f - Healthcheck nhanh:
curl -f http://localhost:5000(Gateway) hoặccurl -f http://localhost:5002/swagger/index.html
- Phase 1:
curl -f http://localhost:5002/swagger/index.html→ 200; thử tạo/sửa/xóa sản phẩm. - Phase 2: tạo sản phẩm → thêm giỏ → áp mã giảm giá hợp lệ/sai/hết hạn → tổng tiền cập nhật đúng.
- Phase 3: đăng ký/đăng nhập → lấy JWT → gọi ProductAPI kèm Bearer token → checkout → OrderAPI trả order id.
- Phase 4: mở Web (
5008) → login → đặt hàng → kiểm tra Email logs (/api/email/logs) và Reward (/api/reward/{userId}) có bản ghi mới. - Log lỗi:
docker-compose -f docker/phases/docker-compose.phase<phase>.yml logs -f service_name
./scripts/run-tests.sh <phase_number> [unit|integration|all]
# Ví dụ
./scripts/run-tests.sh 1 unit # Unit test ProductAPI
./scripts/run-tests.sh 3 all # Tất cả test Phase 3
./scripts/run-tests.sh 4 integration # Integration/Gateway/WebScript sẽ chạy đúng các project test của phase, gom kết quả và trả exit code ≠0 nếu có lỗi.
dotnet test Cherry.Services.OrderAPI.Tests --verbosity minimal
dotnet test Cherry.Web.Tests --filter "Category=Integration"
dotnet test Cherry.Services.CouponAPI.Tests --filter "Category=Unit"Liệt kê test hiện có:
dotnet test Cherry.Web.Tests --list-tests- Mục tiêu: lọc nhanh theo loại test.
- Gắn nhãn (xUnit):
[Fact]
[Trait("Category", "Integration")]
public void Should_call_gateway_endpoints() { ... }- Gợi ý nhãn:
Unit(logic thuần),Integration(DB/Gateway),E2E(luồng đầy đủ),Slow/Flaky(tùy chọn). - Lọc nhiều nhãn:
dotnet test Cherry.Web.Tests --filter "Category=Integration|Category=E2E"- Nếu filter trả về 0 test, kiểm tra lại attribute trong test hoặc bỏ filter để chạy toàn bộ.
- Phase 1 (ProductAPI): CRUD sản phẩm, validate giá âm/stock âm, tìm kiếm/filter, swagger load.
- Phase 2: Thêm giỏ, cập nhật số lượng, áp mã giảm giá hợp lệ/hết hạn/sai; tính tổng khi thay đổi giá sản phẩm.
- Phase 3: Đăng ký/đăng nhập, refresh token (nếu có), phân quyền (role user/admin), checkout -> OrderAPI tạo order và lưu DB.
- Phase 4: Flow E2E qua Web+Gateway; sau checkout kiểm tra EmailLog (EmailAPI) và Reward points; thử tắt 1 service xem Gateway trả lỗi đúng hay không.
- Không có seed user mặc định; bạn có thể đăng ký user mới qua AuthAPI hoặc Web.
- Dữ liệu DB nằm trên volume docker; nếu muốn reset sạch:
./scripts/stop-phase.sh <phase>, chọn xóa volumes.
# Đăng ký user
curl -X POST http://localhost:5001/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"qa@example.com","password":"Pass@123","name":"QA User"}'
# Đăng nhập để lấy token
TOKEN=$(curl -s -X POST http://localhost:5001/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"qa@example.com","password":"Pass@123"}' | jq -r .token)
# Gọi ProductAPI có Bearer
curl -H "Authorization: Bearer $TOKEN" http://localhost:5002/api/productNếu không có jq, xem token thủ công trong response JSON.
- Workflow CI cho từng phase:
.github/workflows/phase1-ci.yml…phase4-ci.yml. - Nội dung chính: build,
dotnet testtheo phase, có thể trigger trên push/PR (tùy cấu hình repository). - Gợi ý bổ sung: cấu hình secret cho JWT/ServiceBus khi deploy thật (không dùng default local secret).
- Có thể tái sử dụng script
./scripts/build-phase.shvà./scripts/run-tests.shtrong pipeline tự host.
FastFoodOrder/
├── Cherry.Services.AuthAPI/ # Auth + JWT
├── Cherry.Services.ProductAPI/ # Sản phẩm
├── Cherry.Services.CouponAPI/ # Mã giảm giá
├── Cherry.Services.ShoppingCartAPI/ # Giỏ hàng
├── Cherry.Services.OrderAPI/ # Đơn hàng
├── Cherry.Services.EmailAPI/ # Log/gửi email
├── Cherry.Services.RewardAPI/ # Điểm thưởng
├── Cherry.GatewaySolution/ # Ocelot API Gateway
├── Cherry.Web/ # Frontend MVC
├── Cherry.*.Tests/ # Test cho từng service/Web
├── docker/phases/ # Compose per phase (1-4)
├── scripts/ # run/build/stop/tests/deploy helper scripts
├── docs/phases/ # Tài liệu chi tiết từng phase
├── init-databases.sql # Tạo DB cho tất cả service
└── README_PHASES.md # Lộ trình 4 phase
- Port bận: đổi mapping port trong compose tương ứng (5000-5008, 1433).
- DB auth fail: kiểm tra
SA_PASSWORDtrong compose và chuỗi kết nốiDefaultConnectioncủa từng service. - Build lâu: chạy
docker-compose ... buildtrước để cache layer .NET; hoặcdotnet restorethủ công để warm cache. - Log ngắn gọn:
docker-compose ... logs --tail=50 service_name; nếu service restart liên tục, kiểm tra healthcheck hoặc connection string. - Reset DB sạch: dừng phase, xoá volume khi script hỏi, hoặc
docker volume rm <volume_name>(ví dụcherry_db_data_phase4). - Windows: luôn chạy qua WSL/Git Bash để tránh lỗi CRLF/permission trong script
.sh.
- Secret mặc định (SA password, JWT,
ServiceBusConnectionStringtrống) chỉ dành cho local/dev; cần override khi deploy. - Email/Reward chưa cấu hình hạ tầng message (Service Bus); muốn chạy async phải cấp connection string & queue/topic thực.
- Script
.shcần Bash; Windows nên dùng WSL/Git Bash để tránh lỗi dòng lệnh. - Compose build lần đầu sẽ lâu do pull/build .NET image; dùng
docker-compose ... buildtrước để cache. - Port 1433/5000-5008 phải trống; nếu trùng, chỉnh trong compose hoặc dừng service đang chiếm port.
- Chưa có seed data/user mặc định; cần tự tạo user và product cho các kịch bản kiểm thử end-to-end.
- Khi đổi mật khẩu SQL hoặc JWT secret, cập nhật đồng bộ trong các compose/appsettings tương ứng để tránh lỗi kết nối.