Dự án môn học Thiết kế phần mềm (Software Design) — Nhóm G05.
Hệ thống TicketBox là một giải pháp quản lý bán vé và soát vé sự kiện âm nhạc quy mô lớn, được tối ưu hóa cho tải lượng truy cập đột biến cao (high concurrency) và hỗ trợ soát vé offline-first tại địa điểm sự kiện.
Hệ thống được xây dựng trên mô hình Event-Driven Modular Monolith với các công nghệ chính:
- Frontend (Web): Next.js (React), TailwindCSS (giao diện khán giả và quản trị BTC).
- Mobile (App): React Native (Expo), SQLite (lưu trữ offline dành cho checker).
- Backend (API): Node.js, NestJS (Kiến trúc chia module nghiệp vụ độc lập).
- Database chính: PostgreSQL (Đảm bảo ACID mạnh mẽ và toàn vẹn giao dịch).
- Caching & Locking: Redis (Cache-aside, Distributed Lock chống overbooking, Rate Limiting).
- Hàng đợi tin nhắn: BullMQ (Xử lý bất đồng bộ luồng đặt chỗ, thanh toán, import dữ liệu).
ticketbox/
├── blueprint/ # Tài liệu thiết kế hệ thống (Blueprint)
│ ├── proposal.md # Bối cảnh, vấn đề, mục tiêu của dự án
│ ├── design.md # Kiến trúc hệ thống, cơ sở dữ liệu, C4 diagrams, kỹ thuật bảo vệ
│ └── specs/ # Đặc tả chi tiết các luồng nghiệp vụ quan trọng
│ ├── auth.md # Đặc tả phân quyền và truy cập (RBAC)
│ ├── payment.md # Đặc tả luồng mua vé, thanh toán & chống trừ tiền 2 lần
│ ├── checkin.md # Đặc tả luồng soát vé offline & đồng bộ dữ liệu
│ ├── csv_import.md # Đặc tả đồng bộ danh sách VIP từ file CSV
│ ├── ai_bio.md # Đặc tả tính năng AI Artist Bio
│ └── business_flows.md # Đặc tả chi tiết kịch bản các luồng nghiệp vụ tích hợp
├── src/ # Mã nguồn dự án
│ ├── backend/ # Mã nguồn Backend (NestJS API Service)
│ ├── frontend-web/ # Mã nguồn Web App (Khán giả, Admin)
│ └── mobile-checkin/ # Mã nguồn Mobile App soát vé
├── data/ # Script tạo DB, Seed data và các file CSV mẫu
├── clips/ # Video demo dự án
├── docker-compose.yml # Khởi chạy toàn bộ hệ thống bằng Docker
├── tech_stack_rationale.md # Tài liệu phân tích lựa chọn Stack công nghệ
├── plan.md # Kế hoạch phát triển dự án và tiến độ hiện tại
└── README.md # Hướng dẫn cài đặt và chạy ứng dụng (File này)
Trước khi bắt đầu, hãy đảm bảo máy tính của bạn đã cài đặt các phần mềm sau:
| Phần mềm | Phiên bản tối thiểu | Mục đích |
|---|---|---|
| Node.js | v18 LTS trở lên | Chạy Backend và Frontend |
| npm | v9 trở lên | Quản lý thư viện |
| Git | Bất kỳ | Clone repository |
| Docker Desktop | v4 trở lên | Chạy PostgreSQL và Redis |
| Expo Go (tuỳ chọn) | Mới nhất | Test Mobile App trên điện thoại thật |
Đây là cách đơn giản và nhanh nhất để khởi chạy toàn bộ hệ thống (Backend + Frontend + PostgreSQL + Redis) cùng lúc:
# 1. Clone repository
git clone https://github.com/trancuonG05/TicketBoxProject.git
cd TicketBoxProject
# 2. Tạo file .env cho backend (bắt buộc)
cp src/backend/.env.example src/backend/.env
# 3. Tạo file .env cho frontend (bắt buộc)
echo "NEXT_PUBLIC_API_URL=http://localhost:3000" > src/frontend-web/.env
# 4. Khởi chạy toàn bộ hệ thống
docker compose up --build -d
# 5. Kiểm tra trạng thái các container
docker compose psSau khi tất cả container ở trạng thái running, tiến hành seed dữ liệu mẫu:
docker exec -it ticketbox_backend npm run seed:prodKết quả: Hệ thống sẽ hoạt động tại các địa chỉ:
| Dịch vụ | URL / Port |
|---|---|
| Web Frontend (Next.js) | http://localhost:3001 |
| Backend API (NestJS) | http://localhost:3000 |
| API Docs (Swagger) | http://localhost:3000/api |
| PostgreSQL Database | localhost:54320 |
| Redis | localhost:6379 |
# Chỉ khởi chạy PostgreSQL và Redis (không build backend/frontend)
docker compose up db redis -d# Di chuyển vào thư mục backend
cd src/backend
# Cài đặt thư viện
npm install
# Tạo file .env từ mẫu
cp .env.example .env
# Sau đó chỉnh sửa .env nếu cần thiết
# Chạy migration và seed dữ liệu mẫu
npm run seed
# Khởi động server ở chế độ phát triển (hot reload)
npm run start:devLưu ý: Backend NestJS chạy tại
http://localhost:3000. Xem tài liệu API tạihttp://localhost:3000/api.
cd src/frontend-web
npm install
npm run devFrontend chạy tại
http://localhost:3001(hoặchttp://localhost:3000nếu không chạy đồng thời với backend ngoài Docker).
cd src/checkin-mobile
npm install
npx expo startĐể test ứng dụng:
- Trên điện thoại thật: Tải Expo Go từ App Store / Google Play. Quét mã QR hiển thị trong terminal.
- Trên giả lập iOS/Android: Nhấn
i(iOS) hoặca(Android) trong terminal.
Để cổng thanh toán SePay (hoặc các dịch vụ bên thứ 3 khác) có thể gửi Webhook về máy tính của bạn khi đang chạy code ở localhost, bạn cần dùng Ngrok để tạo một Public URL.
Bước 1: Tải và cài đặt ngrok từ ngrok.com. Bước 2: Chạy lệnh ngrok trỏ vào port của Backend (Port 3000):
ngrok http 3000Bước 3: Ngrok sẽ cấp cho bạn một đường link dạng https://<random-id>.ngrok-free.app. Hãy copy đường link này.
Bước 4: Vào trang quản trị của SePay (hoặc nền tảng thanh toán bạn dùng), cấu hình URL Webhook thành:
https://<random-id>.ngrok-free.app/payment/sepay-webhook
(Lưu ý: Đừng quên cập nhật token bảo mật của SePay vào file .env biến SEPAY_WEBHOOK_TOKEN)
Sau khi chạy lệnh seed, hệ thống sẽ tạo sẵn các tài khoản sau để test:
| Role | Mật khẩu | Quyền hạn | |
|---|---|---|---|
| Admin | admin@ticketbox.com |
123456 |
Toàn quyền quản trị: tạo concert, xem thống kê, import CSV |
| Checker 1 | checker1@ticketbox.com |
123456 |
Soát vé tại cổng (quét QR) |
| Checker 2 | checker2@ticketbox.com |
123456 |
Soát vé tại cổng (quét QR) |
| Khách hàng 1 | audience1@ticketbox.com |
123456 |
Xem concert, đặt vé, xem lịch sử |
| Khách hàng 2 | audience2@ticketbox.com |
123456 |
Xem concert, đặt vé, xem lịch sử |
| (Đến khách hàng 7) | audience7@ticketbox.com |
123456 |
Xem concert, đặt vé, xem lịch sử |
File .env của backend (src/backend/.env) — xem file mẫu tại .env.example:
| Biến | Mô tả | Giá trị mặc định |
|---|---|---|
DB_HOST |
Host PostgreSQL | localhost |
DB_PORT |
Port PostgreSQL | 5432 |
DB_USER |
Username DB | postgres |
DB_PASSWORD |
Mật khẩu DB | postgres |
DB_NAME |
Tên database | ticketbox |
REDIS_HOST |
Host Redis | localhost |
REDIS_PORT |
Port Redis | 6379 |
JWT_SECRET |
Secret key ký JWT | (bắt buộc điền) |
QR_SECRET |
Secret key ký QR Code | (bắt buộc điền) |
JWT_EXPIRES_IN |
Thời gian sống Access Token | 1d |
SMTP_HOST |
SMTP server gửi email | smtp.gmail.com |
SMTP_USER |
Email tài khoản gửi | (tuỳ chọn) |
SMTP_PASS |
App password Gmail | (tuỳ chọn) |
Khi chạy qua Docker Compose: Các biến
DB_HOST,REDIS_HOSTsẽ tự động được ghi đè thànhdbvàredis(tên service nội bộ trong Docker network).
# Xem log của từng service
docker compose logs -f backend
docker compose logs -f frontend
docker compose logs -f db
# Seed lại dữ liệu từ đầu (xóa và tạo mới toàn bộ)
docker exec -it ticketbox_backend npm run seed:prod
# Truy cập shell database
docker exec -it ticketbox_postgres psql -U postgres -d ticketbox
# Dừng toàn bộ hệ thống
docker compose down
# Dừng và xóa toàn bộ volume (mất hết dữ liệu DB)
docker compose down -vNguyên nhân: File .env của backend bị trống hoặc giá trị DB_PASSWORD không khớp với cấu hình trong docker-compose.yml.
Cách khắc phục:
# Kiểm tra DB_PASSWORD trong docker-compose.yml (POSTGRES_PASSWORD)
# và đảm bảo .env của backend có giá trị trùng khớp
# Mặc định trong docker-compose.yml: POSTGRES_PASSWORD=postgres
# Chỉnh sửa src/backend/.env
DB_PASSWORD=postgresNguyên nhân: Redis container chưa khởi động hoặc cấu hình REDIS_HOST sai.
Cách khắc phục:
# Kiểm tra Redis đã chạy chưa
docker compose ps
# Khởi động lại Redis nếu cần
docker compose restart redis
# Đảm bảo .env có cấu hình đúng
REDIS_HOST=localhost # khi chạy ngoài Docker
REDIS_HOST=redis # khi backend chạy trong DockerNguyên nhân: File .env của frontend chưa được tạo (bị .gitignore loại trừ).
Cách khắc phục:
echo "NEXT_PUBLIC_API_URL=http://localhost:3000" > src/frontend-web/.envCách khắc phục:
# Tìm process đang dùng port (ví dụ 3000)
netstat -ano | findstr :3000 # Windows
lsof -i :3000 # macOS/Linux
# Dừng tất cả container và thử lại
docker compose down
docker compose up -dCách kiểm tra:
# Xem log chi tiết để tìm nguyên nhân
docker compose logs backend --tail=50Nguyên nhân thường gặp: DB chưa sẵn sàng khi backend start (healthcheck chưa pass) hoặc biến môi trường bị thiếu.
- Bản Đánh Giá Tổng Hợp Dự Án (35 Tiêu Chí): Đọc tại assessment.md - Đây là Blueprint tổng hợp để nghiệm thu dự án.
- Bản vẽ Kiến trúc & Sơ đồ C4: Xem chi tiết tại design.md.
- Logic Phân Quyền (RBAC): Đọc tại auth.md.
- Luồng Nghiệp Vụ Chi Tiết (Mua vé, Offline Sync, CSV VIP): Đọc tại business_flows.md.
- Lý do lựa chọn Stack Công nghệ: Đọc tại tech_stack_rationale.md.
Trong các thư mục con như src/frontend-web/ hay src/mobile-checkin/, bạn có thể thấy sự xuất hiện của các tệp tin như CLAUDE.md, AGENTS.md hoặc thư mục .claude/.
- Mục đích: Đây là các tệp cấu hình đặc thù của các công cụ AI Coding giúp các AI Agents hiểu được bối cảnh, phiên bản framework để viết code chính xác, tránh áp dụng sai các API đã lỗi thời (deprecated).
- Quản lý: Các tệp tin này đã được đưa vào
.gitignoreở thư mục gốc để không bị commit lên hệ thống quản lý mã nguồn.