# Phân Hệ Quản Lý Phúc Khảo (Web Exam Regrading)
## 03. Sơ Đồ Chức Năng & Thiết Kế API (Function Diagram & Design)

---

### 1. Kiến Trúc Thành Phần Phân Hệ (System Architecture)

```mermaid
graph TD
    subgraph ClientLayer ["Client Presentation Layer (Browser)"]
        BladeView["Blade View: exam-regrading.index"]
        JSController["JS: exam-regrading.js"]
        ModalRegrade["Modal Chấm Phúc Khảo: exam-detail-modal.edit.js"]
        ModalCheating["Modal Xem Bằng Chứng Gian Lận"]
    end

    subgraph RouterMiddleware ["Routing & Middleware Layer"]
        Routes["routes/web.php (prefix: exam-regrading)"]
        AuthMid["Middleware: auth, check.permission"]
        TenantMid["Middleware: tenant.access:web"]
    end

    subgraph ControllerLayer ["Application Controller Layer"]
        ERC["ExamRegradingController"]
        SEHC["StudentExamHistoryController (API Chấm)"]
    end

    subgraph Services ["Service & Parsing Layer"]
        IclScoreSvc["IclScoreService (parseEmsSnapshot)"]
        MoodleSvc["ApiMoodleService (Category Map)"]
        TenantHelper["HelperTenant"]
    end

    subgraph DataStorage ["Data Layer"]
        DB[(MySQL Database - Multi-Tenant)]
    end

    BladeView --> JSController
    JSController --> RouterMiddleware
    RouterMiddleware --> ERC
    RouterMiddleware --> SEHC

    ERC --> IclScoreSvc
    ERC --> MoodleSvc
    ERC --> TenantHelper
    ERC --> DB

    SEHC --> DB
    JSController -.->|Kích hoạt chấm phúc khảo| ModalRegrade
```

---

### 2. Sơ Đồ Luồng Xử Lý Chức Năng (Function Flowcharts)

#### 2.1. Hàm `getExamRegrading` (ExamRegradingController)

```mermaid
flowchart TD
    Start([GET /exam-regrading/get-exam-regrading]) --> GetTenant[Lấy Tenant Connection]
    GetTenant --> BuildQ[buildExamRegradingQuery: Lọc tah.assign_type = 2 VÀ lấy MAX tah.id]
    BuildQ --> ApplyFilters[Áp dụng bộ lọc: Ngày tháng, Phone, Email, QA ID, Student Code, Product, Course, Exam, Status]
    ApplyFilters --> Paginate[Thực thi phân trang paginate per_page]
    
    Paginate --> ExtractIDs[Lấy danh sách student_score_ids trên trang hiện tại]
    ExtractIDs --> BatchHistory[Batch Query: Lấy toàn bộ StudentScoreGradingHistory của các student_score_ids]
    
    ExtractIDs --> CheckCheating{Có bài thi cheating_status = 1?}
    CheckCheating -- Có --> QueryTeacherLogs[Truy vấn data_rescored từ student_exam_histories_teachers]
    QueryTeacherLogs --> BuildCheatingMap[Bóc tách cheating_reports chi tiết Writing & Speaking]
    CheckCheating -- Không --> LoopTransform
    BuildCheatingMap --> LoopTransform
    
    LoopTransform[Lặp qua Collection để Format dữ liệu] --> CalcProduct[Gán Tên Sản Phẩm Root Category]
    CalcProduct --> ParseBefore[Parse Điểm Trước PK: assign_type = 1]
    ParseBefore --> ParseAfter[Parse Điểm Sau PK: assign_type = 2]
    ParseAfter --> BindCheating[Gán cheating_reports & cờ has_cheating]
    
    BindCheating --> NextItem{Còn bài thi?}
    NextItem -- Còn --> LoopTransform
    NextItem -- Hết --> ReturnJSON[HTTP 200 JSON {success: true, data}]
```

---

### 3. Đặc Tả API Chi Tiết (API Specification)

#### 3.1. `GET /exam-regrading/get-exam-regrading`
- **Route Name**: `exam-regrading.getExamRegrading`
- **Middleware**: `auth`, `check.permission`, `tenant.access:web`
- **Request Parameters (Query)**:
  | Tham số | Kiểu | Mô tả |
  | :--- | :---: | :--- |
  | `page` | Integer | Số trang (Mặc định: 1) |
  | `per_page` | Integer | Số bản ghi trên trang (Mặc định: 10) |
  | `start_date` / `end_date` | String | Khoảng ngày yêu cầu phúc khảo (`d-m-Y`) |
  | `phone` / `email` | String | Tìm theo SĐT / Email học viên |
  | `qa_id[]` | Array[Int] | Lọc theo ID cán bộ QA được phân công |
  | `student_code[]` | Array[Int] | Lọc theo danh sách học viên |
  | `product[]` / `course[]` / `exam[]` | Array[Int] | Mảng ID Sản phẩm, Khóa học, Bài thi |
  | `grading_status` | Integer / String | Trạng thái phúc khảo |
- **Response Success (200 OK)**:
  ```json
  {
      "success": true,
      "data": {
          "current_page": 1,
          "last_page": 3,
          "total": 28,
          "data": [
              {
                  "tah_id": 1502,
                  "student_score_id": 6120,
                  "created_at": "2026-10-06 10:15:00",
                  "qaEmail": "qa.huong@hocmai.vn",
                  "studentName": "Phạm Văn C",
                  "studentEmail": "phamvanc@gmail.com",
                  "studentCode": "HV_2026_88",
                  "product": "IELTS Master",
                  "course": "IELTS Intensive 6.5+",
                  "exam": "Mocktest 03",
                  "timeStart": "2026-10-06 08:00:00",
                  "timeEnd": "2026-10-06 10:00:00",
                  "assignedTime": "2026-10-06 10:30:00",
                  "deadline": "2026-10-08 10:30:00",
                  "statusId": 1,
                  "abnormal": "Bình thường",
                  "has_cheating": false,
                  "cheating_reports": [],
                  "scoreBeforePk": {
                      "overall": 6.0,
                      "skills": {
                          "Listening": 6.5,
                          "Reading": 6.5,
                          "Writing": 5.5,
                          "Speaking": 5.5
                      }
                  },
                  "scoreAfterPk": {
                      "overall": 6.5,
                      "skills": {
                          "Listening": 6.5,
                          "Reading": 6.5,
                          "Writing": 6.0,
                          "Speaking": 6.0
                      }
                  }
              }
          ]
      }
  }
  ```
