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

batch · batch/create · api

POST/api/client/page/batches/create

Vòng
1
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/create — 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: B → người cần đọc: spec + báo cáo + đoạn bị gắn cờ (mục 3)
  • Số quy tắc: 14 · PASS 8 · DEVIATION có chủ đích 4 (R-01/R-12 D-02, R-02 D-01, R-07 D-11, R-13 D-05) · DEVIATION KHÔNG chủ đích 0 · UNVERIFIED 3 (R-06 collation, R-11 dirty-check, R-14 gói dịch vụ)
  • Coverage thấp nhất: F-01 100% dòng / 91% nhánh
  • Finding logic: CRITICAL 0 · MAJOR 0 · MINOR 3 · UNSURE 0 (không cần xác minh)
  • Nghi vấn bug code cũ (mục 3c): 5 (CAO 0) · Quyết định tự chốt cần xác nhận (mục 3d): 9
  • Chạy bằng: /mig-auto (spec do spec-reviewer kiểm 2 lần, 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 mvnw verify ✅ verify/round-1/build.md (584 test)
G2 Test khớp test-plan ✅ verify/round-1/tc-map.md (32/32), 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 (3 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ưu lô (tạo; /create kèm id thì sửa) 100% (252/252) 91% (91/100)

2. Ma trận truy vết

Quy tắc Tầng Code mới Test Golden Kết luận
R-01 B BatchSaveRequest, BatchController.create TC-01..05 — DEVIATION có chủ đích (D-02 body lỗi)
R-02 B BatchManagementService.requireCompany TC-06, 07 — DEVIATION có chủ đích (D-01)
R-03 B BatchExpiryWarning TC-08 — PASS
R-04 B BatchDateParser, service TC-09..11 — PASS
R-05 B service loadOwnBatch TC-12, 13 GM-01 PASS (giữ D-04)
R-06 B service, BatchJpaRepository.findDuplicate TC-14..17 GM-01 UNVERIFIED (collation, JPQL IS NULL chưa chạy MSSQL)
R-07 B BatchWriter (khoá + đếm) TC-18..21 GM-01 DEVIATION có chủ đích (D-11 khoá); giữ D-03
R-08 B LegacyCleanText, service TC-22, 23 — PASS
R-09 B BatchStatusPolicy TC-24 — PASS
R-10 B BatchNormalizedName, service TC-25, 26 — PASS (giữ D-07)
R-11 B BatchDirtyCheck, service TC-27, 28 GM-01 UNVERIFIED (dirty-check Hibernate 5.6, D-08)
R-12 B controller, BatchItemResponse TC-29, 30 — PASS (giữ D-09)
R-13 B service @Transactional, translate TC-31, 32 — DEVIATION có chủ đích (D-05 417→500)
R-14 B — — — UNVERIFIED (D-10)

3. Người cần xem

# Vị trí Vì sao cần người xem
1 infrastructure/relational/batch/adapter/BatchWriter.java:18-53 sp_getapplock nhiều lệnh chưa chạy trên MSSQL; chờ > 10 s → 500 (F-logic-2)
2 BatchWriter.java:68-89, BatchRelationalRepository.java:148-160 F-logic-1 (MINOR): nhánh sửa ghi lúc commit, lỗi DB lúc flush không qua translate → có thể ra UNCERTAIN_ERROR thay vì EXCEPTION_ERROR
3 application/batch/BatchManagementService.java:94-169 F-logic-3 (MINOR): dựng giá trị ghi nằm ở application thay vì BatchDraft (domain) như spec mục 5
4 BatchJpaRepository.java:27-34 JPQL kiểm trùng viết tay thay derived query (Checkstyle ≤ 3 tham số)
5 BatchDirtyCheck.java, service update mô phỏng dirty-check Hibernate 5.6 (D-08)
6 Các file của batch/detail bị sửa: BatchController, BatchWebMapper, BatchErrorCode, BatchRepository, BatchRelationalRepository, BatchJpaEntity, BatchControllerTest, BatchRelationalRepositoryTest K-28: đã chạy lại test và verify đầy đủ — xanh
7 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ưu lô (tạo; /create kèm id thì sửa) KHỚP 11 / KHÁC 4 (D-01, D-05, D-11 + F-logic-2, F-logic-1) / CHỈ CÓ Ở CŨ 1 (kiểm gói dịch vụ, D-10) / CHỈ CÓ Ở MỚI 0 không Câu khoá nhiều lệnh BatchWriter.java:18-53 chưa chạy trên MSSQL thật; nhánh sửa ghi lúc commit ngoài translate (BatchWriter.java:68-89); mô phỏng dirty-check và response trả lotNo thô (BatchManagementService.java:120-150); kiểm trùng viết tay JPQL (BatchJpaRepository.java:27-34)

3c. Nghi vấn bug / sai ở code cũ (đã GIỮ nguyên khi chuyển)

B-01 Mã lô có thể trùng sau khi xoá lô

  • Mức nghi ngờ: TRUNG BÌNH — mã lô lẽ ra duy nhất; các mã khác (kho, sản phẩm) đã chuyển sang bộ đếm riêng.
  • Ở đâu: code cũ base:services/BaseSequenceService.java:337-374 → code mới (giữ) infrastructure/relational/batch/adapter/BatchWriter.java (countByComId), application/batch/BatchManagementService.java (create)
  • Code cũ đang làm gì: mã lô mới = "LH" + (số lô hiện có của công ty + 1), không kiểm mã đã dùng chưa.
  • Ví dụ cụ thể: công ty có LH1, LH2, LH3; xoá LH2 → còn 2 lô → lô mới được mã LH3, trùng lô đang có.
  • Vì sao nghi là sai: mã dùng để tìm/in nhãn, trùng mã gây nhầm lô.
  • Ảnh hưởng nếu đúng là bug: công ty từng xoá lô sẽ có mã trùng ở mỗi lần tạo tiếp theo cho tới khi số lượng vượt mã lớn nhất.
  • Đã xử lý khi chuyển: GIỮ. Test khoá: TC-19 (BatchManagementServiceTest#codeFromCountAfterDelete).
  • Nếu muốn sửa: dùng bộ đếm (SequenceService + seed max(mã)) ở BatchManagementService.create; đổi TC-18, TC-19. Hệ thống cũ chạy song song vẫn sinh mã theo đếm → hai bên có thể đụng mã.
  • Liên quan: D-03, R-07

B-02 Thêm số lô có dấu cách đầu lọt kiểm trùng

  • Mức nghi ngờ: TRUNG BÌNH
  • Ở đâu: code cũ backend:service/impl/BatchesManagementServiceImpl.java:206-217 → code mới BatchManagementService.save (findDuplicate với số lô thô)
  • Code cũ đang làm gì: so trùng bằng số lô chưa làm sạch rồi mới làm sạch khi lưu.
  • Ví dụ cụ thể: đã có lô A1 (không NSX, HSD 2026-12-31). Thêm " A1" cùng ngày → không báo trùng, lưu thành A1 → có 2 lô A1. Lần thêm A1 sau đó → lỗi hệ thống 500 thay vì báo trùng.
  • Vì sao nghi là sai: mục đích kiểm trùng bị vô hiệu bởi khoảng trắng.
  • Ảnh hưởng nếu đúng là bug: dữ liệu lô trùng; về sau thêm/sửa đúng số lô đó lỗi hệ thống.
  • Đã xử lý khi chuyển: GIỮ. Test khoá: TC-15 (a) (BatchManagementServiceTest#duplicateKeyUsesRawLotNo), TC-17.
  • Nếu muốn sửa: truyền LegacyCleanText.clean(lotNo) vào BatchDuplicateKey; đổi TC-15 (a).
  • Liên quan: D-06, R-06

B-03 /create kèm id sửa lô có sẵn

  • Mức nghi ngờ: THẤP — có thể có chủ đích (dùng chung hàm lưu).
  • Ở đâu: code cũ backend:web/rest/BatchesManagementResource.java:40-52 → code mới BatchController.create → BatchManagementService.save
  • Code cũ đang làm gì: API "thêm" gửi kèm id sẽ sửa lô đó.
  • Ví dụ cụ thể: POST /create {"id":5,"comId":10,"lotNo":"B2",…} → lô 5 đổi số lô thành B2, trả "Cập nhật thành công!".
  • Vì sao nghi là sai: tên API là thêm.
  • Ảnh hưởng nếu đúng là bug: client gửi nhầm id sẽ sửa dữ liệu.
  • Đã xử lý khi chuyển: GIỮ. Test khoá: TC-12, TC-13 (BatchManagementServiceTest#idOfOtherCompany, #createWithIdUpdates).
  • Nếu muốn sửa: controller /create bỏ id khi map command; đổi TC-13.
  • Liên quan: D-04, R-05

B-04 Tab trong số lô làm tên tìm kiếm có dấu cách

  • Mức nghi ngờ: THẤP
  • Ở đâu: code cũ backend:util/Common.java:1315-1329 + CleanTextListener → code mới BatchNormalizedName, BatchManagementService
  • Code cũ đang làm gì: tên chuẩn hoá tính trên số lô thô (chỉ xoá dấu cách thường), sau đó làm sạch đổi tab thành dấu cách.
  • Ví dụ cụ thể: số lô "A<tab>B" → lưu lot_no="A B", normalized_name="lh6|a b" → tìm "ab" trong danh sách lô không ra.
  • Vì sao nghi là sai: tên chuẩn hoá lẽ ra không còn dấu cách.
  • Ảnh hưởng nếu đúng là bug: hiếm (cần dán tab vào ô số lô).
  • Đã xử lý khi chuyển: GIỮ. Test khoá: TC-26 (a) (BatchManagementServiceTest#tabInLotNo).
  • Nếu muốn sửa: tính tên chuẩn hoá trên giá trị đã làm sạch; đổi TC-26 (a).
  • Liên quan: D-07, R-10

B-05 Sửa lô trả số lô chưa làm sạch

  • Mức nghi ngờ: THẤP
  • Ở đâu: code cũ backend:service/impl/BatchesManagementServiceImpl.java:248-258 → code mới BatchManagementService.update
  • Code cũ đang làm gì: khi sửa, response dựng trước khi lưu nên trả số lô đúng như client gửi; DB lưu bản đã làm sạch.
  • Ví dụ cụ thể: sửa số lô " A 1 " → response " A 1 ", DB "A 1".
  • Vì sao nghi là sai: response khác dữ liệu đã lưu (khi tạo thì đã làm sạch).
  • Ảnh hưởng nếu đúng là bug: giao diện hiển thị khác tới khi tải lại.
  • Đã xử lý khi chuyển: GIỮ. Test khoá: TC-30 (b) (BatchManagementServiceTest#updatedItemHasRawLotNo).
  • Nếu muốn sửa: dùng giá trị đã làm sạch trong BatchManagementService.update; đổi TC-30 (b).
  • Liên quan: D-09, 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 spec-review Spec qua 2 lần review (lần 2 thu hẹp); đã sửa theo CRITICAL/MAJOR: R-07, R-08, R-10, R-12, R-13, D-03, D-07, thêm D-11 — Đọc kỹ R-07, R-08, R-10
2 D-11 (LỖI KỸ THUẬT) + F-logic-2 Khoá sp_getapplock theo công ty trước khi đếm mã 2 request tạo cùng lúc (5 lô) → cũ LH6,LH6 / mới LH6,LH7; chờ khoá > 10 s → cũ vẫn tạo / mới 500 không ghi Chấp nhận khoá và thời gian chờ 10 s
3 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 TOKEN_EXPIRED / mới tạo lô Chấp nhận
4 D-02 (ADR BẮT KHÁC) Body theo starter trùng lô → cũ có "data":null / mới không có key data; body hỏng → cũ 400 rỗng / mới INVALID_REQUEST Client không phụ thuộc key data khi trùng
5 D-05 (ADR BẮT KHÁC) 417 → 500 giữ EXCEPTION_ERROR 2 lô trùng sẵn → cũ 417 / mới 500 Client không xử lý riêng 417
6 D-08 (MƠ HỒ) Mô phỏng dirty-check: chỉ ghi updater/update_time khi giá trị thô khác DB sửa không đổi gì → cả hai không ghi (UNVERIFIED) Chạy GM-01 xác nhận
7 D-10 (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 / mới tạo lô Gói kiểm ở gateway?
8 spec mục 7 Câu đếm mã lỗi do timeout: cũ có thể vẫn lưu LH1 (Hibernate không rollback-only với timeout) / mới 500 không ghi UNVERIFIED Chấp nhận
9 impl-notes giả định 1 JPQL (:x IS NULL AND col IS NULL) OR col = :x thay derived query cùng ngữ nghĩa (chưa chạy MSSQL) Chạy GM-01

4. Finding đã xác nhận

Không có finding CRITICAL/MAJOR. Ba finding MINOR (không qua xác minh, không sửa trong vòng lặp):

F-logic-1

  • Mức độ: MINOR · Loại: transaction · Quy tắc: R-13 (nhánh sửa)
  • Mô tả: nhánh sửa ghi UPDATE lúc commit, ngoài translate → lỗi DB lúc flush có thể ra UNCERTAIN_ERROR thay vì EXCEPTION_ERROR. Đề xuất entityManager.flush() trong BatchWriter.save ở nhánh sửa. Chi tiết: verify/round-1/review-logic.md.

F-logic-2

  • Mức độ: MINOR · Loại: parity · Quy tắc: R-07 (D-11)
  • Mô tả: chờ khoá > 10 s → 500, không ghi; cũ không có nhánh này. Đã đưa vào 3d #2.

F-logic-3

  • Mức độ: MINOR · Loại: architecture · Quy tắc: R-08, R-11
  • Mô tả: không có BatchDraft (domain) như spec mục 5; dựng giá trị ghi nằm ở application service.

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) — flush nhánh sửa trong translate — (không chặn)
F-logic-3 (MINOR) — tách BatchDraft sang domain — (không chặn)

7. So với vòng trước

Vòng đầu.

8. Thay đổi trong repo đích

28 file (verify/round-1/changed-files.md): 22 file src/main/java (16 mới, 6 sửa — các file sửa thuộc batch/detail), 2 file i18n, 4 file test. Không có file ngoài phạm vi.

9. Đề xuất bổ sung kinh nghiệm

Đề xuất Đưa vào đâu
ArchUnit R13 chặn cả sealed interface tên *Result → kết quả nhiều nhánh viết thành record có cờ + factory lessons.md 1b
Spring Data derived query 4 tham số vi phạm Checkstyle → @Query JPQL + SpEL trên một object tham số, giữ IS NULL bằng (:x IS NULL AND col IS NULL) OR col = :x lessons.md 1b
LF-31: ghi rõ \n,\r bị xoá hẳn (không thành dấu cách) — spec lần 1 hiểu sai legacy-facts.md LF-31
catch nuốt lỗi JPA trong transaction chung vẫn rollback-only, trừ QueryTimeoutException/LockTimeoutException (Hibernate không đánh dấu) lessons.md K-03
Sinh mã LH (lô) đếm bảng, không qua Redis — thêm vào LF-42 legacy-facts.md LF-42

Nguồn của trang này

  • Báo cáo sai lệch migrations/batch/create/report.md vòng 1 · sha256 741ac75ee740

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