Backend e-commerce REST API — project học Spring Boot (portfolio).
Mục tiêu: chạm vào đúng những "điểm đau" backend mà phỏng vấn viên hay đào: transaction khi đặt hàng, chống oversell bằng optimistic locking, JWT auth, DTO mapping, validation, global exception handling, pagination/filter.
- Spring Boot 3.3.x / Java 17
- Spring Data JPA + PostgreSQL
- Flyway (quản lý schema bằng migration)
- Spring Security + JWT (jjwt)
- MapStruct (entity ↔ DTO)
- springdoc-openapi (Swagger UI)
- Testcontainers (integration test với Postgres thật)
Tổ chức theo package-by-feature (mỗi domain một package, gom controller/service/ repository/entity/dto lại cùng chỗ) thay vì package-by-layer. Dễ điều hướng, dễ tách module sau này — và là một điểm để nói khi phỏng vấn.
dev.dada.minishop
├── config # Security, OpenAPI, JPA auditing
├── common # BaseEntity, ApiResponse, PageResponse
├── security # JwtService, filter, UserDetailsService
├── exception # GlobalExceptionHandler + custom exceptions
├── user # User, auth (register/login)
├── category
├── product
├── cart
├── order # <-- trái tim: @Transactional + optimistic locking
└── payment # mock, không tích hợp cổng thật
- Khởi động Postgres:
docker compose up -d
- Copy
.env.example→.envvà điền giá trị (đặc biệtJWT_SECRET). - Sinh Maven wrapper (chạy 1 lần, cần Maven cài sẵn):
mvn -N wrapper:wrapper
- Chạy app:
./mvnw spring-boot:run
- Swagger UI: http://localhost:8080/swagger-ui.html
Làm theo TASKS.md — backlog đã chia ticket như sprint thật, có thứ tự phụ thuộc.
Mỗi ticket có ID (vd MS-18); trong code các file stub đã ghi sẵn TODO MS-xx trỏ về
ticket tương ứng, nên bạn luôn biết file nào thuộc task nào.
Mỗi khi gặp vấn đề khó, ghi lại vào đây: vấn đề gì, vì sao, giải quyết ra sao. Đây chính là nguyên liệu kể chuyện trung thực khi phỏng vấn.
- (ví dụ) Khi làm
placeOrder, ban đầu chưa nghĩ tới 2 người mua cùng lúc → ...