Báo cáo chuyển đổi warehouse-service

batch · batch/detail · api

POST/api/client/page/batches/detail

Vòng
2
Cổng G1–G6
PENDING_SONAR
Bước
sonar-check
Nhánh đích
feat/thongpd/migrate-batch2

Báo cáo sai lệch — batch/detail — vòng 2

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: C → người cần đọc: spec + báo cáo
  • Số quy tắc: 12 · PASS 7 · DEVIATION có chủ đích 3 (R-01/R-09 D-02, R-02 D-01, R-11 D-03) · DEVIATION KHÔNG chủ đích 0 · UNVERIFIED 2 (R-04/R-05 SQL thật, R-12 gói dịch vụ)
  • Coverage thấp nhất: F-01 98.1% dòng / 94.7% nhánh
  • Finding logic: CRITICAL 0 · MAJOR 0 · MINOR 0 · UNSURE 0
  • Nghi vấn bug code cũ (mục 3c): 2 (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: 2 / lần sửa 1/3

1. Điều kiện đạt

Mã Mục tiêu Kết quả Bằng chứng
G1 mvnw verify ✅ verify/round-2/build.md (518 test, 0 lỗi)
G2 Test khớp test-plan, mọi R-xx có test ✅ verify/round-2/tc-map.md (36/36), oracle.md
G3 Coverage mỗi luồng ✅ verify/round-2/coverage.md
G4 0 issue Sonar CHỜ NGƯỜI sonar-ide.md
G5 0 finding CRITICAL/MAJOR ✅ verify/round-2/review-logic.md (0 finding, không cần xác minh)
G6 Không lách cổng ✅ verify/round-2/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 trong test-plan.md)

Coverage theo luồng

Luồng Tên % dòng % nhánh
F-01 Chi tiết lô 98.1% (106/108) 94.7% (36/38)

2. Ma trận truy vết

Quy tắc Tầng Code mới Test Golden Kết luận
R-01 C BatchController, BatchDetailRequest, BatchWebMapper TC-01..03 — DEVIATION có chủ đích (D-02: body lỗi theo starter)
R-02 C BatchQueryService.getBatchDetail TC-04, 05 — DEVIATION có chủ đích (D-01)
R-03 C BatchQueryService, BatchRelationalRepository.findById TC-06..09 — PASS (giữ D-04)
R-04 C BatchDetailLineReader TC-10..16 GM-01 UNVERIFIED (SQL chỉ test bằng mock, K-13)
R-05 C BatchDetailLineReader TC-17..22 GM-01 UNVERIFIED (ORDER BY giả của Hibernate 6, D-08)
R-06 C BatchDetailLineReader TC-23..25 — PASS
R-07 C BatchDetailLineReader, BatchDetailLineResponse TC-26..28 — PASS
R-08 C BatchDateTimes, BatchJpaMapper, BatchWebMapper, BatchInfoResponse TC-29..31 — PASS (múi giờ prod UNVERIFIED, D-09)
R-09 C BatchController, BatchDetailResponse TC-32, 33 — PASS
R-10 C BatchQueryService TC-34 — PASS
R-11 C BatchDetailLineReader, BatchRelationalRepository TC-35, 36 — DEVIATION có chủ đích (D-03: 417 → 500, giữ mã)
R-12 C — — — UNVERIFIED (D-07, không chuyển kiểm gói)

3. Người cần xem

# Vị trí Vì sao cần người xem
1 BatchQueryService.java:56-57 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ước i18n_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ệch migrations/batch/detail/report.md vòng 2 · sha256 e365da8067ea

v1 dựng 2026-11-09 14:46 · base commit đích 661efe9b8c