# 🔧 FIX: Auto-End Sessions và Update Aggregation Tables

## ❌ VẤN ĐỀ

1. **Cron job `sessions:auto-end` chạy nhưng không update bảng `student_daily_study_time`**
2. **Method `autoEndInactiveSessions()` không nhận `$tenantConnection`**
3. **Query từ default connection thay vì từng tenant connection**

---

## ✅ ĐÃ SỬA

### **1. Sửa Method `autoEndInactiveSessions()`**

**File:** `app/Services/HeatUser/StudySessionService.php`

**Thay đổi:**
- ✅ Thêm parameter `$tenantConnection = null`
- ✅ Query với `StudentStudySession::on($tenantConnection)` thay vì default connection
- ✅ Truyền `$tenantConnection` vào `endSessionWithTime()` để update đúng các bảng aggregation
- ✅ Thêm logging với tenant connection info

**Code trước:**
```php
public function autoEndInactiveSessions()
{
    // Query từ default connection ❌
    StudentStudySession::where('status', ...)
        ->chunkById(500, function($sessions) {
            // ...
        });
}
```

**Code sau:**
```php
public function autoEndInactiveSessions($tenantConnection = null)
{
    // Query với tenant connection ✅
    $query = $tenantConnection 
        ? StudentStudySession::on($tenantConnection)
        : StudentStudySession::query();
    
    $query->where('status', ...)
        ->chunkById(500, function($sessions) use ($tenantConnection) {
            // Truyền $tenantConnection vào endSessionWithTime() ✅
            $this->endSessionWithTime($session, $endTime, ..., $tenantConnection);
        });
}
```

---

### **2. Sửa Command `AutoEndInactiveSessions`**

**File:** `app/Console/Commands/AutoEndInactiveSessions.php`

**Thay đổi:**
- ✅ Truyền `$connectionName` vào `autoEndInactiveSessions($connectionName)`

**Code trước:**
```php
$endedCount = $service->autoEndInactiveSessions();  // ❌ Không truyền connection
```

**Code sau:**
```php
$endedCount = $service->autoEndInactiveSessions($connectionName);  // ✅ Truyền connection
```

---

## 🔄 LUỒNG SAU KHI SỬA

### **Cron Job chạy mỗi 5 phút:**

```
1. Cron: sessions:auto-end (mỗi 5 phút)
   ↓
2. Command: AutoEndInactiveSessions@handle()
   → Loop qua tất cả tenants
   ↓
3. Với mỗi tenant:
   → Gọi service->autoEndInactiveSessions($connectionName) ✅
   ↓
4. Service: autoEndInactiveSessions($tenantConnection)
   → Query sessions từ đúng tenant connection ✅
   → Với mỗi session timeout:
      → endSessionWithTime($session, ..., $tenantConnection) ✅
      → distributeDailyTime(..., $tenantConnection) ✅
      → updateDailyStudyTime(..., $tenantConnection) ✅
      → updateHistoryStudyTime(..., $tenantConnection) ✅
      → updateContestStudyTime(..., $tenantConnection) ✅
   ↓
5. Kết quả:
   ✅ student_daily_study_time được update
   ✅ student_history_study_time được update
   ✅ student_contest_study_time được update
```

---

## 📊 CÁC BẢNG ĐƯỢC UPDATE

Sau khi sửa, các bảng aggregation sẽ được update khi cron job chạy:

| Bảng | Khi nào update | Method |
|------|----------------|--------|
| `student_daily_study_time` | ✅ Khi session auto-ended | `updateDailyStudyTime()` |
| `student_history_study_time` | ✅ Khi session auto-ended | `updateHistoryStudyTime()` |
| `student_contest_study_time` | ✅ Khi session auto-ended | `updateContestStudyTime()` |

---

## ✅ CÁCH KIỂM TRA

### **1. Kiểm tra Cron Job:**

```bash
# Chạy thủ công
php artisan sessions:auto-end

# Xem log
tail -f storage/logs/laravel.log | grep "auto-end"
```

### **2. Kiểm tra bảng `student_daily_study_time`:**

```sql
-- Xem dữ liệu mới nhất
SELECT * FROM student_daily_study_time 
WHERE student_id = YOUR_STUDENT_ID 
ORDER BY study_date DESC 
LIMIT 10;

-- Đếm số records
SELECT COUNT(*) FROM student_daily_study_time;
```

### **3. Kiểm tra sessions đã được auto-end:**

```sql
-- Xem sessions auto-ended gần đây
SELECT * FROM student_study_sessions 
WHERE status = 'auto_ended' 
ORDER BY session_end_at DESC 
LIMIT 10;
```

---

## 🎯 KẾT QUẢ

Sau khi sửa:
- ✅ Cron job query đúng tenant connection
- ✅ Các bảng aggregation được update khi session auto-end
- ✅ `student_daily_study_time` có dữ liệu mới
- ✅ Multi-tenant hoạt động đúng

---

## 📝 LƯU Ý

1. **Cron job chạy mỗi 5 phút** → Sessions timeout sau 10 phút không có heartbeat sẽ được auto-end
2. **Các bảng aggregation chỉ update khi session kết thúc** (submit, stop, hoặc auto-end)
3. **Nếu học sinh đóng trình duyệt**, session sẽ được auto-end sau 10 phút và các bảng sẽ được update

