Task 2-1: Structured Audit Trail cho TriggerBatchController
Phase: 2 - Observability Priority: Medium Depends on: task-1-3 Reference: SPEC.md — xem mục 4 (ADM-F-04 Manual batch trigger) và mục 2.10 (
TriggerBatchControllertrong System Config & Maintenance)
Background
TriggerBatchController cho phép admin trigger batch jobs thủ công. Hiện tại không có audit trail: ai trigger, lúc nào, kết quả ra sao.
Tasks
File: admin/controller/trigger_batch/TriggerBatchController.java
-
[ ] Thêm audit log cho mỗi trigger:
@PostMapping("/trigger/{jobName}") public Result<?> triggerBatch(@PathVariable String jobName) { String adminId = getCurrentAdminId(); LOGGER.info("[BATCH_TRIGGER] admin={} job={} time={}", adminId, jobName, Instant.now()); try { batchJobService.trigger(jobName); LOGGER.info("[BATCH_TRIGGER] SUCCESS admin={} job={}", adminId, jobName); return Result.OK(); } catch (Exception e) { LOGGER.error("[BATCH_TRIGGER] FAILED admin={} job={}", adminId, jobName, e); throw e; } }Injection note —
batchJobService: Kiểm tra xemTriggerBatchControllerđã injectbatchJobServicechưa. Nếu chưa, cần thêm:Xác nhận tên service/class chính xác bằng cách tìm kiếm trong@Autowired private BatchJobService batchJobService; // hoặc tên service thực tế trong projectadmin/srchoặccommon/src— có thể làTriggerBatchService,JobService, hoặc tương tự.Injection note —
getCurrentAdminId(): NếuTriggerBatchControllerkhông extend base controller có sẵn method này, thêm helper method:Import cần thiết:private String getCurrentAdminId() { return ((AdminUserDetails) SecurityContextHolder.getContext() .getAuthentication().getPrincipal()).getAdminId(); }org.springframework.security.core.context.SecurityContextHoldervàAdminUserDetails(kiểm tra package trong project).Import
Instant:import java.time.Instant; -
[ ] Store audit record trong DB:
CREATE TABLE admin_batch_trigger_log ( id VARCHAR(36) PRIMARY KEY, admin_id VARCHAR(36), job_name VARCHAR(100), triggered_at DATETIME, status VARCHAR(20), -- SUCCESS, FAILED error_message TEXT );Note về migration: Tạo file migration mới trong thư mục migration của project (thường là
resources/db/migration/với Flyway hoặc Liquibase). Đặt tên theo convention hiện tại (ví dụ:V{next_version}__add_admin_batch_trigger_log.sql). Sau khi tạo table, cần tạo thêm entityAdminBatchTriggerLog, repositoryAdminBatchTriggerLogRepository, và inject vào controller để persist record.
Verification / Acceptance Criteria
- [ ] Code compiles:
TriggerBatchController.javabuild thành công;batchJobService,getCurrentAdminId(), vàInstantđều resolve đúng - [ ] Log xuất hiện: Gọi
POST /api/admin/trigger-batch/trigger/{jobName}→ server logs có dòng[BATCH_TRIGGER]với adminId và jobName đúng - [ ] Log SUCCESS: Job chạy xong không lỗi → log có
[BATCH_TRIGGER] SUCCESS - [ ] Log FAILED: Job throw exception → log có
[BATCH_TRIGGER] FAILEDkèm stack trace; exception được re-throw để caller nhận error response - [ ] DB record: Sau mỗi trigger, bảng
admin_batch_trigger_logcó record mới vớiadmin_id,job_name,triggered_at,statusđúng - [ ] Test class tham khảo:
TriggerBatchControllerTest— kiểm tra cả success và failure path, verify log message và DB record
Files to Modify
admin/controller/trigger_batch/TriggerBatchController.java- Migration file (new table)