# Roote — cPanel Deployment Runbook

This is the one authoritative deploy doc (DEPLOY.md is a pointer to this
file — don't split instructions across both again). It matches how this
project is actually deployed: **zip the `pr-laravel` folder locally,
upload via cPanel File Manager.** No GitHub, no SSH, no Terminal app.
That's a completely normal way to run shared hosting — the only thing
that changed is *how* migrations and cache-clearing get triggered after
upload, since there's no shell to run `artisan` from directly.

## Before you start — if this is an update to an already-live site

1. **Back up the production database first.** `mysqldump` it from cPanel
   (phpMyAdmin → Export, or the "Backup" tool) before running any new
   migration. Migrations in this deploy are additive (they only add new
   tables/columns), but back up regardless — always do this before
   touching a live database.
2. If `public/fix-final.php` is still present on the live server from a
   previous deploy, **delete it now** via File Manager. It was a
   static-token-gated script that could rewrite app files and run
   arbitrary SQL against production — it's been replaced with
   `deploy-tools.php` (below), which can only run a fixed whitelist of
   safe commands.
3. Rotate any account passwords that were created via the old hardcoded
   `Demo@12345678` seed password (the seeder no longer does this, but
   accounts already created with it need a manual password change).

## 1. Build locally

```bash
cd pr-laravel
composer install --no-dev --optimize-autoloader
npm install && npm run build
```

Don't run the `config:cache` / `route:cache` / etc. build steps locally
against your dev `.env` — you'll do that on the server after upload via
`deploy-tools.php`, against the real production `.env` (a config cache
built from the wrong `.env` will break the live site).

## 2. Set up MySQL in cPanel

1. **MySQL Databases** → create a database and a user, add the user to
   the database with **ALL PRIVILEGES**.
2. Note the database name, username, and password — cPanel usually
   prefixes them with your account name (e.g. `tanlurij_roote`).

## 3. Configure `.env`

1. Copy `.env.production.example` to `.env`.
2. Fill in `APP_URL`, the MySQL credentials from step 2, and
   `APP_KEY` — generate one locally with `php artisan key:generate --show`
   and paste the output in.
3. Set `DEPLOY_TOOL_TOKEN` to a long random string, e.g.:
   ```bash
   php -r "echo bin2hex(random_bytes(24)), PHP_EOL;"
   ```
   This is the token for `deploy-tools.php` (step 5). **Never** reuse a
   token that has appeared anywhere in this repo's git history — this
   one is brand new and only lives in your server's `.env`.
4. Review `FEATURE_INVOICING` / `FEATURE_INFLUENCERS` /
   `FEATURE_CRISIS_SESSIONS` — these are `false` by default (hidden from
   the agency nav per the product scope cut). Set any of them to `true`
   only if an agency on this instance is already actively using that
   module.
5. Set your real `OPENAI_API_KEY`, `MAIL_*`, and any monitoring API keys
   you're using (`NEWSAPI_KEY`, `YOUTUBE_API_KEY`, `RAPIDAPI_KEY`, ...).

## 4. Upload

1. Zip the entire `pr-laravel` folder (everything except `.git`,
   `node_modules`, and your local `.env`).
2. Upload via cPanel File Manager and extract into your target
   directory.
3. Set the **document root** to the `public` subfolder — e.g. if
   installed at `public_html/roote/`, document root must be
   `public_html/roote/public`, not `public_html/roote`.
4. Upload your real `.env` from step 3 separately (it's excluded from
   the zip on purpose — never let it sit in git history).

## 5. Run migrations and warm the cache — `deploy-tools.php`

This is your replacement for `fix-final.php`. It's a **permanent** file
(unlike the old `setup.php`, it doesn't self-lock) that you'll reuse
after every future deploy — but it can only run the commands in its
whitelist, never raw SQL or arbitrary file writes, and it locks itself
out for 15 minutes after 5 wrong-token attempts.

Visit, in this order:

```
https://yourdomain.com/deploy-tools.php?token=YOUR_TOKEN&cmd=migrate
https://yourdomain.com/deploy-tools.php?token=YOUR_TOKEN&cmd=seed        (first deploy only)
https://yourdomain.com/deploy-tools.php?token=YOUR_TOKEN&cmd=storage-link (first deploy only)
https://yourdomain.com/deploy-tools.php?token=YOUR_TOKEN&cmd=cache-warm
```

**The `seed` step prints the seeded account passwords in the page
response and nowhere else — copy them immediately, then change them
via the profile page on first login.**

Hit the URL with no `?cmd=` (just the token) any time to see the full
list of available commands — it includes `cache-clear` (run this before
`cache-warm` if you're troubleshooting a stale-cache issue) and
`evidence-backfill` / `evidence-backfill-dry` (see below).

You do **not** need to delete `deploy-tools.php` after use — it's meant
to stay, so you have this capability for every future deploy without
re-adding a fix-final.php-style script each time. Do treat
`DEPLOY_TOOL_TOKEN` as a real production credential: keep it only in
`.env`, rotate it if you ever suspect it leaked, and check
`storage/logs/deploy-tools.log` occasionally to see what's been run
against production and from where.

## 6. Set up cron (queue worker + scheduled monitoring)

In cPanel **Cron Jobs**, add:
```
* * * * * php /home/USER/public_html/PATH/artisan schedule:run >> /dev/null 2>&1
```

This drives `RunMonitoring`, `ProcessRenewals`, and `CheckTrialExpiry`
via Laravel's scheduler, and also processes the `database` queue
(report generation jobs) since shared hosting can't run a persistent
`queue:work` process.

## 7. Verify

1. Visit `/admin` and log in with one of the passwords from the `seed`
   step — **change it immediately** via the profile page.
2. Visit `/super-admin` the same way for the platform admin account.
3. Generate one test report end-to-end to confirm PDF/PPTX export
   works (DomPDF and PhpPresentation both need the `storage/app/reports`
   directory to be writable).

## After the evidence-model migration ships

The `cmd=migrate` step above already creates the `evidence_items`/
`evidence_assets` tables. Populate them from existing data with:

```
https://yourdomain.com/deploy-tools.php?token=YOUR_TOKEN&cmd=evidence-backfill-dry
https://yourdomain.com/deploy-tools.php?token=YOUR_TOKEN&cmd=evidence-backfill
```

Check the dry-run counts look sane before running the real one. Safe to
run more than once — it's idempotent and never touches or deletes the
legacy `coverage_items` / `coverage_media` / `media_mentions` tables.

## Files that should never end up back in git

- `.env`, `.env.bak` — real credentials
- `storage.zip`, `roote_demo.sql` (if regenerated) — large binaries /
  data dumps, not source
- Any future one-off `fix-*.php` script in `public/` — if
  `deploy-tools.php`'s whitelist doesn't cover something you need, add
  a new whitelisted command to it instead of writing a fresh throwaway
  script. A script that can rewrite arbitrary files or run arbitrary
  SQL against production is exactly how the last incident happened.
