# Deploying `pharmacy-ui` on Ubuntu

The web dashboard is served from the Ubuntu box at `159.223.195.13`, the same host as the
API (`https://pharmacy-api.devke.co.ke/api`) and the website that hosts the desktop
binaries. Deploying is: pull, install, **build**, restart.

Unlike the API, the UI is **compiled at build time** — nothing takes effect until
`npm run build` succeeds and the server restarts. A `git pull` on its own changes nothing
a visitor can see.

## 0. One-time: find out how the UI is served

There are two possible setups. Check which one this server uses and write the answer in
here so nobody has to guess again.

```bash
ssh root@159.223.195.13

# where is the code?
ls -d /var/www/* /opt/* /root/* 2>/dev/null | grep -i pharmacy

# is a Node process serving it?
pm2 list                                 # look for pharmacy-ui / next
systemctl list-units --type=service | grep -i pharmacy

# or is nginx serving plain files?
grep -rn "root\|proxy_pass" /etc/nginx/sites-enabled/ | grep -i pharma
```

- **Node server** (`next start`, usually port 3000, nginx `proxy_pass` in front) →
  use §2a. This is the normal setup.
- **Static files** (nginx `root /var/www/.../out`) → use §2b.

Fill in: app directory `<APP_DIR>`, process `pharmacy-ui` (PM2) or `pharmacy-ui.service`.

## 1. Pull and build

```bash
ssh root@159.223.195.13
cd <APP_DIR>

git status            # must be clean — see "Local changes" below
git pull origin main

npm ci                # `npm install` if there is no package-lock.json
npm run build
```

**If the build fails, stop.** The old build is still being served, so the site stays up —
do not restart until `npm run build` exits clean. Next.js needs ~1GB of free RAM to build;
if it is killed with no error, that is why (`free -m` to check).

## 2a. Restart (Node server)

```bash
pm2 restart pharmacy-ui
pm2 logs pharmacy-ui --lines 50       # Ctrl-C to exit
```

or

```bash
systemctl restart pharmacy-ui
systemctl status pharmacy-ui --no-pager
```

## 2b. Publish (static build)

```bash
NEXT_PUBLIC_EXPORT=true npm run build     # writes ./out
rsync -a --delete out/ /var/www/<site>/
```

No restart needed — nginx serves the new files immediately. `--delete` removes files that
no longer exist in the build; make sure the target directory holds *only* the exported
site before you use it.

## 3. Verify

```bash
# on the server, if a Node process serves it
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost:3000/login

# from anywhere
curl -s -o /dev/null -w "HTTP %{http_code}\n" https://pharmapos.devke.co.ke/login
```

Then open the site, log in, and load the dashboard — that single page exercises the API
base URL, auth, and the data endpoints at once. **Hard-refresh** (Ctrl-Shift-R): Next.js
serves hashed asset filenames, but an old HTML page held in the browser cache will ask for
chunks that no longer exist and the page will look broken when the deploy is fine.

## The API base URL — the one thing that bites

`getApiBase()` in `lib/api.ts` resolves the API address **per request**, in this order:

1. `localStorage.api_base`
2. `window.electronAPI.apiBase` (desktop only)
3. `NEXT_PUBLIC_API_BASE` — **baked in at build time**
4. `https://pharmacy-api.devke.co.ke/api` (fallback when nothing is set)

So an unset environment behaves correctly in production. The hazards:

- **`NEXT_PUBLIC_*` values are inlined into the build.** Changing one means a full rebuild,
  not a restart.
- **Never run the production build with `NEXT_PUBLIC_API_BASE` exported in your shell.** It
  silently ships a dev or LAN address to every user. If you have ever exported it in that
  SSH session, open a new one before building.
- `.env.development.local` holds the local dev override and is loaded by `next dev` **only** —
  it cannot leak into a build. That is deliberate; don't rename it to `.env.local`.
- If one browser is hitting the wrong server, it is almost certainly a stale
  `localStorage.api_base` on that machine, not the deploy. Clear it in devtools.

## Deploying UI and API together

A change spanning both repos needs both deployed, API first — the UI calling an endpoint
that does not exist yet fails loudly, while an API with an extra field the UI ignores is
harmless. See `../pharmacy-api/DEPLOY.md`.

A change to a *shipped desktop* app is a third step: `pharmacy-desktop` packages a static
export of this repo, so desktop users keep the old UI until a new binary is built and
uploaded (`../pharmacy-desktop/README.md`).

## Local changes on the server

```bash
git diff                       # see what it is
git stash                      # park it, then pull
# or, once you're sure it's disposable:
git checkout -- .
```

## Rolling back

```bash
git log --oneline -10
git checkout <good-sha>
npm ci && npm run build
pm2 restart pharmacy-ui        # or: systemctl restart pharmacy-ui
```

Then `git checkout main` once the fix is pushed. The UI holds no state of its own — auth
lives in the browser's `localStorage` — so a rollback is safe and needs no database work.

## If the build gets strange

A stale Next.js cache after a dependency change produces errors that make no sense against
the source:

```bash
rm -rf .next node_modules
npm ci
npm run build
```
