Nạp lô không kiểm công ty — giữ lỗ hổng cũ (B-01, CAO)
2
BatchDetailLineReader.java
SQL native chỉ test bằng mock; chạy GM-01 trên MSSQL thật
3
BatchJpaEntity.java (cột ngày kiểu Timestamp), BatchDateTimes.java
Chuỗi ngày chỉ đúng khi có hibernate.jdbc.time_zone; ws1 đặt ở application-dev/uat/prod.yml, application.yml không có
4
WarehouseTransferServiceTest.java
File test có sẵn bị sửa 1 dòng theo constructor mới của BatchQueryService
5
G4
Chưa kiểm Sonar
3b. Phân tích luồng sau chuyển
Chi tiết: verify/round-2/flow-analysis.md (vòng 1: 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
Chi tiết lô
không đổi so với vòng 1 (12 bước: KHỚP 8 / KHÁC 3, đều có chủ đích D-01, D-02, D-07 / CHỈ CÓ Ở CŨ 1 / CHỈ CÓ Ở MỚI 0)
lệch spec mục 6: không
Vẫn như vòng 1: BatchQueryService.java:56-57 nạp lô không kiểm công ty (D-04), SQL native và thứ tự COUNT → PageRequest → SELECT ở BatchDetailLineReader.java:96-112, ép kiểu theo vị trí cột ở :162-180, chuỗi ngày phụ thuộc hibernate.jdbc.time_zone
3c. Nghi vấn bug / sai ở code cũ (đã GIỮ nguyên khi chuyển)
B-01 Xem được thông tin lô của công ty khác
Mức nghi ngờ: CAO — rõ ràng truy vấn chi tiết có lọc công ty mà bước nạp lô thì không; đây là lộ dữ liệu giữa các khách hàng.
Ở đâu: code cũ backend:service/impl/BatchesManagementServiceImpl.java:393-395 → code mới (giữ nguyên) application/batch/BatchQueryService.java:56-57
Code cũ đang làm gì: tìm lô chỉ theo số id, không xem lô đó của công ty nào. Phần danh sách tồn bên dưới thì có lọc công ty nên trả rỗng.
Ví dụ cụ thể: nhân viên công ty 10 gửi {"id": 55}, lô 55 của công ty 20 (mã LO000123, số lô A1) → hệ thống cũ (và mới) trả 200 kèm đủ mã, số lô, hạn dùng, comId=20 của lô đó, details=[]. Đúng nghiệp vụ lẽ ra phải báo 400 BATCH_NOT_FOUND.
Vì sao nghi là sai: mọi API lô khác (save: findByIdAndComId) đều kiểm công ty; id tăng dần nên đoán được.
Ảnh hưởng nếu đúng là bug: bất kỳ người dùng đăng nhập nào cũng đọc được thông tin lô của doanh nghiệp khác.
Đã xử lý khi chuyển: GIỮ nguyên hành vi cũ. Test khoá: TC-07 (BatchQueryServiceTest#batchOfOtherCompanyStillReturned).
Nếu muốn sửa: thêm findByIdAndComId(id, comId) vào BatchRepository/adapter, gọi thay findById ở BatchQueryService.java:56; đổi TC-07 thành 400 BATCH_NOT_FOUND. Không cần sửa dữ liệu. Hệ thống cũ chạy song song vẫn lộ.
Liên quan: D-04, R-03
B-02 Lọc chi tiết lô dùng cột trạng thái và từ khoá thô
Mức nghi ngờ: THẤP — có thể là ý đồ của màn chi tiết.
Ở đâu: code cũ base:repositories/impl/BaseBatchRepositoryCustomImpl.java:51-66 → code mới infrastructure/relational/batch/adapter/BatchDetailLineReader.java
Code cũ đang làm gì: lọc status theo cột batches.status (job cập nhật 4 giờ/lần) chứ không tính theo ngày hết hạn như danh sách lô; từ khoá ghép thẳng vào LIKE, không bỏ dấu, không escape %/_.
Ví dụ cụ thể:keyword="10%" khớp mọi sản phẩm có mã/tên chứa "10"; keyword="sữa" có khớp "Sua tuoi" hay không tuỳ collation DB.
Vì sao nghi là sai: khác cách tìm của danh sách lô (get-with-paging bỏ dấu, chuẩn hoá).
Ảnh hưởng nếu đúng là bug: kết quả tìm kiếm trong màn chi tiết lô không như người dùng mong đợi; không sai dữ liệu.
Đã xử lý khi chuyển: GIỮ. Test khoá: TC-12 (BatchDetailLineReaderTest#statusFilterOnColumn), TC-14 (#keywordVerbatim).
Nếu muốn sửa: đổi buildFromWhere trong BatchDetailLineReader, đổi TC-12, TC-14.
Liên quan: D-06, R-04
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 R-xx/D-xx đã sửa theo MAJOR: R-03, D-05 (F-spec-1, text lỗi), R-08, D-09 (F-spec-2, cách đọc ngày)
—
Đọc kỹ R-03, R-08 trong spec.md
2
D-01 (PHỤ THUỘC NGOÀI)
Chỉ lấy companyId từ token
token quản trị không có công ty, id=5 → cũ 200 batch, details=[] / mới 500 COMPANY_NOT_EXISTS_CODE; token cũ sau đổi mật khẩu → cũ 500 TOKEN_EXPIRED / mới trả dữ liệu
Chấp nhận bỏ các kiểm user
3
D-02 (ADR BẮT KHÁC)
Body theo starter
{"id":"abc"} → cũ 400 body rỗng / mới 400 INVALID_REQUEST
Client không phụ thuộc body lỗi rỗng
4
D-03 (ADR BẮT KHÁC)
417 → 500, giữ EXCEPTION_ERROR
{} → cũ 417 / mới 500
Client không xử lý riêng 417
5
D-05 (MƠ HỒ)
Dùng lại text BATCH_NOT_FOUND sẵn có
không khác
—
6
D-07 (PHỤ THUỘC NGOÀI)
Không kiểm gói dịch vụ
công ty hết hạn dùng thử → cũ 400 TRIAL_EXPIRED / mới 200
Gói dịch vụ kiểm ở gateway hay chỗ khác
7
D-08 (MƠ HỒ)
Giữ SQL không ORDER BY
phân trang có thể lặp/sót dòng — cả hai
Có muốn thêm ORDER BY bd.id
8
D-09 (MƠ HỒ)
Đọc ngày theo jdbc.time_zone +7 rồi đổi múi JVM
trùng cũ khi cả hai cấu hình giống; UNVERIFIED
Múi giờ JVM prod cũ/mới
4. Finding đã xác nhận
Không có.
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
7. So với vòng trước
Vấn đề
Vòng trước
Vòng này
TC-06 thiếu kiểm text i18n (G2)
MỚI
ĐÃ HẾT
8. Thay đổi trong repo đích
29 file (verify/round-2/changed-files.md): 20 file src/main/java (context batch: presentation mới, BatchQueryService, BatchRepository, BatchRelationalRepository, BatchJpaEntity sửa), 2 file i18n, 7 file test (trong đó sửa WarehouseTransferServiceTest 1 dòng, BatchRelationalRepositoryTest đổi constructor). Không có file ngoài phạm vi.
9. Đề xuất bổ sung kinh nghiệm
Đề xuất
Đưa vào đâu
LF-15 thiếu ý: MessageSource monolith tra i18n/messages của backend trướci18n_custom của model (easyposmodel:…/config/BaseMessageSourceConfig.java:18) — text lỗi lấy từ easyposbackend1:src/main/resources/i18n/messages_vi.properties nếu có key; các unit trước có thể đã lấy nhầm text
legacy-facts.md (LF-15)
Entity Hibernate 6 đọc cột datetime như monolith (Hibernate 5.6 + jdbc.time_zone): dùng kiểu Timestamp rồi ofInstant(…, systemDefault); toLocalDateTime().atZone(systemDefault) chỉ đúng khi JVM +7
lessons.md 1b
ObjectMapper.valueToTree làm mất scale BigDecimal (12.500000 → 12.5) — test scale trên chuỗi writeValueAsString
lessons.md 1c
Nguồn của trang này
Báo cáo sai lệchmigrations/batch/detail/report.mdvòng 2 · sha256 e365da8067ea
v1 dựng 2026-11-09 14:46 · base commit đích 661efe9b8c