Giao diện
Tham chiếu kỹ thuật
SequenceField — Kiểu field trong hệ thống
| Thuộc tính | Mô tả |
|---|---|
| Field type | sequence |
| DB column | VARCHAR / STRING |
| Patterns | Mảng pattern objects |
| Read-only | Giá trị sinh tự động, không cho nhập thủ công |
Patterns System
Mỗi field sequence chứa mảng patterns, mỗi phần tử có type và options:
typescript
interface SequencePattern {
type: 'string' | 'integer';
options: StringPatternOptions | IntegerPatternOptions;
}
interface StringPatternOptions {
value: string;
}
interface IntegerPatternOptions {
digits: number;
start: number;
cycle?: string;
}Khi sinh mã, hệ thống duyệt qua từng pattern → sinh giá trị → nối lại thành chuỗi kết quả.
Database — Bảng sequences
Bảng sequences lưu trạng thái counter cho từng field:
| Cột | Kiểu | Mô tả |
|---|---|---|
id | BIGINT | Primary key |
collection | STRING | Tên collection chứa field |
field | STRING | Tên field sequence |
key | INTEGER | Giá trị counter hiện tại |
lastGeneratedAt | DATE | Thời điểm sinh mã gần nhất (dùng cho cycle check) |
Cách kiểm tra cycle reset
Trước khi sinh mã:
→ Đọc lastGeneratedAt từ bảng sequences
→ So sánh với cron expression
→ Nếu đã qua chu kỳ reset → đặt key = start
→ Nếu chưa → key = key + 1
→ Cập nhật key và lastGeneratedAtConcurrency Safety — Bảng sequences
Plugin sử dụng bảng sequences thay vì tính MAX() từ dữ liệu bản ghi:
Không an toàn (race condition):
Thread A: SELECT MAX(code) → 42
Thread B: SELECT MAX(code) → 42
Thread A: INSERT code = 43
Thread B: INSERT code = 43 ← TRÙNG!
An toàn (sequences table + lock):
Thread A: LOCK → read key=42 → key=43 → UNLOCK
Thread B: LOCK → read key=43 → key=44 → UNLOCKCounter tăng atomic trong một transaction, đảm bảo không trùng mã ngay cả với hàng trăm request đồng thời.
Server Hooks
beforeSave — Sinh mã khi tạo bản ghi
Bản ghi mới chuẩn bị INSERT
→ beforeSave hook trigger
→ Kiểm tra field sequence chưa có giá trị
→ LOCK bảng sequences cho (collection, field)
→ Đọc counter hiện tại
→ Kiểm tra cycle reset (nếu có)
→ Tăng counter + sinh mã theo patterns
→ Cập nhật bảng sequences
→ UNLOCK
→ Gán giá trị vào recordafterDestroy — Dọn dẹp khi xóa field
Field sequence bị xóa
→ afterDestroy hook trigger
→ Xóa row tương ứng trong bảng sequencesapp.on('repair') — Sửa counter lệch
Trigger khi admin chạy repair
→ Tìm tất cả field sequence trong hệ thống
→ Với mỗi field:
→ SELECT MAX(extracted_number) FROM collection
→ So sánh với key trong bảng sequences
→ Nếu lệch → cập nhật key = max thực tế
→ Log kết quả sửa chữaSử dụng repair khi:
- Import dữ liệu từ nguồn khác (counter không được cập nhật).
- Khôi phục database từ backup cũ hơn.
- Phát hiện counter bị lệch do lỗi hệ thống.
Sơ đồ tổng quan
┌────────────────┐ lock + increment ┌────────────────┐
│ beforeSave │ ───────────────────────→ │ sequences │
│ Hook │ ←─────────────────────── │ table │
└───────┬────────┘ new counter value └────────────────┘
│
│ patterns → "DH-" + pad(43, 5)
│ result → "DH-00043"
▼
┌────────────────┐
│ Record field │
│ = "DH-00043" │
└────────────────┘