# Kế hoạch triển khai Module Quản lý APK (BuildHub APK Portal v3)

## 1. Mục tiêu
Tích hợp trọn vẹn gói mã nguồn **APK Portal v3** vào dự án hiện tại (`congviec.lvtglobal`):
- **Developer**: Upload APK/AAB, tự động sinh Build #1, #2... khi fix bug cùng version, giữ nguyên QR cho tester, xem lịch sử build.
- **Tester (QA)**: Hiển thị các app đã có bản ghi ở `apk_releases` thuộc quyền phụ trách của Tester đó (Admin xem tất cả), 5 box trạng thái thực tế từ DB (bỏ box Tất cả), lọc Dev/Trạng thái/Search, tải build mới nhất, form gửi kết quả test lưu trực tiếp vào DB.
- **Admin**: Xuất bản (Public) khi build đã Pass QA.
- **Khách / Thiết bị mobile**: Truy cập qua QR link `/apk-test/{token}` tải trực tiếp APK.

---

## 2. Trạng thái triển khai

| Hạng mục | Trạng thái | Ghi chú |
|---|---|---|
| **Sidebar Menu** | ✅ Xong | `admin.blade.php` và `employee.blade.php` đã cập nhật |
| **Routes** | ✅ Xong | 3 nhóm Developer / QA / Public, không trùng lặp |
| **Phân luồng View theo Role** | ✅ Xong | `index.blade.php` phân luồng dev/tester/admin |
| **4 Models** | ✅ Xong | `ApkRelease`, `ApkReleaseBuild`, `ApkShare`, `ApkTestReport` |
| **3 bảng DB** | ✅ Xong | `apk_releases`, `apk_shares`, `apk_release_builds + apk_test_reports` đã migrate |
| **QR Code Library** | ✅ Xong | `bacon/bacon-qr-code:^3.1` đã cài |
| **ApkManagerController** | ✅ Xong | `index`, `store`, `share`, `publish`, `download`, `downloadBuild`, `revoke` |
| **ApkTesterController** | ✅ Xong | `show` (trang public QR), `qr` (sinh SVG), `download` |
| **ApkQaController** | ✅ Xong | `index` (kết nối DB), `report`, `download` |
| **Phân quyền Gates** | ⏸️ Bỏ qua | Tất cả `Gate::authorize()` đã comment out, kiểm soát qua middleware route |
| **Màn hình Tester (`tester.blade.php`)** | ✅ Xong | Kết nối dữ liệu thật từ `apk_releases`, bỏ box Tất cả (5 box số liệu thật), lọc động, xem chi tiết và form gửi kết quả test thật |
| **Form upload APK/AAB thật** | ✅ Xong | Form có `action`, `method POST`, `enctype multipart`, `@csrf`, tất cả `name` attribute |
| **Input file accept .apk + .aab** | ✅ Xong | Frontend `accept=".apk,.aab"`, backend validate + ZipArchive check cả 2 loại |
| **Lưu file theo `apk_releases/{st_app}/{filename}`** | ✅ Xong | Ghi đè file khi upload lại cùng app, không dùng UUID |
| **Bảng Version & lịch sử build** | ✅ Xong | Blade server-side render thật từ DB, `tbody#devRowsReal` tách khỏi JS demo |
| **Layout bảng giống mockup** | ✅ Xong | Avatar chữ cái + màu, Build # badge, `<details>` lịch sử thu gọn, nút QR/Upload lại/Tải |
| **Custom searchable select dropdown** | ✅ Xong | Tìm kiếm tên app/package, badge Android/iOS, sync hidden select cho JS cũ |
| **Panel "Tiến độ phiên bản đang test"** | ✅ Xong | Hiển thị khi chọn app từ dropdown hoặc bấm "Upload lại" từ bảng lịch sử |
| **Bấm "Upload lại" → hiện đúng version** | ✅ Xong | Truyền `releaseId` vào `renderFeaturePanel`, ưu tiên version được chọn thay vì mới nhất |
| **Form upload nhận đúng fields** | ✅ Xong | `app_android_id`, `app_ios_id` set từ JS khi chọn app, `version_name`, `version_code`, `release_notes`, `auto_share` |
| **JS demo không ghi đè data thật** | ✅ Xong | `renderDev()` bị vô hiệu hoá, tbody đổi thành `devRowsReal` |
| **Admin thấy tất cả releases** | ✅ Xong | `isAdmin=true` → không filter theo `app_android_id/app_ios_id` |
| **Developer chỉ thấy app của mình** | ✅ Xong | Filter theo `developer_ids` JSON trong `app_androids/app_ios` |
| **View `download-apk.blade.php`** | ✅ Xong | Trang tải mobile `/apk-test/{token}` responsive, tải trực tiếp APK |
| **Chunk Upload nhanh (pion/laravel-chunk-upload)** | ✅ Xong | Cắt nhỏ 2MB/chunk, thanh tiến trình %, tính tốc độ MB/s, tự động ghép file |

