# Deploying MRCU Tracker to Namecheap Stellar (cPanel) — tracker.mrcug.org

This guide takes the tracker from your PC to `https://tracker.mrcug.org` on Namecheap shared hosting.
Allow about 45 minutes the first time. Everything happens in cPanel plus a few commands in the
cPanel **Terminal** (or SSH). No PHP, no server administration.

What you end up with:

- a subdomain `tracker.mrcug.org` served by the Node.js application (Passenger, managed by cPanel);
- a MySQL/MariaDB database holding every project, task, comment, KPI value and account;
- Roy (super admin) and Solomon (admin) able to sign in with their own passwords;
- Roy's ten portfolio projects, the AOP FY2026/27 organisation projects and the KPI catalogue already loaded;
- HTTPS via AutoSSL and a nightly JSON backup.

---

## 0. Before you start

| You need | Where |
|---|---|
| cPanel login for the Stellar account that hosts `mrcug.org` | Namecheap dashboard → Hosting List → *Go to cPanel* |
| The deployment package (`release/mrcu-tracker-2.0.0-YYYY-MM-DD.zip`) | built in step 1 |
| Two strong passwords (12+ characters) for Roy and Solomon | choose them now, share privately |

Node.js requirement: the app needs Node **22.5 or newer**. Namecheap's *Setup Node.js App* offers 22.x and 24.x — pick **22** (or 24). Do not pick 20 or lower.

---

## 1. Build the package on your PC

From `Tracker/asana-clone` in PowerShell:

```bash
npm run package
```

This builds the web client and writes `release/mrcu-tracker-2.0.0-<date>.zip` (and the matching folder).
The zip contains `app.js`, `package.json`, `server/`, `client/dist/`, `.env.example`, `DEPLOYMENT.md` and `README.md` —
no database, no `node_modules`, no passwords.

---

## 2. Create the subdomain

1. cPanel → **Domains** (or **Subdomains** on older cPanel) → *Create a New Domain*.
2. Domain: `tracker.mrcug.org`. Untick *Share document root*; leave the suggested document root
   (e.g. `/home/USER/tracker.mrcug.org`). Submit.
3. DNS: if `mrcug.org` uses Namecheap BasicDNS, the subdomain record is added for you. If DNS is hosted elsewhere,
   add an `A` record `tracker` → your hosting server IP (cPanel → *General Information* → *Shared IP Address*).

`USER` below means your cPanel username (shown top-right in cPanel).

---

## 3. Create the database

1. cPanel → **MySQL® Database Wizard**.
2. Database name: `mrcu_tracker` → cPanel prefixes it: **`USER_mrcu_tracker`**.
3. User: `tracker` with a generated password → **`USER_tracker`**. Save the password somewhere safe.
4. Privileges: tick **ALL PRIVILEGES**. Finish.

---

## 4. Upload the application files

Keep the app **outside** `public_html` so its source is never served as static files.

1. cPanel → **File Manager** → go to `/home/USER` → *+ Folder* → name it `apps` → inside it create `mrcu-tracker`.
2. Open `/home/USER/apps/mrcu-tracker`, click **Upload**, upload the zip.
3. Back in File Manager select the zip → **Extract**. It extracts into a sub-folder named like `mrcu-tracker-2.0.0-<date>`.
   Open that folder, **Select All → Move** to `/home/USER/apps/mrcu-tracker`, then delete the empty sub-folder and the zip.
4. You should now see `app.js`, `package.json`, `server/`, `client/` directly inside `/home/USER/apps/mrcu-tracker`.

---

## 5. Register the Node.js application

1. cPanel → **Setup Node.js App** → **Create Application**.
2. Fill in:

   | Field | Value |
   |---|---|
   | Node.js version | **22.x** (or 24.x) |
   | Application mode | **Production** |
   | Application root | `apps/mrcu-tracker` |
   | Application URL | `tracker.mrcug.org` |
   | Application startup file | `app.js` |

3. **Environment variables** → *Add Variable* for each:

   | Name | Value |
   |---|---|
   | `NODE_ENV` | `production` |
   | `DB_CLIENT` | `mysql` |
   | `DB_HOST` | `localhost` |
   | `DB_NAME` | `USER_mrcu_tracker` |
   | `DB_USER` | `USER_tracker` |
   | `DB_PASSWORD` | the database password from step 3 |
   | `APP_ORIGIN` | `https://tracker.mrcug.org` |
   | `APP_TIMEZONE` | `Africa/Kampala` |

4. Click **Create**. cPanel writes the Passenger configuration for the subdomain automatically.
5. On the application page click **Run NPM Install** (installs `express`, `helmet`, `mysql2`…). Wait for the green tick.
   If the button is missing, do it from the Terminal (step 6) with `npm install --omit=dev`.

Do **not** click *Start* yet: the app refuses to start in production until real passwords exist (step 6).

---

## 6. Provision the MRCU workspace (first run only)

Open cPanel → **Terminal** (or connect over SSH). The Node.js app page shows a line like
`source /home/USER/nodevenv/apps/mrcu-tracker/22/bin/activate && cd /home/USER/apps/mrcu-tracker` — copy and run it
so `node` is the right version. Then:

```bash
cat > .env <<'EOF'
NODE_ENV=production
DB_CLIENT=mysql
DB_HOST=localhost
DB_NAME=USER_mrcu_tracker
DB_USER=USER_tracker
DB_PASSWORD=the-database-password
APP_TIMEZONE=Africa/Kampala
EOF
chmod 600 .env
```

