# Deploy BETSLIP PRO API on cPanel (api.liwaletech.co.tz)

This guide covers shared hosting with **Setup Node.js App** (Passenger) and **PostgreSQL**.

Production URL: [https://api.liwaletech.co.tz/](https://api.liwaletech.co.tz/)

## 1. Prepare files locally

From the `backend` folder, create a ZIP of the app **excluding** `node_modules` and local secrets:

- Include: `app.js`, `package.json`, `package-lock.json`, `.sequelizerc`, `src/`, `scripts/`, `docs/`
- Exclude: `node_modules/`, `.env` (set env vars in cPanel instead)

## 2. Create PostgreSQL database in cPanel

1. Open **PostgreSQL Databases**.
2. Create a database (note the full name; cPanel often prefixes with your username).
3. Create a database user with a strong password.
4. Add the user to the database with **ALL PRIVILEGES**.

## 3. Setup Node.js App

1. Open **Setup Node.js App**.
2. Create application:
   - **Node.js version:** 18+ (prefer 20 LTS)
   - **Application mode:** Production
   - **Application root:** folder that will contain `package.json` and `app.js` (e.g. `api.liwaletech.co.tz` or `betslip-api`)
   - **Application URL:** `api.liwaletech.co.tz` with path `/`
   - **Application startup file:** `app.js`
3. Save / Create.

## 4. Upload code

Upload and extract the ZIP into the **application root** so that:

```
application-root/
  app.js
  package.json
  .sequelizerc
  src/
  ...
```

## 5. Environment variables

In **Setup Node.js App → Environment variables** (or equivalent), set:

| Variable | Example |
|----------|---------|
| `NODE_ENV` | `production` |
| `APP_URL` | `https://api.liwaletech.co.tz` |
| `DB_HOST` | `127.0.0.1` |
| `DB_PORT` | `5432` |
| `DB_NAME` | your cPanel Postgres DB name |
| `DB_USER` | your cPanel Postgres user |
| `DB_PASSWORD` | your DB password |
| `JWT_SECRET` | long random string |
| `JWT_EXPIRES_IN` | `7d` |
| `ADMIN_EMAIL` | `admin@betslip.pro` |
| `ADMIN_PASSWORD` | strong admin password for seeder |
| `THESPORTSDB_API_KEY` | `123` (free public key; replace if you have your own) |
| `CLICKPESA_CLIENT_ID` | from ClickPesa / shopNew |
| `CLICKPESA_API_KEY` | from ClickPesa / shopNew |
| `CLICKPESA_CHECKSUM_KEY` | optional; API key used if empty |
| `CLICKPESA_APP_NAME` | `BETSLIP PRO` |
| `ENABLE_TEST_PAYMENT` | omit or `false` in production |

In the ClickPesa dashboard, set the webhook URL to:

```
https://api.liwaletech.co.tz/api/webhooks/clickpesa
```

Do **not** upload a production `.env` with local `qwerty` credentials. Prefer the cPanel env UI.

If your host requires a `.env` file on disk, create one in the application root with the same values (never commit it).

## 6. Install dependencies

In Setup Node.js App, click **Run NPM Install**, or open Terminal/SSH and use the virtual-env command shown by cPanel (example shape):

```bash
source /home/USERNAME/nodevenv/APP_ROOT/20/bin/activate
cd ~/APP_ROOT
npm install --production
```

`sequelize-cli` is a devDependency. For migrate/seed on the server either:

- run `npm install` (including devDependencies) once, or
- `npm install --save-dev sequelize-cli` temporarily, or
- `npx sequelize-cli` after a full install

Recommended for first deploy:

```bash
npm install
```

## 7. Run migrations and seed

Still inside the Node virtual environment and application root:

```bash
npx sequelize-cli db:migrate
npx sequelize-cli db:seed:all
```

### If migrate failed earlier (pgcrypto / users missing)

Shared cPanel Postgres often has **no pgcrypto**. The current migration does not need that extension.

1. Re-upload the fixed file: `src/migrations/20260726100000-create-all-tables.js`
2. Clean the failed migrate state, then migrate again:

```bash
source /home/liwalete/nodevenv/api/24/bin/activate
cd /home/liwalete/api

# Option A — if SequelizeMeta exists but tables are incomplete:
npx sequelize-cli db:migrate:undo:all

# Option B — if undo fails: in phpPgAdmin / psql, drop and recreate public schema
# (or drop all tables + DELETE FROM "SequelizeMeta";)

npx sequelize-cli db:migrate
npx sequelize-cli db:seed:all
```

Do **not** run seed until migrate succeeds.

## 8. Restart the app

In **Setup Node.js App**, click **Restart**.

## 9. Verify

- Health: [https://api.liwaletech.co.tz/health](https://api.liwaletech.co.tz/health)
- Swagger: [https://api.liwaletech.co.tz/api/docs](https://api.liwaletech.co.tz/api/docs)
- Login with seeded admin, then change the password

### Seed accounts (default seeder)

| Role | Email | Password |
|------|-------|----------|
| Admin | `admin@betslip.pro` | value of `ADMIN_PASSWORD` (default `Admin@12345`) |
| Bettor | `bettor@betslip.pro` | `Bettor@123` |
| Tipster | `tipster@betslip.pro` | `Tipster@123` |

## Troubleshooting

| Symptom | Check |
|---------|--------|
| 503 / app failed to start | Passenger logs; DB credentials; startup file is `app.js` |
| Cannot connect to DB | `DB_HOST`/`DB_NAME`/`DB_USER`/`DB_PASSWORD`; user privileges |
| `pgcrypto` / `gen_random_uuid` migrate error | Upload fixed migration (no pgcrypto); undo/clean SequelizeMeta; re-migrate |
| `relation "users" does not exist` on seed | First migration failed; fix migrate before seeding |
| Swagger empty paths | Confirm `src/routes` uploaded; restart after deploy |
| Old code still running | Restart Node app; confirm files landed in application root |
| Port errors | Under Passenger do not hardcode a public port; `app.js` uses `listen('passenger')` |
| `npm: command not found` | `source ~/nodevenv/api/24/bin/activate` first |
| CloudLinux `node_modules` error | Delete uploaded `node_modules` folder; use Run NPM Install |

## SSL

Enable AutoSSL / Force HTTPS for `api.liwaletech.co.tz` in cPanel, and set:

```
APP_URL=https://api.liwaletech.co.tz
```

Then **Restart** the Node app. Swagger Try it out must use HTTPS to avoid Mixed Content errors when docs are opened over HTTPS.
