# Tugasan: Deploy BUKUKU ke production (cPanel)

## Konteks

- Repo: https://github.com/mnasiruddinz/bukuku (branch `main`)
- Commit untuk deploy: `b05bda5`, iaitu "Speed up book loading: compress PDFs on upload, session-less assets"
- Commit sebelum ni (untuk rollback): `1f019bb`
- Site live: https://bukuku.mnz.one
- Hosting: cPanel (LiteSpeed, PHP 8.3), path `/home/mnzone/public_html/bukuku`, FTP `ftp.mnz.one`, user `bukuku@mnz.one`
- Cara deploy: skrip `deploy.sh` dalam repo. Skrip ni run `npm run build`, kemudian `lftp mirror --reverse --delete` ke server.

### Apa yang berubah dalam commit ni

1. PDF yang di-upload dan saiznya lebih 5 MB dimampatkan dengan Ghostscript (`gs`) di server. Kalau `gs` tiada, upload tetap berjaya tapi PDF tak dimampatkan.
2. Route `/s/{token}/asset/{pdf|cover|audio}` sekarang berjalan **tanpa session**. Buku berkata laluan guna token `t=` dalam URL asset.
3. Reader: audio `preload="none"`, dan saiz chunk pdf.js 1 MB.
4. Tiada migration baru, jadi **tak perlu** run `setup-run.php`.

## Langkah

### 1. Sediakan kod

```bash
cd /Applications/Projects/buku
git fetch origin && git checkout main && git pull --ff-only
git log --oneline -1   # mesti tunjuk b05bda5 (atau lebih baru)
git status --short     # mesti kosong
```

Kalau ada perubahan yang belum di-commit, **berhenti dan tanya pemilik**. Jangan deploy kod yang belum di-commit.

### 2. Test dulu

```bash
php artisan test
```

Semua test mesti lulus (64 test). Kalau ada yang gagal, berhenti dan laporkan output.

### 3. Deploy

Password FTP **tidak** ada dalam repo. Ambil dari secret store anda, atau minta pemilik. Jangan tulis password dalam fail, log atau commit.

```bash
export FTP_PASS='<dari secret store>'
bash deploy.sh
unset FTP_PASS
```

Amaran: `mirror --delete` akan memadam fail di server yang tiada dalam folder local. `.env`, `database/database.sqlite`, `storage/app/private/*` (fail buku), `storage/app/public/*`, session, cache dan log memang dikecualikan. **Jangan buang** mana-mana `--exclude-glob` dalam `deploy.sh`.

### 4. Semak Ghostscript di server

Run di Terminal cPanel (atau SSH):

```bash
which gs && gs --version
php -r 'var_dump(function_exists("proc_open"));'
```

- Kalau `gs` ada dan `proc_open` = `true`, pemampatan PDF akan berfungsi.
- Kalau `gs` ada tapi bukan dalam PATH, tambah `BUKUKU_GHOSTSCRIPT=/path/penuh/ke/gs` dalam `.env` server.
- Kalau `gs` tiada, laporkan kepada pemilik. Ini bukan halangan untuk deploy, cuma pemampatan tak akan jalan.

Lepas apa-apa perubahan `.env`, kalau server guna config cache, run `php artisan config:clear`.

### 5. Semak site live

```bash
# a) Halaman share: mesti 200
curl -s -o /dev/null -w '%{http_code}\n' https://bukuku.mnz.one/s/j00s7VzVG1sb9k26OTc1BpN6L1aTTqmk

# b) Asset PDF: mesti 200, dan TIADA header set-cookie (bukti route tanpa session)
curl -s -o /dev/null -D - -r 0-1023 https://bukuku.mnz.one/s/j00s7VzVG1sb9k26OTc1BpN6L1aTTqmk/asset/pdf | grep -iE '^HTTP|set-cookie'

# c) Build baru dah sampai: fail JS yang dirujuk dalam halaman mesti 200
curl -s https://bukuku.mnz.one/s/j00s7VzVG1sb9k26OTc1BpN6L1aTTqmk | grep -oE 'build/assets/app-[^"]+\.js' | head -1 \
  | xargs -I{} curl -s -o /dev/null -w '%{http_code}\n' https://bukuku.mnz.one/{}
```

Jangkaan:
- (a) `200`
- (b) `HTTP/2 206` dan **tiada** baris `set-cookie`
- (c) `200`

Semak manual dalam browser:
- Buka link share di atas. Buku patut keluar dan boleh diselak. Audio main bila ditekan.
- Log masuk. Pada buku berkata laluan, buka link share dalam tetingkap incognito, masukkan kata laluan, dan pastikan PDF terbuka.
- Upload PDF besar (> 5 MB). Mesej berjaya patut sebut "PDF dimampatkan … daripada X kepada Y", atau beri amaran saiz kalau `gs` tiada.

### 6. Kalau rosak: rollback

```bash
git checkout 1f019bb
bash deploy.sh          # dengan FTP_PASS sama seperti langkah 3
git checkout main
```

Kemudian laporkan apa yang rosak, berserta output curl atau ralat dari `storage/logs/laravel.log` di server.

## Laporan akhir

Hantar kepada pemilik:
- Commit yang di-deploy
- Keputusan test
- Output semakan (a), (b) dan (c)
- Keputusan semakan `gs` dan `proc_open`
- Apa-apa amaran atau ralat masa deploy
