# Deploying LoanFlow to Namecheap Stellar (cPanel)

Target: subdomain `loans.loansystemph.com`, cPanel account `loanpelm`
(`/home/loanpelm`), database via cPanel's PostgreSQL Database Wizard.

Because the app is built on Windows but the server is Linux, **both
`npm install` and `npm run build` must run on the server itself** (via SSH or
cPanel's "Manage Shell") — not locally. Native binaries (Prisma's query
engine, Next's SWC compiler, Tailwind's lightningcss) are OS-specific, and
npm only resolves the correct ones when it runs on the target OS.

## 1. Create the subdomain

cPanel → **Domains** → **Create A New Domain** → enter `loans.loansystemph.com`.
Leave/accept the default document root it suggests (something like
`/home/loanpelm/loans.loansystemph.com`) — this docroot won't actually serve
the app directly; Setup Node.js App reconfigures routing for it in step 4.

## 2. Create the PostgreSQL database

cPanel → **PostgreSQL Database Wizard**:
1. **Database name**: e.g. `loanapp` (cPanel will prefix it, e.g.
   `loanpelm_loanapp` — note the exact prefixed name it shows you).
2. **Username**: e.g. `loanapp` (again gets prefixed, e.g. `loanpelm_loanapp`)
   + a generated strong password (save it).
3. **Privileges**: grant **ALL PRIVILEGES** on that database to that user.

Your `DATABASE_URL` will be:
```
postgresql://<prefixed_user>:<password>@localhost:5432/<prefixed_db>
```
(host is `localhost` since the app and DB are on the same account/server.)

## 3. Upload the app

Upload `loan-app-deploy.zip` via cPanel **File Manager** into a folder
**outside `public_html`** — e.g. `/home/loanpelm/loan-app`. Extract it there.
(This is a hard requirement from Namecheap's own docs: the Node.js app's
files must not live inside `public_html`.)

## 4. Setup Node.js App

cPanel → **Setup Node.js App** → **Create Application**:
- **Node.js version**: the newest 20.x or 22.x LTS available (this app
  requires Node ≥20.9.0 — check with `node --version` once you're in the
  app's virtualenv if unsure which the selector installed).
- **Application mode**: Production
- **Application root**: `loan-app` (relative to `/home/loanpelm`)
- **Application URL**: `loans.loansystemph.com`
- **Application startup file**: `server.js`
- **Environment variables** (click "Add Variable" for each):
  - `DATABASE_URL` = the connection string from step 2
  - `AUTH_SECRET` = a fresh random secret — generate one, don't reuse the
    dev one. E.g. run `openssl rand -hex 32` in any shell.
  - `NEXTAUTH_URL` = `https://loans.loansystemph.com`
  - `AUTH_TRUST_HOST` = `true` (defensive — cPanel's Passenger integration
    proxies through Apache, and this avoids Auth.js's `UntrustedHost` check
    misfiring if the forwarded Host header isn't exactly what it expects)

Click **Create**. The page will show a command like:
```
source /home/loanpelm/nodevenv/loan-app/20/bin/activate && cd /home/loanpelm/loan-app
```
Copy that — you'll run it first in every shell session below.

## 5. Install, migrate, build (via SSH or cPanel's "Manage Shell")

If SSH isn't enabled yet: cPanel → **Manage Shell** works without it (in-browser
terminal), or request SSH access under cPanel → Security → SSH Access.

```bash
source /home/loanpelm/nodevenv/loan-app/20/bin/activate && cd /home/loanpelm/loan-app

npm install
npx prisma generate
npx prisma migrate deploy   # applies existing migrations — NOT `migrate dev`
npm run build

# Create the first real admin login (safe to re-run; upserts by email):
node scripts/create-admin.js "Your Name" "you@loansystemph.com" "a-strong-password"
```

Then go back to **Setup Node.js App** in cPanel and click **Restart** (or
**Start App** if it's not running yet).

## 6. SSL

cPanel → **SSL/TLS Status** (or the **Namecheap SSL** tool) → run AutoSSL for
`loans.loansystemph.com` once it's resolving. Free Let's Encrypt cert,
usually issues within a few minutes of the subdomain going live.

## 7. Verify

Visit `https://loans.loansystemph.com/login` and sign in with the admin
account you just created. From there, use the **Products** screen to create
your real loan products (the demo seed data — Quick Cash Flat, Business Loan
Diminishing, sample borrowers — was deliberately NOT run against this
database; `prisma/seed.ts` is dev-only).

## Redeploying after a code change

1. Locally: `git add -A && git commit -m "..."`, then
   `git archive --format=zip -o loan-app-deploy.zip HEAD`.
2. Upload the new zip, extract over the existing `loan-app` folder in File
   Manager (overwrite).
3. Back in the SSH/Manage Shell session (re-run the `source .../activate`
   line first): `npm install` (only if package.json changed), and **if the
   Prisma schema changed**, `npx prisma migrate deploy` again.
4. `npm run build`.
5. Restart the app in Setup Node.js App.

**If a schema migration doesn't seem to take effect after restart**, this
project has hit a stale-Turbopack/stale-build-cache issue before locally —
on the server the equivalent fix is `rm -rf .next` then `npm run build`
again before restarting.

## Known constraints of this hosting tier

- Shared LVE limits observed on this account: 2GB RAM, 200% CPU, 30 entry
  processes. `next build` for this app builds fine within that in local
  testing; if a build here times out or gets OOM-killed, the fallback is
  building on a Linux CI runner (e.g. GitHub Actions) and uploading the
  resulting `.next` + a server-installed `node_modules` instead.
- cPanel's built-in PostgreSQL was reported elsewhere as a very old v10.23
  on some Namecheap tiers — Prisma is compatible with it, but you won't get
  upstream security patches for Postgres itself. If that becomes a concern
  later, migrating `DATABASE_URL` to an external managed Postgres (e.g.
  Neon) requires no schema changes — just a connection string swap.
