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

Kho · warehouse/export-excel-error-data · api

POST/api/client/page/warehouse/export-excel/error-data

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

Phân tích luồng sau chuyển — warehouse/export-excel-error-data — vòng 1

F-01 Xuất file dòng lỗi import kho

  • Điểm vào: cũ easyposbackend1:src/main/java/vn/softdreams/easypos/web/rest/WarehouseResource.java:108-116 → mới src/main/java/com/softdreams/easypos/warehouse/presentation/web/warehouse/WarehouseController.java:251-260
  • Quy tắc: R-01 … R-09

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

sequenceDiagram
    participant C as Client
    participant WC as WarehouseController.exportImportErrors
    participant M as WarehouseWebMapperImpl.toImportErrorRows
    participant ES as WarehouseImportErrorExportService.exportErrors
    participant TW as PoiExcelTableWriter.write
    C->>WC: POST /api/client/page/warehouse/export-excel/error-data [WarehouseImportErrorRowRequest…] (@RequestBody bắt buộc, không validate)
    WC->>M: toImportErrorRows(request) (null-safe, phần tử null → null, bỏ id/comId/statusImport)
    WC->>ES: exportErrors(rows)
    ES->>ES: rows null/rỗng → throw SystemException("sds.ep.warehouse")
    ES->>ES: có phần tử null → return byte[0]
    ES->>ES: toTableRow: [i+1, errorMessage, sku, name, phone, address, status?"Đang hoạt động":"Ngừng hoạt động", sellable?"Có":"Không", description]
    ES->>TW: write(ExcelTable("Danh sách bản ghi lỗi", 9 headers, widths {1:7680, 2..8:5120}, centered {0}, rows))
    TW->>TW: new SXSSFWorkbook → createSheet → 3 style → setColumnWidth → dòng 0 tiêu đề → dòng 1.. dữ liệu → workbook.write(output)
    TW->>TW: finally dispose(); try-with-resources close(); IOException|RuntimeException → LOG.error, nuốt
    TW-->>ES: output.toByteArray()
    WC-->>C: 200, application/octet-stream, Content-Disposition: form-data; name="attachment"; filename="filename.extension"

Đố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 kiểm gói dịch vụ (LF-21) — KHÁC có chủ đích (D-02)
2 @RequestBody List<WarehouseSaveRequest> bắt buộc, không validateInput — backend:web/rest/WarehouseResource.java:109 WarehouseController.java:254, record WarehouseImportErrorRowRequest (key sku, sellable khớp getter cũ — LF-05; base:dto/warehouse/WarehouseSaveRequest.java:51-89) KHỚP
3 Body hỏng/thiếu → 400 body rỗng (LF-03) 400 INVALID_REQUEST (handler starter) KHÁC có chủ đích (D-01)
4 Getter getStatus() trả false khi null (base:…/WarehouseSaveRequest.java:75-77) Giữ null rồi Boolean.TRUE.equals (WarehouseImportErrorExportService.java:89) KHỚP (kết quả như nhau)
5 Mở transaction cấp class (LF-33), không có truy vấn Không @Transactional KHỚP với R-08 (không có lệnh DB)
6 null/rỗng → BaseInternalServerException(DATA_NOT_FOUND, ENTITY_NAME) → 500 mã sds.ep.warehouse — SVC:1204-1206 SystemException(DATA_NOT_FOUND_LEGACY) — WarehouseImportErrorExportService.java:64-66 KHỚP mã và status (D-03); text theo starter (D-01, F-logic-2)
7 Phần tử null → NPE ở SVC:1295 trước write → nuốt → 0 byte Kiểm trước, trả new byte[0] — WarehouseImportErrorExportService.java:68-70 KHỚP (D-04)
8 4 style (SVC:1211-1214, createCellStyle SVC:1590-1616) 3 style — PoiExcelTableWriter.fill, createCellStyle KHÁC (F-logic-1), không đổi nội dung ô
9 Độ rộng cột 1 = 30*256, cột 2..8 = 20*256 — SVC:1216-1222 COLUMN_WIDTHS Map, đặt theo từng mục — WarehouseImportErrorExportService.java:39-42 KHỚP (thứ tự đặt không ảnh hưởng)
10 Dòng 0 tiêu đề 9 cột, cột bắt đầu từ 0 (rowIndex == 0) — SVC:1223-1235, SVC:1624-1635 fill dòng HEADER_ROW KHỚP
11 Dòng i+1: STT ô số canh giữa, còn lại canh trái; null → setBlank có style; kiểu lạ → IAE — SVC:1288-1305, SVC:1565-1588 toTableRow + setValue KHỚP
12 workbook.write(bos); catch (Exception) printStackTrace; finally close() (lỗi close cũng nuốt) — SVC:1238-1250 write + catch (IOException | RuntimeException) → LOG.error; trả phần byte đã ghi KHỚP (code chỉ ném được hai loại checked/unchecked này)
13 Không dispose() → file tạm còn lại finally workbook.dispose() KHÁC có chủ đích (D-06)
14 200, octet-stream, setContentDispositionFormData("attachment","filename.extension") — backend:…/WarehouseResource.java:111-115 WarehouseController.java:256-259 KHỚP (D-07 GIỮ, D-08 GIỮ)

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ú
Body JSON Đọc, không validate Đọc, không validate id, comId, statusImport nhận nhưng bỏ
File tạm SXSSF Ghi, không xoá Ghi, xoá bằng dispose() cả khi thành công lẫn khi lỗi D-06
Redis gói dịch vụ Đọc (interceptor) Không D-02
DB Không (chỉ mở transaction) Không —

