| Thư mục | Mô tả |
|---|---|
docs/ |
ERD Markdown + migration SQL PostgreSQL (tham chiếu / DBA) |
backend/ |
API NestJS + Prisma |
frontend/cms/ |
CMS — cổng mặc định 3001 (CMS_PORT trong .env) |
frontend/website/ |
Website học viên — cổng mặc định 3002 (WEBSITE_PORT) |
- Node.js 20+
- PostgreSQL (local hoặc Docker)
Sao chép env.example → .env và chỉnh nếu cần.
Mặc định trong env.example:
- API:
PORT=3000 - CMS / Website:
CMS_PORT=3001,WEBSITE_PORT=3002— dùng chung khi chạynpm run devở gốc (script đọc.envvà gánPORTcho từng Next.js) - PostgreSQL:
DATABASE_URL(chuỗi kết nối Prisma)
Nếu đổi PORT, CMS_PORT hoặc WEBSITE_PORT, hãy cập nhật NEXT_PUBLIC_API_URL (trỏ đúng cổng API) và CORS_ORIGIN (danh sách origin CMS + website) cho khớp.
Ví dụ:
PORT=3000
DATABASE_URL=postgresql://postgres:123456@localhost:5432/squiz?schema=publicTạo database: trên PostgreSQL tạo database tên squiz (hoặc dùng Docker Compose bên dưới — đã tạo sẵn DB squiz).
npm run install:allHoặc: npm install ở root, rồi npm install trong backend/, frontend/cms/, frontend/website/.
bash scripts/setup-dev.shScript tự động: kiểm tra Node.js 20+, tạo .env từ env.example nếu chưa có, cài npm dependencies, chạy Prisma migrate, áp patch legacy, seed dữ liệu mẫu và in tóm tắt tài khoản khi xong.
Cần file .env ở thư mục gốc (copy từ env.example):
npm run setupLệnh này chạy: prisma generate → prisma db push → prisma db seed.
Để dùng migration tracking (thay vì db push):
cd backend
npx prisma migrate deploy
npx prisma db seed| Mật khẩu | Vai trò | Ghi chú | |
|---|---|---|---|
admin@squiz.local |
Admin@123 |
ADMIN | Tài khoản quản trị chính |
le.nam@squiz.local |
Admin@123 |
ADMIN | Admin thứ hai |
teacher@squiz.local |
Teacher@123 |
TEACHER | |
chau.ngo@squiz.local |
Teacher@123 |
TEACHER | |
duc.nguyen@squiz.local |
Teacher@123 |
TEACHER | |
hanh.tran@squiz.local |
Teacher@123 |
TEACHER | |
tuan.dang@squiz.local |
Teacher@123 |
TEACHER | |
thao.pham@squiz.local |
Teacher@123 |
TEACHER | |
student@squiz.local |
Student@123 |
STUDENT | Có lượt thi COMPLETED |
student2@squiz.local |
Student@123 |
STUDENT | Có lượt thi PENDING_GRADING |
anh.ho@squiz.local |
Student@123 |
STUDENT | |
anh.trinh@squiz.local |
Student@123 |
STUDENT | |
dung.dinh@squiz.local |
Student@123 |
STUDENT | |
han.ly@squiz.local |
Student@123 |
STUDENT | |
huyen.nguyen@squiz.local |
Student@123 |
STUDENT | |
linh.do@squiz.local |
Student@123 |
STUDENT | |
long.vu@squiz.local |
Student@123 |
STUDENT | |
mai.phan@squiz.local |
Student@123 |
STUDENT | |
quang.bui@squiz.local |
Student@123 |
STUDENT | |
thai.duong@squiz.local |
Student@123 |
STUDENT |
| Loại | Số lượng | Chi tiết |
|---|---|---|
| Phòng ban | 3 | Phòng Đào tạo, Khoa CNTT, Khoa Kinh tế |
| RBAC | 35 permissions, 3 roles | ADMIN / TEACHER / STUDENT |
| Câu hỏi | 30+ | Trắc nghiệm đơn/đa, tự luận, lỗi sai, đọc hiểu, nghe, tin học VP, bảo hiểm |
| Đề thi (PRACTICE/MOCK) | 10 | Tiếng Anh (3), CNTT (3), BH (2), bảo hiểm pool/động (2) |
| Đề thi nội bộ | 6+ | Tổng hợp, pool, động (matrix), draft, demo cửa sổ thời gian |
| Cuộc thi | 6 | Xem chi tiết bên dưới |
| Lượt thi mẫu | 4 | COMPLETED + PENDING_GRADING (student / student2) |
| Ghi danh cuộc thi | 5 | 5 học viên đã ghi danh vào cuộc thi demo |
| Feedback | 2 | PENDING + RESOLVED |
Cuộc thi mẫu:
| # | Tên | Trạng thái | Ghi chú |
|---|---|---|---|
| 1 | English Sprint — Tháng 4/2026 | Đang diễn ra | 20/4–30/4/2026, bảng XH điểm |
| 2 | CNTT Sprint — Mạng & An toàn thông tin | Đang diễn ra | 22/4–8/5/2026, XH theo thời gian |
| 3 | Olympic Tin học VP — Kỳ 1/2026 | Sắp mở (26/4) | Mở ghi danh, top 5 |
| 4 | BH Chứng chỉ Đại lý Q2/2026 | Sắp mở (1/5), Featured | Mở ghi danh, 1 lượt, có tự luận |
| 5 | Đại hội Kiến thức Tổng hợp — 5/2026 | Sắp mở (5/5), Featured | Tiếng Anh + CNTT + BH |
| 6 | Demo Ghi danh & Nhắc giờ | Bắt đầu sau ~24h (seed) | 5 học viên đã ghi danh sẵn |
Seed idempotent — chạy lại npm run setup / bash scripts/setup-dev.sh nhiều lần an toàn (tiền tố SEED:).
npm run devMột lệnh khởi động (nếu .env có REDIS_URL, script sẽ chạy docker compose up -d redis trước rồi chờ cổng Redis mở):
- API: http://localhost:3000/api — Swagger http://localhost:3000/api/docs
- CMS: http://localhost:3001
- Website: http://localhost:3002
Biến môi trường được nạp từ .env gốc (kể cả NEXT_PUBLIC_API_URL cho Next.js).
Backend
cd backend
npm run start:devCMS / Website: nếu chạy npm run dev trong từng thư mục (không qua npm run dev ở root) thì đặt biến PORT (ví dụ 3001 / 3002) trong shell vì Next.js đọc PORT cho next dev / next start.
Trong thư mục gốc repo (nơi có docker-compose.yml), tạo .env (copy từ env.example → .env, chỉnh JWT_SECRET và cổng nếu cần), rồi:
docker compose up -d(Tương đương: npm run docker:stack — cũng chỉ gọi docker compose up -d.)
Lệnh này không được gõ thêm tên service phía sau (ví dụ đừng viết postgres redis…). Khi đó Compose khởi động toàn bộ:
| Thành phần | Service trong Compose |
|---|---|
| Backend (NestJS API) | api |
| Frontend CMS (Next.js) | cms |
| Frontend website (Next.js) | website |
| PostgreSQL, Redis, MinIO, RabbitMQ | postgres, redis, minio, rabbitmq (+ minio-setup tạo bucket) |
Lần đầu chạy (chưa có image), Compose tự build api, cms, website từ Dockerfile rồi chạy. Nếu đã có image cũ và bạn vừa sửa code, cần build lại: docker compose up -d --build hoặc npm run docker:up hoặc stack-up.cmd / ./stack-up.sh / make up.
Sau khi container lên (lần đầu API chạy prisma db push, có thể ~1 phút):
- API:
http://localhost:3000/api— Swaggerhttp://localhost:3000/api/docs - CMS:
http://localhost:3001 - Website:
http://localhost:3002 - MinIO console:
http://localhost:9001(minio/minio12345) - RabbitMQ UI:
http://localhost:15672(squiz/squiz)
Seed dữ liệu mẫu (một lần):
- Khuyến nghị (luôn chạy được): dùng service
seed(không phụ thuộcapiđang Up):
npm run docker:seedHoặc thủ công: docker compose up -d postgres rồi docker compose run --rm seed.
- Nếu container
apiđang chạy: bạn có thể chạy trực tiếp:docker compose exec api npx prisma db seed.
Dừng stack: npm run docker:down hoặc docker compose down.
Ghi chú: NEXT_PUBLIC_API_URL trong .env được truyền lúc build image Next.js — nếu đổi cổng API, chạy lại docker compose build cms website (hoặc docker compose up --build). Trình duyệt trên máy host vẫn gọi API qua http://localhost:<PORT> nên URL đó phải khớp cổng đã publish.
Lưu ý: Schema DB trong container do entrypoint API (prisma db push) tạo. File docs/migrations/001_init_squiz_sfb_erd.sql dùng tham chiếu / triển khai thủ công.
Chỉ dùng khi bạn tự chạy backend và frontend trên máy (npm run dev) nhưng muốn các dịch vụ nền bằng container:
docker compose up -d postgres redis minio rabbitmqCảnh báo: Nếu gõ docker compose up -d postgres redis minio rabbitmq thì sẽ không khởi động api, cms, website. Muốn cả project trong Docker thì chỉ dùng docker compose up -d (không liệt kê service).
Lỗi dependency api failed / api không healthy: Xem log: docker compose logs api --tail 80. Image API dùng Alpine + OpenSSL cho Prisma; sau khi đổi Dockerfile / schema.prisma cần docker compose build api --no-cache rồi docker compose up -d. Healthcheck gọi GET /api/health/live; cms/website chờ api healthy.
Xem docs/erd-squiz-sfb.md.