The `.env` file lets the command-line tools (seed, backup, restore) reach the database; the running app uses the
variables from the cPanel screen. Now create the accounts and load the workspace:

```bash
MRCU_ROY_PASSWORD='choose-roy-password' MRCU_SOLOMON_PASSWORD='choose-solomon-password' npm run seed:mrcu
```

Expected output ends with `MRCU workspace ready. { users: 2, teams: 2, tags: 9, roles: 7, indicators: 117, projects: 13, tasks: 125 … }`.
The seed is safe to re-run later (it only adds what is missing); never re-run it with `--purge-demo` on the live database.

Without a Terminal: add `MRCU_ROY_PASSWORD` and `MRCU_SOLOMON_PASSWORD` temporarily as environment variables on the
Node.js app page, click **Run JS script** → `seed:mrcu`, then **remove both variables** and save.

---

## 7. Start and check

1. Node.js app page → **Start** (or **Restart**).
2. Open `https://tracker.mrcug.org/api/health` → `{"ok":true,"version":"2.0.0"}`.
3. Open `https://tracker.mrcug.org`, sign in as `roy.asiku@mildmay.or.ug`, go to *Profile* (bottom-left) and change
   your password. Ask Solomon to do the same on first sign-in.
4. **HTTPS**: cPanel → **SSL/TLS Status** → tick `tracker.mrcug.org` → *Run AutoSSL*. Once issued, cPanel →
   **Domains** → toggle *Force HTTPS Redirect* for the subdomain.

If the app shows an error page: Node.js app page → the log is `stderr.log` in the application root (File Manager → *View*).
The two common messages:

- `Known demo passwords remain` — an account still has a test password. Run
  `MRCU_ROY_PASSWORD='…' MRCU_SOLOMON_PASSWORD='…' npm run seed:mrcu -- --reset-passwords`.
- `Set DB_NAME, DB_USER and DB_PASSWORD` or `Access denied` — an environment variable is missing or wrong on the Node.js app page. Fix, save, **Restart**.

---

## 8. Backups (do this before letting anyone else in)

Two independent copies:

1. **Nightly JSON export** — cPanel → **Cron Jobs** → add, *Once Per Day*, command (one line; replace USER and the Node path shown on your app page):

   ```bash
   cd /home/USER/apps/mrcu-tracker && /home/USER/nodevenv/apps/mrcu-tracker/22/bin/node server/src/transfer.js backup /home/USER/backups/mrcu-tracker-$(date +\%F).json >> /home/USER/backups/backup.log 2>&1
   ```

   Create `/home/USER/backups` first (File Manager). Each file is a complete copy of every table; the importer restores it
   into an empty database with `npm run restore -- /home/USER/backups/<file>.json`. Download a copy to the office PC monthly.
2. **cPanel backup** — cPanel → **Backup** → *Download a MySQL Database Backup* → `USER_mrcu_tracker`, whenever you make big changes.

Deleted tasks and projects sit in the in-app **Trash** for 30 days before they are purged, so most mistakes need no backup at all.

---

## 9. Updating the tracker later

1. On the PC: make the changes, run `npm test` (in `asana-clone/server`) and `npm run package`.
2. cPanel File Manager: upload the new zip into `/home/USER/apps/mrcu-tracker`, **Extract**, move the contents over the old
   files (overwrite when asked), delete the zip and the extracted sub-folder. `.env` and the database are untouched.
3. If `package.json` dependencies changed: Node.js app page → **Run NPM Install**.
4. Node.js app page → **Restart**. Database schema changes apply themselves on start-up.

---

## 10. Moving data from the laptop's SQLite file (optional)

If you have been using the tracker locally and want that data online instead of the seeded workspace:

1. Do this **before** step 6 (the destination database must be empty), or drop and recreate the database.
2. Upload `server/data/taskflow.db` to `/home/USER/apps/mrcu-tracker/server/data/`.
3. In the Terminal (with the virtual environment activated and `.env` in place):

   ```bash
   npm run migrate:sqlite -- /home/USER/apps/mrcu-tracker/server/data/taskflow.db
   ```

4. Delete the uploaded `.db` file afterwards. Then run `npm run seed:mrcu` (without flags) to add anything missing.

---

## 11. Security checklist

- [ ] Roy and Solomon changed the passwords they were given.
- [ ] `MRCU_ROY_PASSWORD` / `MRCU_SOLOMON_PASSWORD` removed from the Node.js app environment variables (if used there).
- [ ] `.env` has permission `600` and lives outside `public_html`.
- [ ] `Force HTTPS Redirect` is on for `tracker.mrcug.org`.
- [ ] Nightly backup cron job runs (check `backup.log` after the first night).
- [ ] New staff are added from **People & teams → Add person** with a temporary password, then given a KPI role under **KPI setup** and added to the right team.

Sign-in is rate-limited (30 attempts per 15 minutes per address), sessions expire after 12 hours, passwords are scrypt-hashed
and deactivated accounts cannot sign in.

---

## Runs locally as well

```bash
npm run install:all
npm run build
npm --prefix server start        # http://localhost:4000, SQLite file in server/data/
```

For development with hot reload: `npm run dev` (client on http://localhost:5173, API on 4000).
