# Deployment: cPanel + MySQL + phpMyAdmin

## 1. Directory layout on the cPanel account

This matters more than usual here, because there is no framework enforcing
where "private" code lives — it's just file placement. Lay the account out
like this:

```
/home/cpaneluser/
├── .env                      <-- copy of .env.example, filled in, chmod 600
├── app/                      <-- everything from this project's app/ folder
│   ├── config/
│   ├── includes/
│   └── database/
├── private_storage/          <-- everything from this project's private_storage/ folder
│   ├── verification_docs/
│   ├── bank_transfer_receipts/
│   ├── message_attachments/
│   └── report_evidence/
└── public_html/               <-- THIS is the web root; point your domain here
    ├── .htaccess
    ├── index.php
    ├── assets/
    ├── uploads/
    └── ...every other .php page
```

`app/`, `private_storage/`, and `.env` sit OUTSIDE `public_html`, so no URL
can ever reach them — this is what makes the private-document rule in §46
("never expose private documents through public URLs") actually hold, rather
than relying on `.htaccess` rules that a misconfiguration could defeat.

If your hosting plan only gives you `public_html` and nothing above it,
create `app/`, `private_storage/`, and `.env` as siblings of `public_html`
inside your home directory using File Manager or SFTP — cPanel accounts
almost always allow this even when only `public_html` is web-served.

## 2. Create the MySQL database

cPanel → MySQL Databases:
1. Create a database, e.g. `cpaneluser_tutordb`.
2. Create a database user with a strong password.
3. Add that user to the database with **All Privileges**.

## 3. Import the schema via phpMyAdmin

cPanel → phpMyAdmin → select your new database → **Import** tab → choose
`app/database/schema.sql` → Go.

This creates every table, plus seeds `platform_settings` (commission
defaults, empty bank details for you to fill in via the Admin settings page
once built) and a starter list of subjects/academic levels. It does **not**
create an Admin account — see step 5.

## 4. Configure environment variables

Copy `.env.example` to `.env`, place it per the layout above, and fill in:
`DB_NAME`/`DB_USER`/`DB_PASS` (from step 2), `APP_URL`, `PAYSTACK_SECRET_KEY`
/`PAYSTACK_PUBLIC_KEY`, and SMTP credentials. `chmod 600 .env` if your
hosting environment supports it.

## 5. Create the first Admin account

Admin accounts are deliberately not created through the public site (§41).
SSH into the server (or use cPanel's Terminal) and run:

```
php app/database/create_admin.php "Your Name" admin@yourdomain.com
```

You'll be prompted for a password. This is the *only* path to an Admin
account — there is no public "become an admin" flow anywhere in the app.

## 6. Point the domain at public_html

In cPanel's domain/subdomain settings, make sure the document root is set to
`public_html` (this is usually the default for the primary domain).

## 7. File permissions

`private_storage/` and its subfolders need to be writable by the PHP
process (typically `750` or `770` depending on your host's user/group
setup — check with your host if uploads fail with a permission error).
`public_html/uploads/` needs the same.

## 8. Enable HTTPS

cPanel → SSL/TLS Status → AutoSSL (or Let's Encrypt, if offered). The
`.htaccess` in `public_html/` already forces HTTP → HTTPS redirects, so the
site will loop or refuse to load correctly until a certificate is active.

## 9. Configure the Paystack webhook

In your Paystack dashboard (Settings → API Keys & Webhooks), set the
webhook URL to:

```
https://yourdomain.com/webhooks/paystack.php
```

This endpoint verifies Paystack's HMAC signature on every request before
processing anything, and re-verifies each transaction against Paystack's
API rather than trusting the webhook payload directly — see
`app/includes/payment_services.php` and `public_html/webhooks/paystack.php`.

## 10. Cron jobs (once Phase 2/3 modules exist)

No background workers are assumed (shared cPanel hosting) — anything
time-based (class reminders, payment reconciliation, cleanup) should be a
PHP CLI script invoked via cPanel's Cron Jobs UI, e.g.:

```
* * * * * php /home/cpaneluser/app/cron/send_class_reminders.php
```

None of these cron scripts exist yet in this pass — flagged here so the
hook point is documented ahead of building them.

## Known constraints of this environment

- No PHP interpreter or network access was available in the environment
  this code was written in, so **none of it has been executed**. Before
  trusting it in production: import the schema, run through the register →
  verify → login → find-a-tutor → contact-teacher → messages flow manually,
  and watch your host's PHP error log (`error_log` calls throughout this
  codebase write there on any unexpected failure).
- `mysqli`/`PDO MySQL` driver must be enabled for your PHP version in
  cPanel's "PHP Selector" / "Select PHP Version" tool — check the
  extension list there if `db()` throws on first use.
