Báo cáo sai lệch — warehouse/import-excel-validate — vòng 1
SVC = easyposbase:src/main/java/sds/ep/baseservice/services/impl/BaseWarehouseServiceImpl.java; đường dẫn mới tính từ
warehouse-service:src/main/java/com/softdreams/easypos/warehouse/. (Báo cáo CHẶN lần trước — thiếu Apache POI — ở verify/round-0/report.md.)
0. Kết luận nhanh
- Điều kiện đạt:
G1 ✅ G2 ✅ G3 ✅ G4 — G5 ✅ G6 ✅ → CHỜ KIỂM SONAR (máy đạt hết, chờ người kiểm G4)
- Trạng thái: SẴN SÀNG CHO NGƯỜI XEM
- Tầng rủi ro: A (tự động — R-09 kiểm công ty; phần còn lại chỉ đọc) → người cần đọc: spec + báo cáo + toàn bộ diff
- Số quy tắc: 15 · PASS 8 · DEVIATION có chủ đích 4 (R-01, R-03, R-09, R-14) · DEVIATION KHÔNG chủ đích 0 · UNVERIFIED 3 (R-11
IN () rỗng, R-15, R-10 trường hợp mã chỉ khoảng trắng Unicode)
- Coverage thấp nhất: F-01 100% dòng / 93.9% nhánh
- Finding logic: CRITICAL 0 · MAJOR 0 · MINOR 1 · UNSURE 0
- Nghi vấn bug code cũ (mục 3c): 11 (CAO 1) · Quyết định tự chốt cần xác nhận (mục 3d): 8
- Chạy bằng:
/mig-auto (spec do spec-reviewer kiểm, chưa có người duyệt) · 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 |
Kiến trúc ADR (mvnw verify: build, test, ArchUnit, Checkstyle/PMD/SpotBugs) |
✅ |
verify/round-1/build.md — 730 test, ArchUnit 36/36, 0 vi phạm |
| G2 |
Test khớp test-plan, mọi R-xx có test |
✅ |
verify/round-1/oracle.md — 50/50 TC khớp |
| G3 |
Coverage mỗi luồng (dòng ≥ 80%, nhánh ≥ 70%) |
✅ |
verify/round-1/coverage.md |
| G4 |
0 issue Sonar (người kiểm bằng SonarQube for IDE) |
CHỜ NGƯỜI |
sonar-ide.md (CHƯA KIỂM) |
| G5 |
0 finding logic CRITICAL/MAJOR đã xác nhận |
✅ |
verify/round-1/review-logic.md (chỉ 1 MINOR, không cần xác minh) |
| G6 |
Không lách cổng, không ghi ngoài phạm vi |
✅ |
verify/round-1/gates.md — 29 file, đều có trong impl-notes.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..GM-03 trong test-plan.md)
Coverage theo luồng
| Luồng |
Tên |
% dòng |
% nhánh |
| F-01 |
Đọc file Excel (adapter POI) |
100.0% |
93.9% |
| F-02 |
Kiểm dòng — tạo mới |
100.0% |
94.6% |
| F-03 |
Kiểm dòng — cập nhật |
100.0% |
94.6% |
| F-04 |
Kiểm dòng — type khác / không gửi |
100.0% |
94.0% |
2. Ma trận truy vết
| Quy tắc |
Tầng |
Code mới |
Test |
Golden |
Kết luận |
| R-01 |
C |
WarehouseController.validateImport, WarehouseImportSheetRequest |
TC-01, TC-02, TC-03, TC-01-EXTRA-1/2 |
— |
DEVIATION (có chủ đích, D-02: 400 INVALID_REQUEST thay body rỗng; file > 10MB theo starter — UNVERIFIED) |
| R-02 |
C |
PoiExcelImportReader.load |
TC-04..TC-07 |
GM-03 |
PASS |
| R-03 |
C |
PoiExcelImportReader.sheetOf |
TC-08 |
— |
DEVIATION (có chủ đích, D-02: 417 → 500 giữ mã) |
| R-04 |
C |
PoiExcelSheet.headerCellCount, WarehouseImportValidationService.validateImport |
TC-09..TC-13 |
GM-03 |
PASS |
| R-05 |
C |
WarehouseImportValidationService.readLines, PoiExcelSheet.isMergedRow/readRow |
TC-14..TC-18, TC-31 |
GM-03 |
PASS |
| R-06 |
C |
PoiExcelImportReader.rawValue, WarehouseImportSheetChecker.cleaned |
TC-19..TC-23 |
GM-03 |
PASS |
| R-07 |
C |
WarehouseImportSheetChecker |
TC-24..TC-30 |
— |
PASS |
| R-08 |
C |
WarehouseImportValidationService.validateImport |
TC-03, TC-32, TC-33 |
— |
PASS |
| R-09 |
A |
WarehouseImportValidationService.checkExisting, WarehouseImportExistingPolicy.uniqueBy |
TC-33..TC-36 |
GM-01, GM-02 |
DEVIATION (có chủ đích, D-01 kiểm công ty) |
| R-10 |
A |
WarehouseImportExistingPolicy.checkUpdate |
TC-37..TC-41 |
GM-01 |
PASS; trường hợp mã chỉ khoảng trắng Unicode → UNVERIFIED (F-logic-1) |
| R-11 |
A |
WarehouseImportExistingPolicy.checkCreate, nonEmpty, findAllByNameIn |
TC-42..TC-46 |
GM-02 |
PASS; danh sách rỗng IN () → UNVERIFIED (D-04) |
| R-12 |
C |
WarehouseImportValidationService.checkExisting, WarehouseImportSheetChecker |
TC-28, TC-47 |
— |
PASS |
| R-13 |
C |
WarehouseWebMapper.toImportValidateResponse/toImportRowResponse |
TC-01, TC-48, TC-49 |
GM-01..03 |
PASS (key rỗng bỏ theo D-02) |
| R-14 |
C |
@Transactional trên validateImport |
TC-50 |
— |
DEVIATION (lệch ADR có chủ đích, D-14 — giữ đọc DB chính) |
| R-15 |
B |
— (không chuyển) |
— |
— |
UNVERIFIED (D-03) |
3. Người cần xem
| # |
Vị trí |
Vì sao cần người xem |
| 1 |
Toàn bộ diff verify/round-1/changes.diff (29 file) |
Tầng A |
| 2 |
application/warehouse/WarehouseImportValidationService.java nonEmpty |
Cố ý ném lỗi hệ thống khi danh sách tra DB rỗng để giống code cũ (D-04, UNVERIFIED) — nếu monolith không lỗi thì đây là lỗi mới làm hỏng import tạo mới không có mã |
| 3 |
infrastructure/excel/PoiExcelImportReader.java |
Port nguyên văn POI; workbook đóng trước khi đọc (như cũ). Đã test bằng file .xlsx/.xls thật dựng trong bộ nhớ, chưa thử file mẫu thật của sản phẩm (GM-03) |
| 4 |
F-logic-1 (MINOR) |
Nhánh UPDATE cũng ném lỗi khi danh sách mã rỗng (chỉ xảy ra khi ô Mã chỉ có khoảng trắng Unicode) — spec R-10 chưa mô tả |
| 5 |
WarehouseController.validateImport |
indexSheet/type nhận qua record (Checkstyle 3 tham số); lỗi sai kiểu số đi qua handler binding của starter |
| 6 |
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 |
Đọc file Excel |
7 / 2 / 0 / 0 |
indexSheet/type qua record |
đóng workbook trước khi đọc; 2 chỗ bọc lỗi POI thành SystemException; binding model-attribute |
| F-02 |
Tạo mới |
7 / 3 / 0 / 1 |
kiểm DB tách sang WarehouseImportExistingPolicy |
thứ tự kiểm công ty → tên → mã, IN () rỗng (D-04); hàm gộp ném lỗi (D-09) |
| F-03 |
Cập nhật |
3 / 2 / 0 / 0 |
như F-02; nonEmpty(skus) ở UPDATE (F-logic-1) |
thứ tự ngắn mạch WH1 giữ như cũ |
| F-04 |
type khác / không gửi |
3 / 0 / 0 / 0 |
không |
bỏ qua kiểm DB trước bước kiểm công ty |
3c. Nghi vấn bug / sai ở code cũ (đã GIỮ nguyên khi chuyển)
B-01 Import tạo mới mà không dòng nào điền mã kho → (có thể) lỗi hệ thống cả file
- Mức nghi ngờ: CAO — đọc code thấy rõ câu SQL
SKU in () được gọi với danh sách rỗng; chưa chạy thật để chắc Hibernate 5.6 có dựng đúng câu đó không.
- Ở đâu: code cũ
SVC:1024,1058-1059, base:repositories/BaseWarehouseRepository.java:113 → code mới application/warehouse/WarehouseImportValidationService.java (nonEmpty)
- Code cũ đang làm gì: khi kiểm file tạo mới, hệ thống tra cả tên và mã kho trong DB. Nếu không dòng hợp lệ nào có mã (người dùng để trống cho hệ thống tự sinh), danh sách mã rỗng nhưng vẫn được đưa vào câu SQL.
- Ví dụ cụ thể: file 3 dòng chỉ có tên "Kho 1", "Kho 2", "Kho 3", cột mã để trống → hệ thống cũ (theo suy luận) và mới trả "Lỗi hệ thống". Chỉ cần điền mã cho một dòng thì kiểm bình thường. Đúng nghiệp vụ thì phải trả 3 dòng hợp lệ.
- Vì sao nghi là sai: điều kiện vào nhánh kiểm DB dùng "mã khác rỗng hoặc tên khác rỗng" — người viết rõ ràng có nghĩ tới danh sách rỗng nhưng dùng nhầm "hoặc".
- Ảnh hưởng nếu đúng là bug: mọi người dùng import tạo kho mà để hệ thống tự sinh mã đều không import được; có thể họ đã quen luôn điền mã.
- Đã xử lý khi chuyển: GIỮ (ném
SystemException(EXCEPTION_ERROR), HTTP 500). Test khoá: TC-43 (WarehouseImportValidationServiceTest#createWithoutAnySkuIsSystemError), TC-44 (#createWithoutAnyNameIsSystemError).
- Nếu muốn sửa: bỏ hàm
nonEmpty (danh sách rỗng → coi như không tìm thấy kho nào); đổi TC-43, TC-44. Trước hết chạy GM-02 (b) trên monolith: nếu monolith không lỗi thì D-04 sai và phải sửa ngay (không phải đổi nghiệp vụ).
- Liên quan: D-04, R-11, F-logic-1
B-02 Mã kho hợp lệ ở bước kiểm nhưng bị bỏ qua im lặng ở bước lưu
- Mức nghi ngờ: TRUNG BÌNH — lỗi nằm ở bước lưu (
save-data B-01, CAO); bước kiểm này làm người dùng tin là ổn.
- Ở đâu: code cũ
SVC:1058-1059 → WarehouseImportValidationService.checkExisting
- Code cũ đang làm gì: kiểm "mã kho đã tồn tại" chỉ trong công ty của người dùng; bước lưu lại tra mã ở mọi công ty.
- Ví dụ cụ thể: công ty B đã có kho
KHO01; công ty A import tạo KHO01 → bước kiểm báo hợp lệ, bước lưu bỏ qua, kho không được tạo, không báo lỗi.
- Vì sao nghi là sai: hai bước của cùng một tính năng kiểm khác phạm vi.
- Ảnh hưởng nếu đúng là bug: như
save-data B-01.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-42, TC-35.
- Nếu muốn sửa: sửa ở
save-data (lọc com_id), bước kiểm giữ nguyên.
- Liên quan: D-08, R-11;
warehouse/import-excel-save-data B-01
B-03 Kho mặc định WH1 chỉ được bảo vệ khi bị ngừng và ẩn bán cùng lúc
- Mức nghi ngờ: TRUNG BÌNH — câu thông báo nói "hoặc" nhưng code dùng "và".
- Ở đâu: code cũ
SVC:1041-1042 → domain/warehouse/policy/WarehouseImportExistingPolicy.checkUpdate
- Code cũ đang làm gì: chặn dòng cập nhật kho WH1 chỉ khi trạng thái "ngừng" và bán trực tiếp "không" cùng lúc.
- Ví dụ cụ thể: dòng
{WH1, Kho tổng, Ngừng hoạt động, Có} → hợp lệ, bước lưu ngừng kho mặc định. {WH1, …, Ngừng hoạt động, Không} → bị chặn.
- Vì sao nghi là sai: API sửa kho chặn đổi từng thuộc tính của kho mặc định; câu lỗi dùng chữ "hoặc".
- Ảnh hưởng nếu đúng là bug: kho mặc định bị ngừng qua import, các luồng bán hàng dựa vào kho mặc định có thể lỗi.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-39 (#defaultWarehouseLockedOnlyWhenBothFalse).
- Nếu muốn sửa: đổi
&& thành || giữa hai điều kiện trạng thái/bán; đổi TC-39 (b), (c).
- Liên quan: D-06, R-10
B-04 SĐT/mã kho nhập dạng số trong Excel bị đổi thành dạng 9.12345678E8
- Mức nghi ngờ: TRUNG BÌNH — người dùng Excel hay gõ số điện thoại vào ô kiểu số.
- Ở đâu:
model:util/BaseCommon.java:1984-1987, SVC:952-955 → PoiExcelImportReader.rawValue, WarehouseImportSheetChecker.cleaned
- Code cũ đang làm gì: đọc ô số bằng định dạng số thực của Java, chỉ bỏ đuôi
.0.
- Ví dụ cụ thể: ô SĐT số
912345678 → "9.12345678E8" → "Số điện thoại không hợp lệ". Mã kho số 12345678 → mã "1.2345678E7".
- Vì sao nghi là sai: người dùng thấy "912345678" trên Excel nhưng hệ thống báo sai.
- Ảnh hưởng nếu đúng là bug: dòng bị báo lỗi oan, hoặc mã kho bị biến dạng.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-19, TC-21, TC-22.
- Nếu muốn sửa: đọc ô số bằng
DataFormatter; đổi TC-19, TC-22.
- Liên quan: D-05, R-06, R-07
B-05 Kiểm trùng phân biệt hoa thường và dấu cách thừa
- Mức nghi ngờ: TRUNG BÌNH
- Ở đâu:
SVC:918-922,932-935,1034,1066,1072 → WarehouseImportSheetChecker, WarehouseImportExistingPolicy
- Code cũ đang làm gì: trùng trong file so chuỗi nguyên văn; trùng với DB thì SQL tìm theo cách so của DB (không phân biệt hoa thường) nhưng lại đối chiếu lại bằng so nguyên văn.
- Ví dụ cụ thể: DB có "Kho A", file tạo mới "kho a" → không báo trùng. File có "Kho A" và "Kho A" → không báo trùng, cả hai lưu "Kho A". Cập nhật mã "k01" khi DB lưu "K01" → "Không tìm thấy mã kho hàng".
- Vì sao nghi là sai: cùng một tên/mã nhưng kết quả kiểm khác nhau.
- Ảnh hưởng nếu đúng là bug: dữ liệu kho trùng tên lọt qua; báo "không tìm thấy" oan.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-26, TC-38, TC-45.
- Nếu muốn sửa: so không phân biệt hoa thường sau làm sạch; đổi các TC trên.
- Liên quan: D-07, R-07, R-09..R-11
B-06 Import cập nhật không kiểm trùng tên/mã
- Mức nghi ngờ: TRUNG BÌNH
- Ở đâu:
SVC:919,932,1026-1051 → WarehouseImportSheetChecker, WarehouseImportExistingPolicy.checkUpdate
- Code cũ đang làm gì: chỉ kiểm trùng khi tạo mới; cập nhật không so tên với kho khác, không kiểm mã lặp trong file.
- Ví dụ cụ thể: DB
{K01, Kho A}, {K02, Kho B}; file cập nhật {K02, Kho A} → hợp lệ → công ty có 2 kho "Kho A".
- Vì sao nghi là sai: API sửa kho chặn tên trùng.
- Ảnh hưởng nếu đúng là bug: tên kho trùng nhau.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-28.
- Nếu muốn sửa: thêm kiểm trùng tên cho UPDATE (trừ chính kho đó); thêm TC.
- Liên quan: D-15, R-07, R-10
B-07 Dừng ở dòng trống đầu tiên, bỏ dòng có gộp ô, bỏ dòng sau 2000 — không báo
- Mức nghi ngờ: TRUNG BÌNH
- Ở đâu:
SVC:889-910,993-996,1091-1098 → WarehouseImportValidationService.readLines
- Code cũ đang làm gì: gặp dòng trống thì ngừng đọc; dòng có ô gộp bị bỏ; chỉ đọc 2000 dòng.
- Ví dụ cụ thể: file 10 dòng, dòng 4 trống → chỉ 3 dòng được kiểm, 6 dòng sau mất không báo.
- Vì sao nghi là sai: người dùng không biết dòng bị bỏ.
- Ảnh hưởng nếu đúng là bug: import thiếu dữ liệu.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-14, TC-16, TC-17.
- Nếu muốn sửa: đọc tiếp qua dòng trống hoặc báo lỗi; đổi các TC trên.
- Liên quan: D-10, R-05
B-08 Trạng thái / bán trực tiếp nhập lạ → thành "ngừng" / "không", không báo lỗi
- Mức nghi ngờ: THẤP
- Ở đâu:
SVC:938-949,976-982 → WarehouseImportSheetChecker.assign
- Ví dụ cụ thể: Trạng thái "Hoạt động" (thiếu "Đang") → kho thành ngừng hoạt động, dòng vẫn hợp lệ.
- Code cũ đang làm gì / vì sao nghi: chỉ nhận đúng chữ "Đang hoạt động", "Có"; giá trị khác thành
false mà không cảnh báo.
- Ảnh hưởng nếu đúng là bug: lỗi gõ đổi trạng thái kho.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-29.
- Nếu muốn sửa: báo lỗi giá trị không nhận ra; đổi TC-29 (e), (f).
- Liên quan: D-13, R-07
B-09 DB có 2 kho trùng mã/tên trong công ty → lỗi hệ thống cả file
- Mức nghi ngờ: THẤP
- Ở đâu:
SVC:1028-1029,1055-1059 → WarehouseImportExistingPolicy.uniqueBy
- Ví dụ cụ thể: công ty có 2 kho "Kho tổng" → file tạo mới có dòng "Kho tổng" → "Lỗi hệ thống".
- Code cũ đang làm gì / vì sao nghi: gom kết quả DB vào map không cho trùng khoá; dữ liệu bẩn làm lỗi chung chung.
- Ảnh hưởng nếu đúng là bug: công ty có dữ liệu trùng không import được.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-36.
- Nếu muốn sửa: lấy kho đầu tiên; đổi TC-36.
- Liên quan: D-09, R-09
B-10 Lỗi file trả 3 kiểu; tiêu đề chỉ đếm đủ 7 ô
- Mức nghi ngờ: THẤP
- Ở đâu:
SVC:854-877 → PoiExcelImportReader, WarehouseImportValidationService.validateImport
- Ví dụ cụ thể: file không mở được → 200
status=false; tiêu đề sai → 400; sheet sai → lỗi hệ thống. File mẫu sản phẩm 7 cột → qua kiểm tiêu đề, cột 2 bị hiểu là tên kho.
- Code cũ đang làm gì / vì sao nghi: không kiểm nội dung tiêu đề; 3 cách báo lỗi khác nhau cho cùng loại vấn đề.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-04, TC-08..TC-13.
- Nếu muốn sửa: kiểm tên cột, thống nhất mã lỗi; đổi các TC trên.
- Liên quan: D-11, R-02..R-04
B-11 Không gửi type vẫn báo kiểm tra thành công
- Mức nghi ngờ: THẤP
- Ở đâu:
SVC:918,926,1026,1053 → WarehouseImportValidationService.checkExisting
- Ví dụ cụ thể: không gửi
type, file có 2 dòng cùng tên "Kho A" → cả hai hợp lệ.
- Code cũ đang làm gì / vì sao nghi:
type không bắt buộc, không kiểm giá trị.
- Đã xử lý khi chuyển: GIỮ. Test khoá:
TC-28, TC-47.
- Nếu muốn sửa: 400 khi
type không phải 1/2; đổi TC-47.
- Liên quan: D-12, R-12
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 |
D-04 (MƠ HỒ) + F-logic-1 (MINOR) |
Danh sách tra DB rỗng (CREATE: mã hoặc tên; UPDATE: mã khi ô Mã chỉ khoảng trắng Unicode) → 500 EXCEPTION_ERROR |
file tạo mới không có mã → cũ 417 (suy luận) / mới 500 |
Chạy GM-02 (b) trên monolith. Nếu cũ không lỗi → bỏ nonEmpty, sửa TC-43, TC-44 |
| 2 |
D-01 (LỖI KỸ THUẬT) |
Kiểm comId là công ty của người đăng nhập ngay trước truy vấn DB đầu tiên |
user công ty 10 gửi comId=20 → cũ dò được tên/mã công ty 20 / mới 400 COMPANY_NOT_OF_CURRENT_USER |
Đồng ý vị trí kiểm (không kiểm khi không đọc DB) |
| 3 |
D-02 (ADR BẮT KHÁC) |
Body/HTTP theo starter |
thiếu tham số → cũ 400 body rỗng / mới 400 INVALID_REQUEST; lỗi không bắt 417 → 500 EXCEPTION_ERROR; key null/rỗng (id, phone, errorMessage:"", countWarning) mất do NON_EMPTY |
Vấn đề chung NON_EMPTY (như get-with-paging F-logic-1b); client có dựa vào errorMessage: "" không |
| 4 |
D-02 + R-01 |
File > 10MB: mới theo handler starter |
cũ 417 EXCEPTION_ERROR / mới chưa xác định (UNVERIFIED) |
Thử upload file 12MB |
| 5 |
D-03 (PHỤ THUỘC NGOÀI) |
Không kiểm gói dịch vụ |
công ty hết hạn gói → cũ 400 ACCOUNT_EXPIRED / mới kiểm được |
Chung mọi API |
| 6 |
D-14 (lệch ADR) |
@Transactional không readOnly, đọc DB chính |
không khác cũ; trái docs/rules/database-performance.md:290, ADR-0201 |
Duyệt lệch ADR để kết quả kiểm trùng thấy dữ liệu mới nhất |
| 7 |
Thiết kế (review-logic "Lệch mục 5") |
indexSheet/type qua record; kiểm DB ở domain policy; một FormulaEvaluator cho cả sheet |
sai kiểu indexSheet=abc → cũ 400 body rỗng / mới 400 qua handler binding của starter (chưa kiểm định dạng body) |
Đồng ý thiết kế |
| 8 |
spec-review |
spec qua 1 lần review, các R-xx đã sửa theo MAJOR: R-07 (F-spec-1: Trạng thái/Bán trực tiếp so trên giá trị đã làm sạch) |
— |
Đọc kỹ R-07 |
4. Finding đã xác nhận
Không có finding CRITICAL/MAJOR. Finding MINOR (không qua xác minh, chuyển cho người):
F-logic-1
- Mức độ: MINOR · Loại: parity · Quy tắc: R-10 (liên quan R-07, D-04)
- Code mới:
application/warehouse/WarehouseImportValidationService.java:119,140-145 · Code cũ: SVC:926-931,950,1010-1014,1024,1028
- Mô tả: ô Mã chỉ chứa
U+3000 làm dòng UPDATE hợp lệ với sku = null; UPDATE có thể tra DB với danh sách mã rỗng. Code mới ném 500 như D-04; spec R-10 ghi sai "skuList khác rỗng", D-04 chỉ nói CREATE.
- Kịch bản:
type=2, dòng {Mã " ", Tên "Kho A"} → cũ findBySkuIn([]) (417 nếu D-04 đúng, nếu không: 200 + "Không tìm thấy mã kho hàng") | mới 500.
- Đề xuất: không sửa code; sửa spec R-10/D-04 khi người duyệt (AI không sửa spec sau bước C). Đã ghi giả định này trong
impl-notes.md trước khi review.
5. Finding bị loại
6. Xử lý của người
| Vấn đề |
Cổng |
Chỉ thị |
| Kiểm Sonar các file thay đổi |
G4 |
|
7. So với vòng trước
| Vấn đề |
Vòng trước |
Vòng này |
CHẶN — thiếu Apache POI trong pom.xml |
CHẶN (lượt 20261105-1253) |
ĐÃ HẾT (người thêm POI 5.1.0, commit 61e71d8) |
| F-logic-1 |
— |
MỚI |
8. Thay đổi trong repo đích
29 file (verify/round-1/changed-files.md): 16 file mới ở src/main (port Excel 5, adapter POI 1, command/model/policy/result 6, service 1,
DTO 3), 6 file sửa ở src/main (WarehouseErrorCode, WarehouseRepository, WarehouseRelationalRepository, WarehouseJpaRepository,
WarehouseController, WarehouseWebMapper), 2 file i18n, 3 file test mới, 2 file test sửa (WarehouseControllerTest — constructor thêm mock,
WarehouseRelationalRepositoryTest). Không file nào ngoài phạm vi dự kiến; không chạm pom.xml.
9. Đề xuất bổ sung kinh nghiệm (/mig-learn gom vào proposal để người duyệt)
| Đề xuất |
Đưa vào đâu (lessons.md / review-criteria.md / rule ArchUnit / CLAUDE.md) |
Spotless đổi escape \uXXXX trong chuỗi thành ký tự thật → Sonar S2479; dựng ký tự đặc biệt bằng (char) 0x… |
lessons.md 1b/1c |
PMD CloseResource báo cả biến cục bộ kiểu Workbook đã đóng ở hàm khác — truyền qua tham số/Optional.map; InefficientEmptyStringCheck với trim().isEmpty() phải giữ nghĩa (≠ isBlank) |
lessons.md 1b (K-15) |
Port code đọc Excel: giữ phân biệt String.trim() (≤ U+0020) và isBlank() (Unicode) — sinh ra trạng thái "có giá trị nhưng không có chữ" (F-spec-2, F-logic-1) |
lessons.md 1a |
Collectors.toMap không hàm gộp / danh sách rỗng trong IN ?1 của Hibernate 5.6: hai nguồn lỗi hệ thống hay gặp, ghi D-xx khi spec |
legacy-facts.md (đề xuất) |
Hook chặn git config cả khi chỉ đọc; dùng git ls-files --eol để xem kiểu xuống dòng |
lessons.md Phần 2 |