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

Tồn kho · inventory/get-detail-product · api

GET/api/client/page/inventory/get-detail-product

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

Báo cáo sai lệch — inventory/get-detail-product — vòng 1

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 (chỉ đọc) → người cần đọc: spec + báo cáo
  • Số quy tắc: 11 · PASS 4 (R-03, R-04, R-05, R-07) · DEVIATION có chủ đích 5 (R-01, R-02, R-08, R-10, R-11) · DEVIATION KHÔNG chủ đích 0 · UNVERIFIED 2 (R-06 thứ tự lô trong kho, R-09 DB đọc của code cũ) — xem mục 2
  • Coverage thấp nhất: F-01 100% dòng (38/38) / nhánh N/A (0 nhánh mới)
  • Finding logic: CRITICAL 0 · MAJOR 0 · MINOR 1 · UNSURE 0
  • Nghi vấn bug code cũ (mục 3c): 1 (CAO 0) · Quyết định tự chốt cần xác nhận (mục 3d): 7
  • Chạy bằng: /mig-auto lượt 20261105-1351 (spec do spec-reviewer kiểm, chưa có người duyệt) · Số vòng: 1 verify / 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 (599 test, exit 0)
G2 Test khớp test-plan, mọi R-xx có test ✅ verify/round-1/oracle.md (22/22 TC)
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
G5 0 finding logic CRITICAL/MAJOR đã xác nhận ✅ verify/round-1/review-logic.md (không cần xác minh — không có CRITICAL/MAJOR)
G6 Không lách cổng, không ghi ngoài phạm vi ✅ verify/round-1/gates.md; 16 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, chưa cấu hình)

Coverage theo luồng

