# 2026-10-17 — Deployment prep (v5)

## Context
CEO asked whether the app is "ready for loading into server" and then to prepare
the files to upload. Target confirmed as **cPanel shared hosting**, secrets via a
non-committed `config/config.local.php`.

## Readiness review (before changes)
Code was fine; **configuration** was the gap:
- Secrets only reachable via env vars that `start.sh` sets locally — absent under
  Apache/PHP-FPM, so DB connect would use empty password / `root` / default DB.
- cPanel DB name/user are prefixed and differ from local defaults.
- No SSH assumed → CLI `install/install.php` can't be run the usual way, and both
  `schema.sql`/`seed.sql` hard-code `USE \`studentorbit\``.
- No production error suppression; bare `session_start()` (no Secure/HttpOnly).
- Good news: all asset/link paths are **relative** and reset uses an emailed OTP
  (no hardcoded `localhost` URL), so the app is URL-portable.

## Decisions
- **Override file over env vars** on the server: simplest for shared hosting;
  deep-merged in `config.php`; example committed, real file git-ignored.
- **Keep one SQL source**: the web installer strips `CREATE DATABASE`/`USE` at
  runtime instead of maintaining a separate cPanel schema file.
- **Token-guarded web installer** (`public/setup.php`) rather than requiring SSH;
  `hash_equals` on `install_token`, seeding opt-in, delete-after instructions.
- **Defense in depth** with deny-all `.htaccess` in `config/ src/ install/` in
  case docroot can't be set to `public/`.

## Open / follow-ups
- Upload + run installer on the real host (needs `.ftp.env` + live DB).
- **Rotate** chat-shared DB/mail passwords, then update `config.local.php`.
- Consider removing the now-redundant plaintext-fallback note once all secrets
  live in `config.local.php`.
