# Deploying Rafif Hotel to cPanel

Step-by-step guide. Everything code-side is already prepared — this is the
server setup work.

## Before you start — requirements

- cPanel with **"Setup Node.js App"** (Passenger). Ask your host if unsure.
- **Node.js 18 or 20** available in that tool. Node 16 or older will crash
  on startup (the app uses global `fetch` and `AbortSignal.timeout`).
- A domain or subdomain with **SSL** (AutoSSL / Let's Encrypt). HTTPS is
  mandatory — the offline mode and "Install app" feature (service worker)
  do not work over plain HTTP.

Recommended: a dedicated subdomain, e.g. `hotel.yourdomain.com`.

## 1. Create the database

1. cPanel → **MySQL Databases** → create database (e.g. `cpuser_rafif`).
2. Create a DB user with a strong password; add it to the database with
   **ALL PRIVILEGES**.
3. Decide: fresh start, or bring your local data?
   - **Bring local data:** on the hotel PC run
     `mysqldump -u root -p rafif_hotel > rafif.sql`
     then import `rafif.sql` via cPanel → phpMyAdmin → Import.
   - **Fresh start:** you'll run migrations + seed in step 4.

## 2. Upload the files

Keep the same folder layout the app expects (backend serves `../frontend/dist`):

```
/home/cpuser/rafifhotel/
├── backend/          (everything except node_modules)
└── frontend/
    └── dist/         (the production build only — not src/)
```

Build the frontend locally first (`npm run build` in `frontend/`), then upload.
Easiest: zip the two folders, upload via File Manager, extract.

## 3. Create the Node.js app

cPanel → **Setup Node.js App** → Create Application:

| Setting            | Value                                   |
|--------------------|-----------------------------------------|
| Node.js version    | 18.x or 20.x                             |
| Application mode   | Production                               |
| Application root   | `rafifhotel/backend`                     |
| Application URL    | your subdomain, `/` (root)               |
| Startup file       | `src/app.js`                             |

Then click **Run NPM Install** (installs from `package.json`).

## 4. Environment variables

In the same Node.js App screen, add these (or create `backend/.env`):

```
NODE_ENV=production
JWT_SECRET=<generate a NEW random 40+ character string — do not reuse the local one>
DB_USER=cpuser_dbuser
DB_PASS=<db password>
DB_NAME=cpuser_rafif
DB_SOCKET=/var/lib/mysql/mysql.sock     # ask your host; some use DB_HOST=localhost instead
ALLOWED_ORIGINS=https://hotel.yourdomain.com
PUBLIC_URL=https://hotel.yourdomain.com
UPLOAD_DIR=/home/cpuser/hotel_uploads   # outside public_html; create the folder
```

If DB_SOCKET doesn't work, remove it and use `DB_HOST=localhost` + `DB_PORT=3306`.

**Fresh-start only:** open the cPanel Terminal (or SSH) and run:

```
cd ~/rafifhotel/backend
npm run migrate
npm run seed
```

(Skip this if you imported your local database — it already has the schema.)

## 5. Start and verify

1. **Restart** the app in the Node.js App screen.
2. Open `https://hotel.yourdomain.com` — you should see the login page.
3. Log in, then **immediately change the default passwords** (Settings →
   admin accounts): `owner/owner123` and `frontdesk/frontdesk123` are public
   knowledge.
4. Verify each of these once:
   - Create a test booking, then cancel it.
   - Open a booking → Print receipt.
   - Guests → a guest → QR upload → scan with a phone on **mobile data**
     (not hotel Wi-Fi) — this proves `PUBLIC_URL` is right.
   - On a staff phone/PC: Chrome → ⋮ → **Install app**.

## 6. Backups (do not skip)

cPanel → **Cron Jobs** → add daily at e.g. 4:00:

```
mysqldump -u cpuser_dbuser -p'DBPASSWORD' cpuser_rafif | gzip > /home/cpuser/backups/rafif-$(date +\%u).sql.gz
```

(`%u` = weekday number, so you keep a rolling 7 days.) Create
`/home/cpuser/backups/` first. Back up `hotel_uploads/` (guest ID documents)
weekly via cPanel Backup or a second cron.

## Updating the app later

1. Locally: make changes, run `npm run build` in `frontend/`.
2. Upload the changed files (`backend/src/...` and/or `frontend/dist/`).
3. If there are new files in `backend/migrations/`, run `npm run migrate`.
4. **Restart** the app in the Node.js App screen.

## Known behavior after moving to cPanel

- **Hotel internet down** → staff devices keep working offline (local data,
  queued writes) but can't see each other's changes until internet returns.
  Guest QR uploads don't work during the outage.
- The exchange-rate auto-refresh needs outbound HTTPS from the server;
  if your host blocks it, rates can still be set manually in Settings.
- Passenger may put the app to sleep when idle; the first request after a
  quiet period takes a few seconds. Rate refresh timers pause while asleep.