Transaction, khoá, idempotency, tenant

  • Ranh giới transaction: cũ có transaction cấp class nhưng không truy vấn → mới không có.
  • Khoá / cập nhật nguyên tử: không áp dụng.
  • Idempotency, thời điểm phát event: không có event.
  • Lọc comId: cả cũ và mới đều không dùng (R-08); không có dữ liệu tenant nào bị truy cập.

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

Không. Code đi đúng Controller → Mapper → WarehouseImportErrorExportService → ExcelTableWriter/PoiExcelTableWriter, như spec mục 5–6.

Dev cần chú ý khi review

Vị trí Vì sao
src/main/java/com/softdreams/easypos/warehouse/infrastructure/excel/PoiExcelTableWriter.java write (try-with-resources lồng try/finally) Nhánh lỗi nuốt exception và trả byte đã ghi (D-04). Thứ tự là dispose() trước, close() sau. Lỗi khởi tạo SXSSFWorkbook cũng nằm trong catch.
src/main/java/com/softdreams/easypos/warehouse/application/warehouse/WarehouseImportErrorExportService.java:64-70 Hai nhánh lỗi giữ như cũ: rỗng → 500 mã sds.ep.warehouse (D-03); phần tử null → 0 byte thay cho NPE bị nuốt.
src/main/java/com/softdreams/easypos/warehouse/domain/warehouse/exception/WarehouseErrorCode.java:31 Mã lỗi không có entry i18n (F-logic-2). Cần chạy thử body [] để xem body 500 của starter.
PoiExcelTableWriter.fill, createCellStyle Có 3 style thay vì 4 (F-logic-1). Font không đậm dùng setBold(false) thay vì không gọi, kết quả XML vẫn như nhau.
src/main/java/com/softdreams/easypos/warehouse/presentation/web/warehouse/WarehouseController.java:254 Key lạ (ví dụ "SKU") chỉ bị bỏ qua nếu ObjectMapper khi chạy thật tắt FAIL_ON_UNKNOWN_PROPERTIES. Test controller dùng ObjectMapper riêng đã tắt sẵn, nên chưa kiểm được điều này với cấu hình thật của starter (UNVERIFIED).

Nguồn của trang này

  • Phân tích luồng migrations/warehouse/export-excel-error-data/verify/round-1/flow-analysis.md vòng 1 · sha256 584fd99bd3d2

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