# Tài liệu Chức năng: Kiểm tra Bài thi Bất thường (Suspicious Exam Check)

## 1. Giới thiệu tổng quan
Hệ thống kiểm tra bài thi bất thường được thiết kế để tự động quét và phân tích các bài thi ngay sau khi học viên nộp bài. Mục tiêu là phát hiện các dấu hiệu gian lận hoặc kết quả không logic để đưa ra hướng xử lý tự động: Gán giáo viên chấm lại hoặc thông báo hoàn thành cho bộ phận quản lý.

## 2. Thành phần hệ thống

### 2.1. CheckSuspiciousExamJob
- **Đường dẫn**: `app/Jobs/CheckSuspiciousExamJob.php`
- **Vai trò**: Là một Queue Job xử lý bất đồng bộ (background task). Nó giúp hệ thống không bị treo khi học viên nộp bài, đồng thời đảm bảo việc kiểm tra được thực hiện ngay cả khi có lượng lớn bài thi nộp cùng lúc.
- **Tham số đầu vào**:
    - `$studentScoreId`: ID của bản ghi điểm trong bảng `student_scores`.
    - `$status`: Trạng thái bài thi lúc nộp.
    - `$tenantConnection`: Tên kết nối database của tenant (đảm bảo đa nền tảng).

### 2.2. SuspiciousExamService
- **Đường dẫn**: `app/Services/SuspiciousExamService.php`
- **Vai trò**: "Bộ não" của chức năng. Chứa các quy tắc kiểm tra (Rules) và quy trình xử lý kết quả (Workflow).

## 3. Luồng xử lý chính (Main Workflow)

1.  **Tiếp nhận**: Job được dispatch sau khi học viên hoàn thành bài thi.
2.  **Kiểm tra điều kiện lọc**:
    - Trạng thái phải là `0` (Đã nộp bài, chờ xử lý).
    - Bài thi chưa từng được kiểm tra (`is_checked_suspicious = 0`).
3.  **Thực thi các luật kiểm tra (Rules)**:
    - Nếu vi phạm bất kỳ luật nào: Đánh dấu là **Bất thường (Suspicious)**.
    - Nếu không vi phạm: Đánh dấu là **Bình thường (Normal)**.
4.  **Hành động sau kiểm tra**:
    - **Nếu Bất thường**: Tự động gán giáo viên chấm lại.
    - **Nếu Bình thường**: Thông báo cho bên thứ 3 (Quản lý/Sale) và cho phép xem kết quả.
5.  **Kết thúc**: Cập nhật cờ `is_checked_suspicious = 1` để tránh quét lặp.

## 4. Các Quy tắc kiểm tra (Rules)

### Quy tắc 1: Hành vi bất thường (`checkAbnormalBehavior`)
- **Chuyển Tab**: Nếu học viên chuyển sang tab khác hoặc thoát trình duyệt từ **3 lần trở lên**.
- **Làm bài quá nhanh (Đang ẩn)**: So sánh thời gian làm bài thực tế với thời gian cho phép của từng kỹ năng. Nếu < 1/5 thời gian cho phép sẽ bị coi là bất thường.
- **Tổng thời gian cực ngắn (Đang ẩn)**: Nếu toàn bộ bài thi hoàn thành trong ít hơn 5 phút.

### Quy tắc 2: Lệch điểm giữa các kỹ năng (`checkScoreDiscrepancy`)
- Tự động so sánh điểm số giữa các kỹ năng dựa trên công thức chấm (Formula) của Campaign:
    - **Easy IELTS**: Bắt lỗi nếu chênh lệch giữa các cặp kỹ năng (L-R, W-S) >= 2.0 band hoặc (L/R - W/S) >= 3.0 band.
    - **Easy PASS**: Bắt lỗi nếu bất kỳ hai kỹ năng nào chênh lệch nhau >= 3.0 điểm/band.

## 5. Xử lý kết quả

### Luồng 1: Bài thi Bất thường (Gán giáo viên)
- **Cơ chế gán**: Dựa vào cấu hình `grading_scope` của Campaign:
    - `Scope 0 (Gộp)`: Gán tất cả kỹ năng cần chấm cho cùng 1 giáo viên ngẫu nhiên.
    - `Scope 1 (Tách)`: Mỗi kỹ năng được gán cho một giáo viên ngẫu nhiên khác nhau.
- **Trạng thái**: `exam_status` chuyển sang `2` (Đang chờ chấm lại).
- **Lưu vết**: Ghi nhận vào bảng `teacher_assigned_histories`.

### Luồng 2: Bài thi Bình thường (Thông báo Quản lý)
- **Đối tượng nhận**: User quản lý được gắn trong `StudentTracking`.
- **Quyền hạn**: User nhận phải có quyền `notifications.receiveCompleteExam`.
- **Trạng thái**: `exam_status` chuyển sang `4` (Hoàn thành) và bật `third_party_access = 1`.
- **Thông báo**: Gửi Notification hệ thống báo bài thi đã sẵn sàng.

## 6. Ghi chú kỹ thuật
- **Log**: Toàn bộ quá trình được ghi lại trong Laravel Log với tiền tố `CheckSuspiciousExamJob` hoặc `Xử lý bài thi bất thường`.
- **Tính mở rộng**: Các luật kiểm tra mới có thể dễ dàng thêm vào `SuspiciousExamService` mà không ảnh hưởng đến cấu trúc Job.