﻿# cPanel Deployment Guide

## Directory structure on the server

Upload the **entire project** to a directory **outside** `public_html`, then point
your domain's document root at the `public/` subfolder.

```
/home/USERNAME/
├── copyedge/             ← upload everything here (no spaces in the name)
│   ├── public/           ← set this as the domain's document root
│   ├── src/
│   ├── database/
│   ├── logs/
│   ├── tmp/
│   ├── cron/
│   └── .env
└── public_html/          ← leave untouched (or unused)
```

> **Why?** Keeping `src/`, `database/`, `.env`, `logs/`, and `tmp/` above the
> web root means they can never be served directly to a browser, even if
> `.htaccess` rules fail. Each of those directories also has its own
> `.htaccess` with `Require all denied` as a belt-and-suspenders measure.

---

## Step-by-step

### 1. Upload files

Use cPanel File Manager or SFTP/FTP. Upload the **entire project folder** to:

```
/home/USERNAME/copyedge/
```

> Use a name with **no spaces** — shell commands break on paths with spaces.

### 2. Point your domain to `public/`

In cPanel → **Domains** (or **Addon Domains / Subdomains**), set the document
root to:

```
/home/USERNAME/copyedge/public
```

### 3. Set file permissions

Run these in cPanel → **Terminal** (or SSH):

```bash
# Project root and key directories
chmod 755 /home/USERNAME/copyedge
chmod 755 /home/USERNAME/copyedge/public
chmod 755 /home/USERNAME/copyedge/src
chmod 755 /home/USERNAME/copyedge/database
chmod 755 /home/USERNAME/copyedge/logs
chmod 755 /home/USERNAME/copyedge/tmp
chmod 755 /home/USERNAME/copyedge/tmp/rate_limits

# Pre-create writable files so chmod doesn't fail
touch /home/USERNAME/copyedge/logs/app.log
chmod 664 /home/USERNAME/copyedge/logs/app.log

# The database auto-creates on first request; make the directory writable
chmod 775 /home/USERNAME/copyedge/database
```

> The SQLite database (`database/platform.db`) is created automatically on the
> first HTTP request — no manual step needed. Just ensure `database/` is
> writable (`chmod 775` or `chmod 777` if your host requires it).

### 4. Set PHP version

In cPanel → **MultiPHP Manager**, select **PHP 8.1** (or 8.2) for your domain.

The project requires PHP 8.0+ (`pdo_sqlite` and `curl` extensions must be
enabled — both are on by default on virtually every cPanel host).

### 5. Edit `.env`

Open `/home/USERNAME/copyedge/.env` and fill in:

```
FINNHUB_API_KEY=your_real_key_here
APP_ENV=production
```

Get a free Finnhub API key at https://finnhub.io

### 6. Seed the admin account

Run once via cPanel → **Terminal** (or SSH):

```bash
cd /home/USERNAME/copyedge
php database/seed_admin.php
```

Default credentials created: `admin@copyedge.com` / `Admin@123456`
**Change the password immediately** after your first login at `/admin/login.php`.

### 7. (Optional) Seed demo data

```bash
php database/seed_performance.php
```

Or use the admin panel → **Demo** page to generate data via the browser.

---

## Automatic background jobs — no cron needed

The platform includes a **Poor Man's Cron** that triggers automatically on
every HTTP request (after the response is already sent to the browser — users
experience zero extra latency).

Two jobs run automatically:

| Job | Interval | What it does |
|-----|----------|--------------|
| `fetch_market_data` | every 60s | Fetches live stock prices from Finnhub; purges old cache rows |
| `run_simulation` | every 60s (+30s offset) | Opens/closes positions, recalculates ROI, updates allocations |

The state is tracked in `tmp/cron_state.json`. No cPanel cron setup required.

> **If you also want a real cron** (for extra reliability on low-traffic sites),
> add this in cPanel → **Cron Jobs** — it's safe to run alongside PoorManCron:
> ```
> * * * * *  /usr/local/bin/php /home/USERNAME/copyedge/cron/run_simulation.php >> /dev/null 2>&1
> * * * * *  /usr/local/bin/php /home/USERNAME/copyedge/cron/fetch_market_data.php >> /dev/null 2>&1
> ```

---

## PHP-FPM vs mod_php

Modern cPanel hosts use **PHP-FPM** by default. The project includes:

- `public/.htaccess` — PHP settings for mod_php / CGI (all PHP versions)
- `public/.user.ini` — PHP settings for PHP-FPM (picked up automatically)

Both set the same security configuration, so the app works correctly in either
environment.

---

## Troubleshooting

| Symptom | Fix |
|---------|-----|
| White screen / HTTP 500 | Check `logs/app.log`; verify directory permissions |
| "Database not found" | Ensure `database/` is writable (`chmod 775`) |
| Prices never update | Add your Finnhub API key to `.env` |
| Simulation never runs | Visit a few pages to trigger PoorManCron, or add real cron |
| Session keeps expiring | Ensure `.user.ini` was uploaded and PHP-FPM reloaded (wait 5 min) |
| CSS/JS not loading | Confirm document root points to `public/`, not the project root |
| `display_errors` still on | PHP-FPM ignores `.htaccess` php_flag; `.user.ini` handles it — wait 5 min for cache |
| HTTPS redirect loop | Check your SSL certificate is active in cPanel → SSL/TLS |
| `session.cookie_samesite` error on old PHP | Upgrade to PHP 8.0+ in cPanel MultiPHP Manager |
