# Hosting / Go-Live Guide

## Recommended cPanel deployment
- Public web root: `public/` only.
- Keep `app/`, `config/`, `database/`, `scripts/`, `docs/`, and `.env` outside the public web root.
- Create a MySQL database and user; import `database/schema.sql`.
- Copy `.env.example` to `.env` and fill real credentials.
- Create `PRIVATE_STORAGE_PATH` outside public_html and make it writable by PHP.
- Point `letstalkipdaphne.com` to the hosting server only if you can still prevent origin bypass; otherwise use Cloudflare Tunnel.

## PHP
Use PHP 8.1+ (8.2/8.3 recommended), PDO MySQL, OpenSSL, mbstring and cURL.

## Cloudflare
1. Add the `.com` domain to Cloudflare.
2. Create a Self-hosted Access application for the apex hostname. Leave path blank so the entire `.com` is covered.
3. Add an Allow policy with exact approved emails.
4. Configure One-time PIN as the login method. Do NOT use unrestricted OTP as the Include rule.
5. Prefer Cloudflare Tunnel so the origin is not directly exposed.
6. Enable Full (strict) SSL.
7. Ensure the webhook `/api/paystack/webhook.php` is reachable publicly by Paystack and is NOT behind client authentication.

## Paystack
- Use live secret/public keys only on production.
- Secret key exists only in `.env`/server environment.
- Configure the Paystack webhook to `https://letstalkipdaphne.com/api/paystack/webhook.php` if your Cloudflare rules allow that path, otherwise use a separate public webhook hostname.
- Never protect the webhook with Cloudflare Access.
- Verify payment server-side before marking an order paid.

## Cloudflare policy order
- Protected apex application: Allow exact approved client/admin emails.
- Public endpoint applications: `/api/paystack/webhook.php` → Bypass Everyone; `/invite.php` → Bypass Everyone. Keep these paths extremely narrow. Cloudflare documents Bypass specifically for webhook/public endpoints, but notes that Bypass removes Access enforcement/logging for that traffic.

## Email
The package uses PHP `mail()` by default for invitations. On shared hosting this may be unreliable. Configure the host's authenticated SMTP or replace `send_mail()` with a transactional provider before launch.

## Cron
Recommended daily cron: expire clients whose `access_expires_at` is past, and optionally purge old unused invitation tokens.

## Launch checklist
- HTTPS works.
- Cloudflare Access blocks unknown email.
- Approved email receives OTP.
- Approved client reaches dashboard.
- Revoked/expired client is rejected.
- Admin login works and is protected.
- Paystack test payment verifies.
- Webhook returns HTTP 200 to valid Paystack calls.
- Documents are not directly public.
- `.env` cannot be downloaded.
- `public/` is the only document root.
- No staging site is publicly exposed.
