
Tech stack
Chi tiết dự án
HCLib — Full-stack Library Management System
Quản lý mượn trả · Catalog nhiều quan hệ · Phân quyền và phiên đăng nhập
Vai trò: Solo developer cho cả frontend và backend. Tôi thiết kế kiến trúc và tự build toàn bộ luồng mượn trả, catalog và xác thực.
Next.js 15 · React 19 · TypeScript · NestJS 11 · TypeORM · PostgreSQL · Redis · Docker Compose
HCLib là hệ thống quản lý thư viện cho staff vận hành hằng ngày. Phần khó nhất nằm ở luồng mượn trả nhiều bản copy, cập nhật tồn kho đúng trạng thái và giữ dữ liệu catalog nhất quán khi một cuốn sách có nhiều relation.
Kiến trúc Hệ thống
Frontend và backend tách thành hai app riêng: admin UI iterate nhanh, domain logic giữ transaction boundary rõ. Feature-first ở client giúp route layer mỏng; domain-centric ở server nhốt validation, state transition và side-effect vào đúng module. Redis, health check và scheduled sync tách khỏi happy path để request chính gọn và deploy dễ kiểm soát.
Quản lý vòng đời phiếu mượn
Vấn đề: Phiếu mượn trong thư viện thật không phải một record đơn giản — nhiều copy, mỗi copy có due date, condition và trạng thái trả riêng. Xử lý hời hợt dễ double-loan, sai tồn kho hoặc transition không hợp lệ. Staff UI cần flow đủ nhanh tại quầy nhưng vẫn chặn member không active, copy đã mượn, trả sách hư mà quên tạo phạt.
Giải pháp: Đóng gói loan lifecycle thành domain flow thống nhất — UI orchestration, state validation và inventory mutation ở service layer với transaction và atomic update.
Cách thực hiện:
- Form tạo phiếu: chọn member, staff, nhiều book copy, due date, loan condition trong một màn hình — giảm context switch cho thủ thư
- UI map server validation errors (ví dụ
items[0].copy_id) về đúng React Hook Form path để lỗi hiển thị tại item gây lỗi - Backend
LoanService.create()trong transaction: validate member ACTIVE, staff tồn tại, rồi insert loan items LoanItemService.insertMultiple()kiểm tra từng copy AVAILABLE, atomic updateAVAILABLE -> BORROWED, rollback nếu copy đã bị lấy — chặn race condition ở DB- Trả sách: modal 2 bước chọn condition khi trả; nếu sách xuống condition xấu, UI tạo fine trước rồi mới gọi return
- State transition tách endpoint:
return,renew,lost,complete— logic “không complete khi còn item chưa trả” nằm ở backend
Kết quả: Circulation khó nhất gom vào một flow, boundary rõ giữa UI và business rules. Tránh bug “cùng copy mượn 2 lần”, giảm case xử lý thủ công. Tách loan-level và item-level state giúp mở rộng lost/renew/fine mà không phá cấu trúc.

Catalog management với quan hệ phức hợp
Vấn đề: Thêm sách không chỉ insert một dòng — record hợp lệ cần đúng publisher, nhiều author (role + order), nhiều category, cover image, ISBN unique. Form dễ thành “monster form” khi selectors load động và ảnh phải upload trước submit.
Giải pháp: Catalog flow thành composite form nhiều khối; upload cover trước lấy file id, backend validate toàn bộ relation trong transaction rồi ghi Book, BookAuthor, BookCategory.
Cách thực hiện:
- Form tạo sách: basic info, metadata, cover upload, relational selectors — staff nhập nhanh không ngợp
AuthorSelector: debounced search, multi-select, gán role, reorder drag-and-drop — nhiều author + thứ tự thành UI tự nhiên- Frontend upload cover qua
fileService→ nhậncover_id→ gửi payload sách; backend book endpoint không xử lý multipart + business cùng lúc - Backend
BookService.create(): validate ISBN unique, publisher/category/author tồn tại, cover file tồn tại, rồi insert trong một transaction - Relation tables BookAuthor, BookCategory save riêng; scheduled job đồng bộ stats sách hằng ngày
Kết quả: Entity chính + nhiều relation, payload sạch dễ debug. Form business “dày” vẫn usable, complexity ở selector layer, upload layer và transaction layer.

CI/CD & Deploy
- Pipeline: lint-staged, backend jest, frontend eslint/next build, healthcheck ở container level
- Docker:
docker-composedev,docker-compose.prod.ymlproduction,docker-compose.ci.ymlcho image-based deploy - Deploy: host reverse proxy trỏ hai service container (frontend app + backend API)
Các màn hình chính
Danh sách mượn trả
Màn hình mượn trả cho thủ thư: tạo phiếu mượn, theo dõi trạng thái từng bản copy và xử lý trả sách.
Đặt sách
Luồng đặt trước cho người đọc, từ giữ chỗ sách tới theo dõi trạng thái đặt.
Quản lý tiền phạt
Màn hình ghi nhận và theo dõi tiền phạt cho các trường hợp trễ hạn, hư hỏng hoặc mất sách.
Quản lý đầu sách
Quản lý đầu sách, bản copy và dữ liệu liên quan trong danh mục sách.
Quản lý thành viên
Quản lý hồ sơ thành viên, trạng thái hoạt động và các thao tác liên quan.