Đây là ứng dụng web mini phục vụ quản lý thông tin Học sinh - Phụ huynh, quản lý Lớp học và Gói học (Subscription). Ứng dụng được xây dựng nhằm đáp ứng yêu cầu bài kiểm tra cho vị trí Product Builder.
- Frontend: Next.js (React), TailwindCSS.
- Backend: Node.js, Express, TypeScript.
- Database: PostgreSQL (Sử dụng thư viện
pgvới Raw SQL để tối ưu hóa hiệu suất và kiểm soát Transaction chặt chẽ). - DevOps: Docker, Docker Compose.
Hệ thống đã được đóng gói hoàn chỉnh bằng Docker. Bạn không cần cài đặt Node.js hay PostgreSQL trên máy thật.
Bước 1: Clone repository
git clone <link-repo-cua-ban>
cd teenup-testBước 2: Khởi chạy toàn bộ hệ thống
docker-compose up --buildLưu ý: Ngay khi Backend khởi động thành công, hệ thống sẽ tự động tạo cấu trúc bảng (Tables) trong PostgreSQL và tự động Seed dữ liệu mẫu.
Bước 3: Truy cập ứng dụng
- Frontend (Giao diện UI): http://localhost:3000
- Backend (RESTful API): http://localhost:4000
- PostgreSQL Database:
localhost:5432(User:admin, Pass:password, DB:teenup_db)
Hệ thống được thiết kế theo mô hình CSDL Quan hệ (Relational DB) gồm các bảng sau:
- Parent (
id,name,phone,email): Thông tin phụ huynh. - Student (
id,name,dob,gender,current_grade,parentId): Học sinh (quan hệ N-1 với Parent). - Class (
id,name,subject,day_of_week,start_time,end_time,teacher_name,max_students): Thông tin lớp học. - Subscription (
id,studentId,package_name,start_date,end_date,total_sessions,used_sessions): Quản lý gói học của học sinh. - ClassRegistration (
id,classId,studentId,classDate,createdAt): Bảng trung gian ghi nhận lịch sử đăng ký lớp học.
Dự án áp dụng Database Transaction (BEGIN, COMMIT, ROLLBACK) để xử lý các nghiệp vụ chặt chẽ, chống Race Condition:
- Kiểm tra sĩ số: Không cho phép đăng ký nếu
COUNT(registrations)>=max_students. - Kiểm tra trùng lịch: So sánh
start_timevàend_timecủa lớp đang đăng ký với các lớp đã đăng ký trong cùng ngày (classDate). - Kiểm tra gói học: Ưu tiên trừ buổi học vào gói (
Subscription) có thời hạn gần nhất vàused_sessions<total_sessions. - Hủy lịch hoàn buổi: Tính toán khoảng thời gian từ hiện tại đến giờ bắt đầu lớp. Nếu > 24h, tự động hoàn trả 1 buổi (
used_sessions - 1) vào gói học gần nhất.
Dưới đây là một số endpoint chính. Lưu ý: Dữ liệu (ID) dưới đây đã được hệ thống tự động Seed khi chạy server.
curl -X GET http://localhost:4000/api/classesGửi request đăng ký với studentId và classDate (Ngày diễn ra lớp học).
curl -X POST http://localhost:4000/api/classes/c1b1b1b1-b1b1-b1b1-b1b1-b1b1b1b1b1b1/register \
-H "Content-Type: application/json" \
-d '{
"studentId": "123e4567-e89b-12d3-a456-426614174000",
"classDate": "2024-05-20T00:00:00Z"
}'Thay <registration_id> bằng ID nhận được sau khi đăng ký thành công.
curl -X DELETE http://localhost:4000/api/registrations/<registration_id>Khi chạy Docker, hệ thống tự động chèn các dữ liệu sau để có thể test tính năng đăng ký ngay lập tức:
- 2 Classes: Toán Nâng Cao (ID:
c1b1...), Ngữ Văn (ID:c2b2...). - 1 Parent: Phụ huynh Test (ID:
p1b1...). - 1 Student: Học sinh Test (ID:
123e4567-e89b-12d3-a456-426614174000). - 1 Subscription: Gói Test 10 Buổi (còn hạn 30 ngày, 0/10 buổi sử dụng).