Bỏ qua, đến nội dung

Câu hỏi thường gặp — Record History

Sử dụng

Có thể xem ai đã tạo bản ghi không?

Có. Plugin ghi lại cả action create (không chỉ update). Khi bản ghi được tạo, một entry lịch sử được tạo với action: 'create', userId, và snapshot giá trị ban đầu.

Có thể phục hồi giá trị cũ không?

Hiện tại plugin chỉ hiển thị lịch sử. Không có chức năng restore tự động. Bạn có thể xem giá trị before trong recordFieldHistories và cập nhật thủ công nếu cần.

Lịch sử có ghi lại thao tác xóa không?

Có. Khi bản ghi bị xóa (destroy), plugin ghi lại entry với action: 'destroy'. Tuy nhiên, snapshot giá trị sẽ là null (vì bản ghi đã bị xóa).

Bulk update có được tracking không?

Có. Plugin hook vào afterBulkCreate, afterBulkUpdate, afterBulkDestroy. Mỗi bản ghi trong batch tạo entry lịch sử riêng.

Cấu hình

Tại sao không thấy lịch sử cho Collection?

Kiểm tra:

  1. Collection đã được bật tracking trong cấu hình recordHistoryCollections
  2. Ít nhất một field đã được chọn trong recordHistoryFields
  3. Lịch sử chỉ ghi từ khi bật — không retroactive cho dữ liệu cũ

Có nên bật tracking cho tất cả Collection không?

Không khuyến nghị. Lý do:

  • Bảng history lớn nhanh (mỗi thay đổi = 1+ bản ghi)
  • Tăng overhead cho mỗi thao tác ghi
  • Khó quản lý khi dữ liệu lớn

Chỉ nên bật cho Collection quan trọng (đơn hàng, hợp đồng, tài khoản...) và field quan trọng.

Plugin có hỗ trợ multi data source không?

Có. Plugin hook vào app.dataSourceManager.afterAddDataSource() — mọi data source được thêm vào đều có thể tracking. Cấu hình recordHistoryCollections lưu cả dataSourceKey để phân biệt.

Kỹ thuật

Tại sao plugin dùng Database connection riêng?

Plugin tạo historyDB riêng biệt để:

  1. Tách transaction — ghi history không nằm trong transaction của data chính, tránh deadlock
  2. Tách migration — history tables có migration rules riêng (schema-only, overwrite)
  3. Isolation — lỗi ghi history không ảnh hưởng thao tác chính

Event Queue dùng để làm gì?

Plugin sử dụng Event Queue để xử lý bất đồng bộ:

  • Hook chỉ publish message vào queue → response trả về ngay
  • Queue consumer xử lý tạo snapshot và diff ở background
  • Đảm bảo response time không bị ảnh hưởng bởi logic history

Snapshot + Diff hoạt động thế nào?

  1. recordFieldSnapshots lưu giá trị mới nhất của mỗi field (1 record per field per bản ghi)
  2. Khi snapshot được cập nhật, afterSave hook so sánh model.get('value') với model.previous('value')
  3. Nếu khác nhau → tạo entry trong recordFieldHistories (before + after)
  4. Đồng thời tạo entry tổng trong recordHistories (action, userId, timestamp)

Plugin có ảnh hưởng hiệu năng không?

  • Response time: Không đáng kể — plugin chờ transaction commit rồi publish vào queue, không block response
  • Database: Có tăng — mỗi thay đổi tạo snapshot + diff + history entries
  • Memory: historyDB sử dụng connection pool riêng

Khuyến nghị monitor kích thước bảng history và thiết lập cleanup định kỳ cho production.

UUID và requestId dùng để làm gì?

FieldMô tả
uuidID duy nhất cho mỗi lần thay đổi — liên kết recordHistories với recordFieldHistories
requestIdID request HTTP — nhóm các thay đổi từ cùng một request

Nhờ requestId, bạn có thể xem tất cả field thay đổi trong cùng một lần submit form.