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

batch · batch/batches · api

GET/api/client/page/inventory-checking/batches

Vòng
2
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/batches — vòng 2

logic-reviewer viết dựa trên code đã implement, đối chiếu với code cũ. Chế độ thu hẹp. F-01 có file trong fix.diff (CurrentUserAdapter, JwtAuthorityClaimReader) nên viết lại. Các bước không có file trong fix.diff dùng lại kết luận vòng 1.

F-01 Lô có tồn của ĐVT trong kho cho kiểm kê

  • Điểm vào: cũ easyposbackend1:src/main/java/vn/softdreams/easypos/web/rest/InventoryCheckingManagementResource.java:81-92 → mới src/main/java/com/softdreams/easypos/warehouse/presentation/web/batch/InventoryCheckingBatchController.java:47-66
  • Quy tắc: R-01, R-02, R-03, R-04, R-05, R-06, R-07

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

sequenceDiagram
    participant C as Client
    participant F as BaseAuthenticationFilter / DefaultAuthenticationExtractor (starter, jwt_verify)
    participant IC as InventoryCheckingBatchController.batches
    participant S as InventoryCheckBatchService.getBatches
    participant U as CurrentUserAdapter.findAuthorityClaim → JwtAuthorityClaimReader.read
    participant Q as BatchQueryService.findInventoryCheckBatches (@Transactional readOnly)
    participant W as WarehouseQueryService.existsActive → WarehouseRelationalRepository.existsActive
    participant R as BatchRelationalRepository → InventoryCheckBatchReader.read
    C->>F: GET ?comId&warehouseId&ppuId[&keyword], header Authorization: Bearer <jwt>
    F->>F: kiểm chữ ký token (không hợp lệ/thiếu → 401 của starter, chưa vào controller)
    F->>IC: bind @RequestParam comId, warehouseId (thiếu → 400); record InventoryCheckingBatchFilter
    IC->>IC: ppuId null → MissingServletRequestParameterException → 400
    IC->>S: getBatches(InventoryCheckBatchQuery)
    S->>U: findAuthorityClaim()
    U->>U: RequestContextHolder → header Authorization → bỏ "Bearer " + trim → split(".") → Base64URL decode [1] → JSON "auth"
    U-->>S: rỗng (không request/header/claim, token hỏng) → SystemException EXCEPTION_ERROR (500)
    S->>S: BatchPermission.canAccessInventoryCheck (Set.of(split(","))) — IAE → 500; không 3401/3403 → AuthenticationException 401 UNAUTHORIZED_BY_CHECK
    S->>Q: findInventoryCheckBatches
    Q->>W: SELECT 1 FROM warehouse WHERE com_id=:comId AND id=:id AND status=1 (maxResults 1)
    W-->>Q: false → BadRequestException INVENTORY_CHECK_WAREHOUSE_INVALID (400)
    Q->>R: native SQL nguyên văn findBatchStocksByWarehouseAndPpu, ORDER BY b.id DESC
    R-->>Q: List<InventoryCheckBatchItem> (ngày Instant)
    Q-->>IC: danh sách
    IC->>IC: BatchWebMapper.toInventoryCheckingBatchResponses (ngày → chuỗi UTC yyyy-MM-dd'T'HH:mm:ss.SSSxxx)
    IC-->>C: 200 BaseResponseDTO.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 Interceptor gói dịch vụ HandleInterceptorCustom.preHandle (LF-21) — KHÁC có chủ đích (D-08) — như vòng 1