Luồng Tên % dòng % nhánh
F-01 Tồn chi tiết một ĐVT theo kho và lô 100.0% (38/38) N/A (0/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 InventoryController.java:42-53 TC-01, 02, 03 — DEVIATION (có chủ đích, D-02: body 400 theo starter)
R-02 C InventoryQueryService.java:42-46 TC-04..07 — DEVIATION (có chủ đích, D-01)
R-03 C ProductStockDetailJdbcRepository.java:30-47 TC-08, 09, 10 GM-01 PASS (H2; MSSQL thật UNVERIFIED — K-13)
R-04 C ProductStockDetailJdbcRepository.java:39,49-60 TC-11, 12, 13 GM-01 PASS
R-05 C InventoryWebMapper.java:25-29 TC-14 — PASS
R-06 C ProductStockDetailJdbcRepository.java:46 TC-15 GM-01 UNVERIFIED (thứ tự lô trong cùng kho do DB — D-03)
R-07 C ProductStockDetailResponse.java, InventoryWebMapper.java TC-16, 17, 18 — PASS (tên key pid/ppuidAndWarehouseId suy từ Jackson — so response thật ở GM-01)
R-08 C InventoryController.java:51-52 TC-19, 20 — DEVIATION (có chủ đích, D-02, D-07)
R-09 C InventoryQueryService.java:42 TC-21 — UNVERIFIED (DB đọc của code cũ suy từ cấu hình — D-04)
R-10 C — — — DEVIATION (có chủ đích, D-05 — không chuyển kiểm gói)
R-11 C InventoryRelationalRepository.java:51-57 TC-22 — DEVIATION (có chủ đích, D-06: 417 → 500, giữ mã)

3. Người cần xem

# Vị trí Vì sao cần người xem
1 ProductStockDetailJdbcRepository.java:30-47 SQL native chỉ chạy trên H2 (chế độ MSSQL); chạy GM-01 trên MSSQL thật để chốt R-03, R-04, R-06 (K-13)
2 ProductStockDetailJdbcRepository.java (F-logic-1, MINOR) Lệch spec mục 5: tách lớp JDBC riêng thay vì thêm vào InventoryJpaRepositoryCustomImpl (thêm vào lớp cũ làm PMD CyclomaticComplexity đỏ). Không đổi hành vi
3 InventoryQueryService.java Lớp dùng chung cho context khác nay phụ thuộc CurrentCompanyService; đã sửa 1 dòng WarehouseTransferServiceTest.java:135. Lưu ý gộp nhánh: repo chính đang sửa dở chính file này (unit warehouse/get-with-paging)
4 R-07 Tên key JSON pid, ppuidAndWarehouseId suy từ quy tắc đặt tên của Jackson 2.13 — UNVERIFIED tới khi so response thật
5 R-09 (D-04) Code cũ đọc DB chính hay replica chỉ suy từ cấu hình — UNVERIFIED
6 G4 Sonar chưa kiểm

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 Tồn chi tiết một ĐVT theo kho và lô 6 / 5 (đều có chủ đích: D-01, D-02, D-05, D-06, D-07) / 0 / 0 Thêm tầng ProductStockDetailJdbcRepository (F-logic-1) SQL native + thứ tự tham số (comId 2 lần) chưa chạy MSSQL; is_primary đọc Boolean phụ thuộc kiểu BIT; @JsonInclude(ALWAYS) bắt buộc giữ; list rỗng mất key data

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

B-01 Các lô trong cùng một kho trả về theo thứ tự ngẫu nhiên

  • Mức nghi ngờ: THẤP — có thể màn hình tự sắp lại; chỉ thấy ORDER BY không đủ, chưa thấy nơi dùng thứ tự này để quyết định nghiệp vụ.
  • Ở đâu: code cũ easyposbase:src/main/java/sds/ep/baseservice/repositories/impl/BaseInventoryRepositoryImpl.java:82 → code mới (giữ nguyên) src/main/java/com/softdreams/easypos/warehouse/infrastructure/relational/inventory/jpa/ProductStockDetailJdbcRepository.java:46
  • Code cũ đang làm gì: sắp kết quả theo sản phẩm, kho, rồi "ĐVT chính trước". Vì API chỉ hỏi một ĐVT nên chỉ còn sắp theo kho; các lô trong cùng kho không có tiêu chí sắp.
  • Ví dụ cụ thể: kho 6 có lô 301 (HSD 12/2026) và lô 302 (HSD 03/2027) → hệ thống cũ (và mới) có thể trả 301, 302 ở lần gọi này và 302, 301 ở lần gọi khác, tuỳ SQL Server. Nếu muốn ổn định thì lẽ ra phải sắp thêm theo lô hoặc HSD.
  • Vì sao nghi là sai: is_primary desc vô nghĩa khi chỉ có một ĐVT; API khác trong cùng code (createBatchOnHandMap) có sắp lô theo HSD, API này thì không.
  • Ảnh hưởng nếu đúng là bug: danh sách lô trên màn hình nhảy thứ tự giữa các lần mở; người chọn "lô đầu tiên" có thể chọn lô khác nhau.
  • Đã xử lý khi chuyển: GIỮ nguyên hành vi cũ. Test khoá hành vi này: TC-15 (ProductStockDetailJdbcRepositoryTest#orderByAsLegacy) — đổi hành vi thì test này phải đổi theo.
  • Nếu muốn sửa: thêm bd.batch_id (hoặc HSD qua bảng batches) vào ORDER BY ở ProductStockDetailJdbcRepository.java:46, sửa TC-15; monolith còn chạy song song sẽ trả thứ tự khác service mới.
  • Liên quan: D-03, R-06

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-07 (ADR BẮT KHÁC) Giữ BaseResponseDTO + mapper starter ?comId=10&ppuId=999999 → cũ "data":[] / mới không có key data Chốt chung với warehouse/get-with-paging F-logic-1: chấp nhận hay đổi cấu hình JSON cấp service
2 D-01 (LỖI KỸ THUẬT) Thêm kiểm công ty của token comId=20 (user công ty 10) → cũ trả tồn công ty 20 / mới 400 COMPANY_NOT_OF_CURRENT_USER; comId=0 → cũ data=[] / mới 400 INVALID_COMPANY; token không có companyId → cũ trả tồn / mới TOKEN_INVALID_OR_EXPIRED Đồng ý chặn
3 D-02 (ADR BẮT KHÁC) Body response/lỗi theo starter thiếu ppuId → cũ 400 body rỗng / mới 400 INVALID_REQUEST; message[0]/reason theo starter Client không đọc body 400 rỗng
4 D-04 (MƠ HỒ) @Transactional không readOnly → đọc DB chính không khác (nếu suy luận đúng) Xác nhận code cũ đọc DB chính; nếu cũ đọc replica có thể đổi sang readOnly=true
5 D-05 (PHỤ THUỘC NGOÀI) Không chuyển kiểm gói dịch vụ công ty hết gói → cũ 400 ACCOUNT_EXPIRED / mới trả tồn Tầng nào (gateway/service) kiểm gói
6 D-06 (ADR BẮT KHÁC) Lỗi DB → SystemException(EXCEPTION_ERROR) lỗi kết nối → cũ 417 / mới 500, cùng mã EXCEPTION_ERROR Client không phụ thuộc HTTP 417
7 spec-review Spec qua 1 lần review, các R-xx đã sửa theo MAJOR: R-03, R-07, R-08 (F-spec-1, F-spec-2) — Đọc kỹ R-03, R-07, R-08 trong spec.md

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 — mục 3 dòng 2):

F-logic-1

  • Mức độ: MINOR · Loại: architecture · Quy tắc: R-03, R-04, R-06, R-11
  • Code mới: ProductStockDetailJdbcRepository.java:19-86; InventoryRelationalRepository.java:51-57
  • Mô tả: spec mục 5 ghi SQL nằm trong InventoryJpaRepositoryCustomImpl; code tạo lớp @Repository riêng. Không đổi kết quả.
  • Đề xuất: chuyển vào lớp cũ hoặc ghi lại spec mục 5. Không bắt buộc cho G5.

5. Finding bị loại

Finding Lý do loại
(không có)

6. Xử lý của người

Vấn đề Cổng Chỉ thị
(không có vấn đề làm trượt cổng máy; G4 chờ người kiểm Sonar) G4

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

Vấn đề Vòng trước Vòng này
(vòng đầu) — —

8. Thay đổi trong repo đích

16 file (verify/round-1/changed-files.md), đều trong src/main, src/test:

  • Mới (main): presentation/web/inventory/InventoryController, InventoryWebMapper, dto/response/ProductStockDetailResponse; domain/inventory/result/ProductStockDetailResult; infrastructure/relational/inventory/jpa/ProductStockDetailJdbcRepository.
  • Sửa (main): InventoryQueryService, InventoryRepository, InventoryErrorCode, InventoryRelationalRepository, i18n/messages_vi|en.properties.
  • Test mới: InventoryControllerTest, InventoryQueryServiceTest, ProductStockDetailJdbcRepositoryTest, InventoryRelationalRepositoryTest.
  • Test sửa ngoài unit (cần thiết): WarehouseTransferServiceTest — 1 dòng dựng InventoryQueryService.

9. Đề xuất bổ sung kinh nghiệm (/mig-learn gom vào proposal để người duyệt)

Đề xuất Đưa vào đâu
Response record có field null/rỗng phải giữ key như monolith → @JsonInclude(ALWAYS) vì mapper starter NON_EMPTY (DataConverterAutoConfiguration.java:51); test serialize bằng buildObjectMapper() lessons.md 1b + legacy-facts/target-cheatsheet
Thêm method vào InventoryJpaRepositoryCustomImpl làm PMD CyclomaticComplexity (tổng lớp > 50) đỏ — truy vấn mới đặt ở lớp JDBC riêng; ghi vào spec mục 5 ngay từ đầu target-cheatsheet.md mục 4
Truy vấn native có thể test thật trên H2 MODE=MSSQLServer (bảng tối thiểu) thay vì chỉ mock — vẫn UNVERIFIED trên MSSQL target-cheatsheet.md mục 5

Nguồn của trang này

  • Báo cáo sai lệch migrations/inventory/get-detail-product/report.md vòng 1 · sha256 29da12faefd2

v1 dựng 2026-11-06 00:42 · base commit đích a06ccfa6d4