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

batch · batch/get-with-paging · api

POST/api/client/page/batches/get-with-paging

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

Phân tích luồng sau chuyển — batch/get-with-paging — vòng 1

logic-reviewer viết dựa trên code đã implement (worktree C:/Projects/warehouse-service-wt/ws2), đối chiếu với code cũ easyposbackend1 (backend: = src/main/java/vn/softdreams/easypos/). Đường dẫn mới viết tắt từ src/main/java/com/softdreams/easypos/warehouse/.

F-01 Danh sách lô theo trang

  • Điểm vào: cũ easyposbackend1:src/main/java/vn/softdreams/easypos/web/rest/BatchesManagementResource.java:33-38 → mới presentation/web/batch/BatchController.java:49-56
  • Quy tắc: R-01 … R-13

Sơ đồ luồng mới (theo code thực tế)

sequenceDiagram
    participant C as Client
    participant BC as BatchController.getWithPaging
    participant M as BatchWebMapper
    participant QS as BatchPageQueryService.getBatchPage (@Transactional, không readOnly)
    participant CU as CurrentUserPort.findCompanyId
    participant RR as BatchRelationalRepository.findPage
    participant PR as BatchPageReader.read
    C->>BC: POST body BatchPageRequest
    BC->>BC: Guard.validateInput (comId @NotNull → 400 COMPANY_ID_NOT_NULL)
    BC->>M: toPageQuery
    BC->>QS: getBatchPage(BatchPageQuery)
    QS->>CU: findCompanyId → rỗng: 400 TOKEN_EXPIRED; khác comId: 500 COMPANY_NOT_EXISTS_CODE
    QS->>QS: validatePage: paged && (page<0 || size<1) → 500 EXCEPTION_ERROR
    QS->>RR: findPage
    RR->>PR: read
    PR->>PR: BatchKeyword.likePattern; pageWhere (FROM/WHERE/[keyword]/[status]/GROUP BY/[HAVING])
    PR->>PR: COUNT(DISTINCT results.id) (bind comId [+keyword])
    PR->>PR: findRows: SELECT [+ppu] … ORDER BY [ppu]…; paged: (int)(page*size) <0 → 500 EXCEPTION_ERROR, setFirstResult/setMaxResults
    PR->>PR: toItem từng dòng; pageTotal theo quy tắc PageImpl
    PR-->>BC: BatchPage(items, total)
    BC-->>C: 200 BaseResponseDTO.count(total).ok(items, SUCCESS_GET_LIST)

Đối chiếu từng bước

# Luồng cũ (repo:path:dòng) Luồng mới (path:dòng) Kết luận
1 Đọc body SearchBatchRequest, mặc định status=3, inventoryQuantityStatus=0 (backend:dto/batches/SearchBatchRequest.java:8-19) BatchPageRequest record, không mặc định (presentation/web/batch/dto/request/BatchPageRequest.java:21-29) KHỚP (null cũng = không lọc như 3/0, R-01)
2 Body hỏng → 400 body rỗng (LF-03) Starter → 400 INVALID_REQUEST KHÁC có chủ đích (D-02)
3 baseCommon.validateInput (BatchesManagementResource.java:35) Guard.validateInput (BatchController.java:51) KHỚP (mã COMPANY_ID_NOT_NULL; body lỗi theo starter — D-02)
4 getUserWithAuthorities(comId): JWT không có companyId → 400 TOKEN_EXPIRED; khác → 500 COMPANY_NOT_EXISTS_CODE (backend:service/UserService.java:1844-1851) requireCompany (application/batch/BatchPageQueryService.java:46-52) KHỚP
5 Nạp user, kiểm active/lần đăng nhập đầu/password version (UserService.java:1853-1900) — CHỈ CÓ Ở CŨ — D-01
6 Kiểm gói dịch vụ qua interceptor (LF-21) — CHỈ CÓ Ở CŨ — D-11
7 request.getPageable() → PageRequest.of ném IAE → 417 EXCEPTION_ERROR (backend:dto/CommonPageable.java:11-16; BatchesManagementServiceImpl.java:152) validatePage (BatchPageQueryService.java:55-59), sau kiểm công ty, trước SQL KHÁC có chủ đích (D-03: 417→500, giữ mã)
8 Keyword !isNullOrEmpty → LIKE '%'+normalizedName+'%' (BatchRepositoryImpl.java:43-46; Common.java:1131-1139,1315-1329) BatchKeyword.likePattern/normalize (domain/batch/model/BatchKeyword.java:29-46) KHỚP (khác locale toLowerCase — F-logic-2)
9 Điều kiện status 0/2/1 nguyên văn (BatchRepositoryImpl.java:48-107) statusCondition + WARNING_DATE_SQL (BatchPageReader.java:43-67,188-199) KHỚP (SQL so từng dòng; tràn DATEADD âm là nghi-bug-cu F-logic-4)
10 GROUP BY + HAVING theo inventoryQuantityStatus (BatchRepositoryImpl.java:108-117) GROUP_BY_SQL, stockCondition (BatchPageReader.java:68-75,201-209) KHỚP
11 COUNT trước, bind comId [+keyword] (BatchRepositoryImpl.java:118-123) read (BatchPageReader.java:129-131) KHỚP
12 ORDER BY có/không ppuId, bind ppuId (BatchRepositoryImpl.java:125-143) ORDER_SQL/ORDER_PPU_SQL, findRows (BatchPageReader.java:78-86,142-155) KHỚP
13 SELECT 10/11 cột, mapping BatchItem/BatchItemWithPpuOnHand (BatchRepositoryImpl.java:145-179; backend:domain/Batches.java:19-59) SELECT_SQL/SELECT_PPU_SQL, toItem (BatchPageReader.java:87-99,230-257) KHỚP (số Number.intValue() cắt phần lẻ — D-04; ngày toZonedDateTime — D-12)
14 Phân trang setFirstResult((int) offset) (âm → IAE → 417), setMaxResults (Common.java:267-281) applyPage tự kiểm (int) âm → SystemException(EXCEPTION_ERROR) (BatchPageReader.java:158-165) KHỚP thứ tự (sau COUNT, trước SELECT); HTTP 500 theo D-03
15 Có pageable: PageImpl(content, pageable, count); không: PageImpl(content); (int) getTotalElements() (BatchRepositoryImpl.java:181-189; BatchesManagementServiceImpl.java:154-160) pageTotal (BatchPageReader.java:219-228) KHỚP (offset tính long, ép int cuối như cũ)
16 Lỗi SQL/map không bắt → 417 EXCEPTION_ERROR (LF-13) catch (PersistenceException | ClassCastException) → SystemException.builder().errorCode(EXCEPTION_ERROR).error(e) (BatchPageReader.java:136-139) KHÁC có chủ đích (D-03)
17 200 BaseResultDTO(SUCCESS, SUCCESS_GET_LIST, true, content, count), data=[] khi rỗng (LF-10) BaseResponseDTO.count(total).ok(items, SUCCESS_GET_LIST) (BatchController.java:53-55); item @JsonInclude(ALWAYS) KHÁC có chủ đích (D-02: mất key data khi rỗng)

