# Deploying to cPanel

Laravel 13 (PHP 8.3) deploy checklist for this app. Written for the layout you
use: **the domain's document root points at the app's `public/` folder**, with
the rest of the app sitting outside the web root.

```
/home/USER/vantagemarkets/          <- full app, OUTSIDE the web root
    app/  config/  routes/  storage/  vendor/  .env
    public/   <-- cPanel Document Root points HERE
        index.php  .htaccess  build/  storage(link or folder)
```

> Replace `/home/USER/vantagemarkets` everywhere with your real path. Get it from
> the `base_path()` row on `/admin/upload-diagnostics`, or cPanel File Manager.

---

## 1. Build assets locally (before upload)

cPanel usually has no Node. Build on your machine and upload the result.

```bash
npm ci
npm run build        # writes public/build/ (manifest.json + assets/)
```

Commit/upload `public/build/`. Do **not** run `npm` on the server.

---

## 2. Upload the app

Upload everything **except**: `node_modules/`, `.env`, `.git/`, `tests/`, and
any local SQLite (`database/database.sqlite`). `vendor/` must be present — either
upload it, or run `composer install --no-dev --optimize-autoloader` on the server
if Composer + the right PHP CLI are available.

Point the domain's **Document Root** at `/home/USER/vantagemarkets/public`
(cPanel → Domains → Manage → Document Root, or set it when creating the
addon/subdomain). Never expose the project root as the docroot — that would put
`.env` on the web.

---

## 3. Production `.env`

Do not upload your local `.env`. Create it on the server (File Manager) with at
least these changed from local:

```
APP_ENV=production
APP_DEBUG=false
APP_URL=https://vantagepromarket.com

APP_KEY=base64:...        # keep the EXISTING key; regenerating logs everyone out
                          # and breaks existing encrypted/hashed data

DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=your_cpanel_db
DB_USERNAME=your_cpanel_user
DB_PASSWORD=your_cpanel_pass

SESSION_DRIVER=database   # requires the `sessions` table (created by migrate)
QUEUE_CONNECTION=database

MAIL_MAILER=resend
RESEND_KEY=...
```

`APP_DEBUG=false` is mandatory in production — `true` leaks `.env` values and
stack traces on any error.

---

## 4. One-time server commands

From the app root (`/home/USER/vantagemarkets`, **not** `public/`):

```bash
php artisan migrate --force      # --force is required in production
php artisan config:clear
```

`migrate` creates the `sessions` and `jobs` tables the database session/queue
drivers depend on.

---

## 5. Uploads / storage  ← the part that usually breaks on cPanel

Uploads are written to the `public` disk and displayed via relative
`/storage/...` URLs (`App\Support\PublicStorage::url()`), which resolve to
`public/storage/...`. That folder must contain the uploaded files. Pick ONE:

### Option A — symlink (Laravel-standard, try first)
```bash
php artisan storage:link --relative
php artisan config:clear
```
Creates `public/storage` → `../storage/app/public`. On single-user cPanel this
usually works. `--relative` keeps it portable across account paths.

### Option B — no symlink (bulletproof; use if Option A 403s)
Write uploads straight into the web-served folder. In `.env`:
```
FILESYSTEM_DISK=public
FILESYSTEM_PUBLIC_ROOT=/home/USER/vantagemarkets/public/storage
FILESYSTEM_PUBLIC_URL=https://vantagepromarket.com/storage
```
Then:
```bash
mkdir -p /home/USER/vantagemarkets/public/storage
chmod -R 755 /home/USER/vantagemarkets/public/storage
php artisan config:clear
```
With Option B, do **not** run `storage:link` — the real folder and a symlink
would collide.

### Verify
Log in as admin and open **`/admin/upload-diagnostics`**. Green needed on:
`storage path writable`, `write probe`, and (Option A only) `link resolves to
storage`. Then upload a profile photo and confirm it displays.

### PHP upload limits
cPanel → MultiPHP INI Editor. Ensure `upload_max_filesize` and `post_max_size`
are ≥ the app's limits (profile photo `max:2048` = 2 MB; identity docs 5 MB),
and `file_uploads = On`. Values also shown on the diagnostics page.

---

## 6. Writable directories

PHP must be able to write to these (500s the whole app otherwise):

```bash
chmod -R 755 storage bootstrap/cache
# if PHP runs as a different group, use 775 instead
```

---

## 7. Cache for production (do this LAST, after `.env` is final)

```bash
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

Re-run `config:clear` + `config:cache` **every time you edit `.env`** — cached
config ignores later `.env` changes.

---

## 8. Post-deploy cleanup

Once uploads are confirmed working, remove the diagnostics tool — it exposes
server paths and PHP config to any admin:

- `routes/web.php` → the `/upload-diagnostics` route
- `app/Http/Controllers/Admin/UploadDiagnosticsController.php`

---

## Quick redeploy (code changes only)

```bash
# upload changed files (+ rebuilt public/build if assets changed)
php artisan migrate --force        # if there are new migrations
php artisan config:cache
php artisan route:cache
php artisan view:cache
```
