Báo cáo sai lệch — batch/by-id — vòng 1
0. Kết luận nhanh
- Điều kiện đạt:
G1 ✅ G2 ✅ G3 ✅ G4 — G5 ✅ G6 ✅ → CHỜ KIỂM SONAR
- Trạng thái: SẴN SÀNG CHO NGƯỜI XEM
- Tầng rủi ro: C → người cần đọc: spec + báo cáo
- Số quy tắc: 7 · PASS 3 · DEVIATION có chủ đích 3 (R-01/R-06 D-02, R-02 D-01/D-03, R-07 D-03/D-08) · DEVIATION KHÔNG chủ đích 0 · UNVERIFIED 1 (R-03/R-04 SQL thật, D-07)
- Coverage thấp nhất: F-01 97.8% dòng / 89.1% nhánh
- Finding logic: CRITICAL 0 · MAJOR 0 · MINOR 1 · UNSURE 0
- Nghi vấn bug code cũ (mục 3c): 2 (CAO 0) · Quyết định tự chốt cần xác nhận (mục 3d): 7
- Chạy bằng:
/mig-auto · Số vòng: 1 / lần sửa 0/3
1. Điều kiện đạt
| Mã |
Mục tiêu |
Kết quả |
Bằng chứng |
| G1 |
mvnw verify |
✅ |
verify/round-1/build.md (670 test) |
| G2 |
Test khớp test-plan |
✅ |
verify/round-1/tc-map.md (19/19), oracle.md |
| G3 |
Coverage |
✅ |
verify/round-1/coverage.md |
| G4 |
Sonar |
CHỜ NGƯỜI |
sonar-ide.md |
| G5 |
Finding CRITICAL/MAJOR |
✅ |
verify/round-1/review-logic.md (1 MINOR) |
| G6 |
Lách cổng |
✅ |
verify/round-1/gates.md |
Không chặn nhưng cần người: Integration test CHƯA CHẠY · Golden master CHƯA CHẠY (GM-01)
Coverage theo luồng
| Luồng |
Tên |
% dòng |
% nhánh |
| F-01 |
Lô và tồn theo lô của sản phẩm |
97.8% (91/93) |
89.1% (41/46) |
2. Ma trận truy vết
| Quy tắc |
Tầng |
Code mới |
Test |
Golden |
Kết luận |
| R-01 |
C |
ProductBatchController, request |
TC-01, 02 |
— |
DEVIATION có chủ đích (D-02) |
| R-02 |
C |
BatchQueryService.getProductBatches |
TC-03..05 |
— |
DEVIATION có chủ đích (D-01, D-03) |
| R-03 |
C |
ProductBatchReader, BaseNormalizedName |
TC-06..09 |
GM-01 |
UNVERIFIED (SQL mock) |
| R-04 |
C |
service, reader |
TC-10..14 |
— |
PASS (giữ D-05) |
| R-05 |
C |
reader, ProductBatchResponse |
TC-15, 16 |
— |
PASS (giữ D-06) |
| R-06 |
C |
controller |
TC-17 |
— |
PASS |
| R-07 |
C |
@Transactional, reader |
TC-18, 19 |
— |
DEVIATION có chủ đích (D-03, D-08); UNVERIFIED nguồn đọc (D-07) |
3. Người cần xem
| # |
Vị trí |
Vì sao cần người xem |
| 1 |
ProductBatchReader.java:98,105-113 |
Câu đếm bind "", câu dữ liệu có phân trang bind null; offset ép (int) — cố ý như cũ |
| 2 |
BaseNormalizedName.java |
F-logic-1 (MINOR): chèn | theo result.isEmpty() thay cờ first — lệch chỉ khi phần đầu chỉ có dấu kết hợp, API này truyền 1 phần tử nên không đổi kết quả |
| 3 |
G4 |
Chưa kiểm Sonar |
3b. Phân tích luồng sau chuyển
Chi tiết: verify/round-1/flow-analysis.md
| Luồng |
Tên |
Số bước KHỚP / KHÁC / CHỈ CÓ Ở CŨ / CHỈ CÓ Ở MỚI |
Lệch luồng đã duyệt (spec mục 6) |
Điểm dev cần chú ý |
| F-01 |
Lô và tồn theo lô của sản phẩm |
19 bước: 14 KHỚP / 5 KHÁC có chủ đích (D-01, D-02, D-03, D-08) / 0 CHỈ CÓ Ở CŨ / 0 CHỈ CÓ Ở MỚI |
lệch spec mục 6: không |
Hai cách bind null khác nhau giữa câu đếm và câu dữ liệu có phân trang, và offset ép (int) — cả hai cố ý giữ như cũ (ProductBatchReader.java:98,105-113). PageImpl dùng pageable gốc (:118). Các chỗ ép kiểu cột theo vị trí chỉ test bằng mock (:126-135). Thứ tự kiểm token → comId → phân trang ở BatchQueryService.java:60-72 |
3c. Nghi vấn bug / sai ở code cũ (đã GIỮ nguyên khi chuyển)
B-01 Trạng thái lô trả dạng chuỗi
- Mức nghi ngờ: THẤP
- Ở đâu:
backend:domain/Batches.java:60-77 (ColumnResult(name="status", type=String)) → ProductBatchReader (String.valueOf), ProductBatchResponse.status
- Code cũ đang làm gì: cột số
status được đọc thành chữ.
- Ví dụ cụ thể: lô còn hạn →
"status":"1"; các API lô khác trả "status":1.
- Vì sao nghi là sai: không nhất quán kiểu.
- Ảnh hưởng nếu đúng là bug: client so
=== 1 sai.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-15, TC-16 (ProductBatchReaderTest#mapRow, ProductBatchControllerTest#lineJson).
- Nếu muốn sửa: đổi
ProductBatchLine.status/ProductBatchResponse.status sang Integer; đổi TC-15, TC-16.
- Liên quan: D-06, R-05
B-02 Lọc trạng thái theo cột job cập nhật
- Mức nghi ngờ: THẤP
- Ở đâu:
backend:repository/impl/BatchRepositoryImpl.java:216-219 → ProductBatchReader
- Code cũ đang làm gì: lọc
b.status (job cập nhật 4 giờ/lần), không tính theo ngày như màn danh sách lô.
- Ví dụ cụ thể: lô hết hạn hôm qua 00:00, job chưa chạy → cột vẫn 2; lọc
status=0 không thấy.
- Vì sao nghi là sai: lệch màn danh sách lô.
- Ảnh hưởng nếu đúng là bug: hiển thị lệch tối đa ~4 giờ.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-07 (ProductBatchReaderTest#statusFilter).
- Nếu muốn sửa: dùng điều kiện theo
exp_date như BatchFilterReader; đổi TC-07.
- Liên quan: D-04, R-03
3d. Quyết định AI tự chốt và thay đổi tự động (cần người xác nhận)
| # |
Nguồn |
AI đã làm gì |
Khác code cũ ở điểm nào (input → cũ / mới) |
Người cần xác nhận gì |
| 1 |
spec-review |
Spec qua 1 lần review (tầng C), các mục sửa theo MAJOR: mục 5 (F-spec-1: service tự bọc lỗi comId null và page/size sai) |
— |
Đọc mục 5 |
| 2 |
D-01 (PHỤ THUỘC NGOÀI) |
Chỉ giữ 2 kiểm token/công ty |
token cũ sau đổi mật khẩu → cũ 500 / mới trả dữ liệu |
Chấp nhận |
| 3 |
D-02 (ADR BẮT KHÁC) |
Body theo starter |
không có lô → cũ data=[] / mới không có key |
Chấp nhận |
| 4 |
D-03 (ADR BẮT KHÁC) |
417 → 500 giữ mã |
thiếu comId → cũ 417 / mới 500 |
Chấp nhận |
| 5 |
D-05 (MƠ HỒ) |
Giữ không ORDER BY |
phân trang có thể lặp/sót — cả hai |
Có muốn thêm ORDER BY |
| 6 |
D-07 (MƠ HỒ) |
Đọc DB chính |
UNVERIFIED |
Chạy thử nguồn đọc |
| 7 |
D-08 (PHỤ THUỘC NGOÀI) |
Không kiểm gói |
hết hạn dùng thử → cũ 400 / mới trả |
Gói kiểm ở đâu |
4. Finding đã xác nhận
F-logic-1 (MINOR, parity, R-03): xem mục 3 #2 — không sửa trong vòng lặp.
5. Finding bị loại
Không có.
6. Xử lý của người
| Vấn đề |
Cổng |
Chỉ thị |
| Chưa kiểm Sonar |
G4 |
|
F-logic-1 (MINOR) — BaseNormalizedName dùng cờ first như cũ |
— (không chặn) |
|
7. So với vòng trước
Vòng đầu.
8. Thay đổi trong repo đích
15 file: mới ProductBatchController, ProductBatchRequest, ProductBatchResponse, ProductBatchQuery, ProductBatchLine, ProductBatchPage, BaseNormalizedName, ProductBatchReader + 2 test mới; sửa BatchWebMapper, BatchQueryService, BatchRepository, BatchRelationalRepository, BatchQueryServiceTest. Không có file ngoài phạm vi.
9. Đề xuất bổ sung kinh nghiệm
| Đề xuất |
Đưa vào đâu |
Repo đích có hai bản chuẩn hoá tên: BatchNormalizedName (backend Common) và BaseNormalizedName (model BaseCommon, LF-32) — spec phải ghi rõ code cũ gọi bản nào |
lessons.md 1a |
Lỗi ném ở service trước khi vào adapter (NPE comId, PageRequest.of) không qua khối bọc lỗi của adapter — spec mục 5 phải chỉ rõ nơi bọc thành EXCEPTION_ERROR |
lessons.md K-11 |