Dữ liệu và side effect

Bảng / topic / cache Cũ (đọc/ghi, điều kiện) Mới (đọc/ghi, điều kiện) Ghi chú
batches b đọc, b.com_id = :comId [+ keyword, status] đọc, cùng điều kiện KHỚP
batches_detail bd LEFT JOIN bd.batch_id = b.id, không lọc com_id như cũ KHỚP
product_product_unit ppu LEFT JOIN bd.ppu_id = ppu.id AND ppu.is_primary = 1 như cũ KHỚP
Cache/bảng user, JWT đọc (getUserWithAuthorities) chỉ đọc claim companyId của principal D-01
Redis gói dịch vụ đọc (LF-21) không D-11

Không ghi bảng, không phát event, không ghi cache ở cả hai bên.

Transaction, khoá, idempotency, tenant

  • Ranh giới transaction: cũ @Transactional cấp class service đọc-ghi (BatchesManagementServiceImpl.java:55-57) → mới @Transactional (không readOnly) trên BatchPageQueryService.getBatchPage (BatchPageQueryService.java:38-43). Hai câu SQL chạy trong cùng một transaction, đọc DB chính (D-10). Lỗi trong transaction chỉ dẫn tới rollback rỗng.
  • Khoá / cập nhật nguyên tử: không có ở cả hai bên (chỉ đọc).
  • Idempotency, thời điểm phát event: không áp dụng.
  • Lọc comId: b.com_id = :comId có ở cả COUNT và SELECT. comId đã được kiểm bằng claim của token trước khi chạy SQL. bd/ppu không lọc com_id, giống code cũ.

Lệch so với luồng mới đã duyệt (spec mục 6)

Application service là class mới BatchPageQueryService, không phải BatchQueryService như sơ đồ mục 6 và bảng mục 5 (F-logic-1). Thứ tự các bước giống sơ đồ.

Dev cần chú ý khi review

Vị trí Vì sao
infrastructure/relational/batch/adapter/BatchPageReader.java:35-99 (các hằng SQL) SQL phải giống hệt code cũ nhưng chỉ test bằng mock (K-13). Đọc kỹ chỗ ghép text block (TOTAL_ON_HAND_SQL có dấu """ cùng dòng, ORDER_TAIL_SQL, SELECT_PPU_SQL nối ", SUM…") và chạy thử trên MSSQL.
BatchPageReader.java:125-140 (read) Ranh giới try/catch: chỉ PersistenceException/ClassCastException thành EXCEPTION_ERROR; SystemException từ applyPage đi thẳng ra. Lỗi khác (vd IllegalArgumentException của Hibernate) sẽ ra UNCERTAIN_ERROR.
BatchPageReader.java:158-165,219-228 Phép (int) offset và tính count theo PageImpl (K-09): offset tràn dương lấy từ vị trí bị cắt, count tính bằng long rồi ép.
BatchPageReader.java:230-257 + BatchRelationalRepository.java:93-107 Kiểu Java Hibernate 6 trả cho mfg_date/exp_date/status/SUM chưa kiểm trên MSSQL. Nếu cột là SQL date thì java.sql.Date không thuộc nhánh nào của toZonedDateTime → ClassCastException → 500, trong khi cũ đọc được. Spec giả định cột là datetime.
application/batch/BatchPageQueryService.java:46-59 Thứ tự kiểm token → công ty → trang phải giữ đúng (R-02 trước R-03).
domain/batch/model/BatchKeyword.java:29-46 likePattern trả %% với từ khoá toàn dấu cách (D-08); Locale.ROOT (F-logic-2).

Nguồn của trang này

  • Phân tích luồng migrations/batch/get-with-paging/verify/round-1/flow-analysis.md vòng 1 · sha256 97085466a7ba

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