# Setup Lokal - GTGStore (WSL2 Ubuntu)

## Prasyarat
```bash
sudo apt update
sudo apt install php8.3 php8.3-cli php8.3-mbstring php8.3-xml php8.3-curl \
  php8.3-mysql php8.3-sqlite3 php8.3-zip php8.3-bcmath php8.3-gd php8.3-intl \
  mariadb-server unzip git
```

Composer:
```bash
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
```

## Clone/Setup Project
```bash
composer create-project laravel/laravel:^10.0 GTGStore
cd GTGStore
```

Catatan: kalau composer error soal security advisory saat resolve, jalankan:
```bash
composer config --global policy.advisories.block false
```

## Tailwind CSS v3
```bash
npm install -D tailwindcss@^3 postcss autoprefixer
npx tailwindcss init -p
```

## Database
```bash
sudo service mariadb start
sudo mysql -e "
CREATE DATABASE IF NOT EXISTS gtgstore;
CREATE DATABASE IF NOT EXISTS gtgstore_test;
CREATE USER IF NOT EXISTS 'gtgstore'@'localhost' IDENTIFIED BY 'GANTI_PASSWORD';
GRANT ALL PRIVILEGES ON gtgstore.* TO 'gtgstore'@'localhost';
GRANT ALL PRIVILEGES ON gtgstore_test.* TO 'gtgstore'@'localhost';
FLUSH PRIVILEGES;
"
```

## Environment
```bash
cp .env.example .env
php artisan key:generate
```
Isi di `.env`: `DB_USERNAME`, `DB_PASSWORD`, `ADMIN_LOGIN_PATH` (string acak, contoh:
`php artisan tinker --execute="echo bin2hex(random_bytes(8));"`).

`PAKASIR_PROJECT_SLUG` dan `PAKASIR_API_KEY` baru diisi setelah daftar/login di
https://app.pakasir.com dan buat project mode Sandbox.

`phpunit.xml` sudah diarahkan ke `DB_DATABASE=gtgstore_test` untuk testing, terpisah
dari database development.

## Migrasi dan Data Uji
```bash
php artisan migrate --seed
```

## Build Frontend
```bash
npm run build
```

## Buat Admin Pertama
```bash
php artisan tinker --execute="
App\Models\Admin::create([
    'name' => 'Admin GTGStore',
    'email' => 'admin@gtgstore.test',
    'password' => Hash::make('GANTI_PASSWORD'),
    'is_active' => true,
]);
"
```

## Jalankan
```bash
php artisan serve
```
- Storefront: http://127.0.0.1:8000
- Admin: http://127.0.0.1:8000/{ADMIN_LOGIN_PATH} (sesuai .env)

## Menjalankan Test
```bash
php artisan test
```

## Cron Reconciliation (test manual lokal)
```bash
php artisan orders:reconcile
```
Untuk simulasi otomatis tiap menit di lokal, jalankan di terminal terpisah:
```bash
php artisan schedule:work
```

## Testing Pembayaran QRIS Tanpa Akun Pakasir Asli

Selama `PAKASIR_SANDBOX_MODE=true` di `.env` (default), `PakasirClient` tidak memanggil
API Pakasir sama sekali. Alurnya untuk test lokal:

1. Checkout produk seperti biasa dari storefront, sampai masuk ke halaman invoice.
2. Halaman invoice akan menampilkan QR dummy (bukan QR asli, sekadar string acak yang
   tetap valid dirender sebagai gambar QR untuk keperluan tampilan).
3. Untuk mensimulasikan pembayaran berhasil (memicu transisi status + fulfillment
   seperti webhook Pakasir asli):
   ```bash
   php artisan pakasir:simulate-payment {order_public_token}
   ```
   `{order_public_token}` bisa dilihat dari URL invoice (`/invoice/{public_token}`).

Command ini ditolak kalau `APP_ENV=production` — murni untuk development. Detail lengkap
di `docs/webhook-handling.md`.

## Isu Teknis yang Pernah Ditemukan (lihat docs/CHANGELOG.md untuk detail lengkap)
- Urutan migrasi harus mengikuti rantai foreign key: categories -> admins -> products
  -> vouchers -> orders -> product_stock -> order_stock_link -> payment_events ->
  activity_logs -> order_status_history.
- Model pakai `protected $casts = [...]` (Laravel 10), BUKAN method `casts()`
  (fitur Laravel 11).
- `ProductStock` butuh `protected $table = 'product_stock';` eksplisit (konvensi
  plural Eloquent menebak `product_stocks`).
- MariaDB kadang perlu `DROP USER` lalu `CREATE USER` ulang kalau user sempat
  dibuat dengan kredensial lain sebelumnya.