---

## 3. Bước tiếp theo

### Bước 1 — Hoàn thiện trang public mobile `/apk-test/{token}` ⏳
File: `resources/views/apk-manager/download-apk.blade.php`  
Hiển thị: tên app, version, build #, nút Tải APK lớn  
Xử lý trạng thái: hết hạn / bị thu hồi / hết lượt tải

### Bước 2 — (Tùy chọn) Bổ sung Gates sau khi ổn định ⏸️
```php
// app/Providers/AppServiceProvider.php
Gate::define('manage-apks', fn($user) => in_array($user->role, ['Admin', 'Developer']));
Gate::define('test-apks',   fn($user) => in_array($user->role, ['Admin', 'Tester']));
Gate::define('publish-apks',fn($user) => $user->role === 'Admin');
```

---

## 4. Sơ đồ luồng dữ liệu

```
Developer upload APK/AAB
  → Form POST apks.admin.store
  → Validate .apk/.aab + ZipArchive check
  → Lưu file: storage/app/apk_releases/{st_app}/{filename}.(apk|aab)  [ghi đè]
  → Tạo/cập nhật ApkRelease + tạo ApkReleaseBuild (revision++)
  → (tuỳ chọn) Tạo ApkShare → sinh QR token

Developer xem lịch sử
  → ApkManagerController::index() → $releases với builds + shares eager loaded
  → Blade render bảng server-side (tbody#devRowsReal)
  → Panel "Tiến độ" cập nhật JS client-side từ window._apkReleasesData

Tester xem danh sách
  → ApkQaController::index() → filter/search/paginate
  → Tải APK: ApkQaController::download()
  → Gửi kết quả: ApkQaController::report() → cập nhật test_status

Admin thấy Pass → bấm Publish
  → ApkManagerController::publish() → set published_at

Thiết bị quét QR
  → /apk-test/{token} → ApkTesterController::show()
  → Bấm Tải → ApkTesterController::download() → stream file từ private storage
```

---

## 5. Cấu trúc file quan trọng

```
app/
  Http/Controllers/APK/
    ApkManagerController.php   ✅ Xong
    ApkQaController.php        ✅ Xong
    ApkTesterController.php    ✅ Xong
  Models/
    ApkRelease.php             ✅ Xong
    ApkReleaseBuild.php        ✅ Xong
    ApkShare.php               ✅ Xong
    ApkTestReport.php          ✅ Xong

database/migrations/
  2026_11_04_000001_create_apk_releases_table.php       ✅ Migrated
  2026_11_04_000002_create_apk_shares_table.php         ✅ Migrated
  2026_11_04_000003_create_apk_builds_and_test_reports_table.php  ✅ Migrated

routes/essential/apk_manager/apk_manager.php            ✅ Xong

resources/views/apk-manager/
  index.blade.php              ✅ Xong (phân luồng role, JS demo tách biệt)
  dev.blade.php                ✅ Xong (form upload thật, bảng lịch sử Blade, panel tiến độ JS)
  tester.blade.php             ✅ Xong (phân luồng role)
  qa-index.blade.php           ✅ Xong (danh sách QA, modal kết quả)
  download-apk.blade.php       ⏳ Cần hoàn thiện UI mobile

storage/app/apk_releases/
  {st_app}/
    {original_filename}.apk    ← Ghi đè khi upload lại cùng app
    {original_filename}.aab
```
để upload file nhanh
composer require pion/laravel-chunk-upload