2 Bind 4 @RequestParam, thiếu/sai kiểu → 400 body rỗng (InventoryCheckingManagementResource.java:85-90, LF-03) InventoryCheckingBatchController.java:50-58 KHÁC có chủ đích (D-02, D-09) — như vòng 1
3 CheckAuthorizeAspect.java:38-39 → UserService.java:1979-1995 giải payload của credentials (token từ JWTFilter.java:42-50, TokenProvider.java:129) → BaseJwtDTO.auth InventoryCheckBatchService.java:37-38 → CurrentUserAdapter.java:31-33 → JwtAuthorityClaimReader.java:39-63 giải payload token header Authorization (cùng token starter đã kiểm chữ ký) KHỚP (thiếu claim/payload hỏng: 417 → 500, D-03); F-logic-1 vòng 1 đã sửa
4 Set.of(authStr.split(",")), anyMatch 3401/3403 (CheckAuthorizeAspect.java:40-41) BatchPermission.java:25-28; IAE bọc SystemException (InventoryCheckBatchService.java:39-44) KHỚP (D-04; D-03 cho 417→500)
5 Không quyền → BaseAuthenticateException 401 UNAUTHORIZED_BY_CHECK (CheckAuthorizeAspect.java:43-45) InventoryCheckBatchService.java:45-46 KHỚP (text: D-10) — nay tới được
6 @Transactional(readOnly) + @ReadQuery (ICS:173-176) BatchQueryService.java:56 KHỚP (D-07, UNVERIFIED) — như vòng 1
7 warehouseExists (ICS:178-180; BaseInventoryCheckingQueryRepositoryImpl.java:38-41) → 400 BatchQueryService.java:58-60; WarehouseRelationalRepository.java:32-56 KHỚP — như vòng 1
8 normalize/appendLike (BaseInventoryCheckingQueryRepositoryImpl.java:142-151,176-178) InventoryCheckBatchReader.java:58-64 KHỚP — như vòng 1
9 SQL native BaseBatchesRepository.java:29-60 InventoryCheckBatchReader.java:23-35 KHỚP — như vòng 1
10 Projection ngày Object → Jackson StdDateFormat UTC InventoryCheckBatchReader.java:77-96 + BatchWebMapper KHỚP (D-06, UNVERIFIED) — như vòng 1
11 BaseResultDTO(SUCCESS, SUCCESS_GET_LIST, true, list) (ICS:181-185) InventoryCheckingBatchController.java:61-65 KHÁC có chủ đích (D-02) — như vòng 1
12 Lỗi SQL → 417 EXCEPTION_ERROR (LF-13) → 500 EXCEPTION_ERROR KHÁC có chủ đích (D-03) — như vòng 1

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ú
warehouse đọc, com_id, id, status = true đọc, com_id, id, status = 1, setMaxResults(1) tương đương
batches ⋈ batches_detail ⋈ inventory đọc, SQL R-04 đọc, SQL nguyên văn không lọc i.com_id ở cả hai
JWT claim auth đọc từ payload token (credentials) đọc từ payload token header Authorization khớp
Redis gói dịch vụ đọc (interceptor) không D-08

Transaction, khoá, idempotency, tenant

  • Ranh giới transaction: kiểm quyền ngoài transaction (cũ AOP ở controller; mới InventoryCheckBatchService), đọc trong BatchQueryService.findInventoryCheckBatches readOnly. Kết quả: khớp.
  • Khoá / cập nhật nguyên tử: không có (chỉ đọc).
  • Idempotency, thời điểm phát event: không có event.
  • Lọc comId: theo tham số ở mọi truy vấn như cũ; không đối chiếu công ty token (D-01, GIỮ).

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

Không. Cấu trúc đúng sơ đồ mục 6. Riêng cách đọc claim khác mô tả spec mục 5 (đọc header thay vì BaseUserDTO.getClaim), không đổi luồng.

Dev cần chú ý khi review

Vị trí Vì sao
infrastructure/security/JwtAuthorityClaimReader.java:47-63 Tự giải payload JWT, không kiểm chữ ký. Chỉ an toàn vì starter jwt_verify đã kiểm chữ ký chính header này và /api/client/page/** không public. Nếu đổi authentication-type sang header_forwarded hoặc thêm path public thì reader trả rỗng (500) hoặc tin token chưa kiểm
infrastructure/security/JwtAuthorityClaimReader.java:39-45 Phụ thuộc RequestContextHolder: gọi ngoài thread request (async, Kafka) → rỗng → 500
application/batch/InventoryCheckBatchService.java:36-48 Thứ tự lỗi: thiếu claim → 500, trùng mã → 500, không quyền → 401, đều trước mọi truy cập DB
infrastructure/relational/batch/adapter/InventoryCheckBatchReader.java:77-96 Đổi ngày sang Instant phụ thuộc kiểu driver trả (D-06, UNVERIFIED) — như vòng 1

Nguồn của trang này

  • Phân tích luồng migrations/batch/batches/verify/round-2/flow-analysis.md vòng 2 · sha256 9ecbcd2b8f6a

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