# Intranet deployment (local network / LAN)

Use this guide when the clinic should be reachable **only inside your office or hospital LAN** (no public internet required). Phones, tablets, and other PCs on the same Wi‑Fi or Ethernet can open the web app using the **server computer’s LAN IP address** (for example `http://192.168.1.50`).

For internet-facing hosting (domain name, HTTPS, public cloud), use the main [README](../README.md) production checklist instead.

---

## How it works

| Role | What it does |
|------|----------------|
| **Server PC** | Runs MySQL, Laravel API, and serves the built Vue app (`frontend/dist`) |
| **Other devices** | Browser → `http://<server-lan-ip>/` (or your Apache hostname if DNS exists on the LAN) |
| **Mobile app** | `EXPO_PUBLIC_API_URL=http://<server-lan-ip>/api` (or Apache proxy URL) |

The API must listen on **all interfaces** (`0.0.0.0`), not only `127.0.0.1`, when you use `php artisan serve`. Apache/Nginx on port 80 is often easier for intranet because you do not expose port 8000 on the firewall.

---

## Before you start

1. **One stable server machine** — desktop or small server, always on during clinic hours.
2. **Static LAN IP (recommended)** — reserve an IP in your router (DHCP reservation) for the server, e.g. `192.168.1.50`.
3. **Empty MySQL database** — same as internet install (`online_clinic`).
4. **Firewall** — allow inbound **TCP 80** (Apache) and/or **TCP 8000** (if using `artisan serve` only).
5. **Same network** — clients must be on the same VLAN/Wi‑Fi; guest Wi‑Fi isolation blocks access.

---

## Quick path (installation wizard)

1. Clone or copy the project to the server (e.g. `D:\www\online-clinic` or `/var/www/online-clinic`).
2. Run bootstrap: `scripts\install.bat` (Windows) or `bash scripts/install.sh` (Linux/macOS).
3. Start API for LAN: `scripts\intranet\start-api-intranet.bat` or `bash scripts/intranet/start-api-intranet.sh`.
4. Open the setup wizard from the **server browser** first:
   - Apache: `http://clinic-frontend.localdev/setup/` or `http://<LAN-IP>/setup/`
   - Dev: `http://localhost:5173/setup/`
5. On **Site & URLs**, choose **Intranet (local network only)**.
6. Enter your server **LAN IP** (wizard can suggest addresses).
7. Complete database, admins, email, and mobile URL (`http://<LAN-IP>/api`).
8. After install, open from another device: `http://<LAN-IP>/` (same URL you set as **Web app URL**).

---

## Step-by-step by operating system

### A. Get the server LAN IP address

**Windows (Command Prompt or PowerShell)**

```bat
ipconfig
```

Use the **IPv4 Address** of the active adapter (Ethernet or Wi‑Fi), e.g. `192.168.1.50`. Ignore `127.0.0.1`.

**Linux**

```bash
hostname -I | awk '{print $1}'
# or
ip -4 addr show scope global
```

**macOS**

```bash
ipconfig getifaddr en0
# Wi‑Fi — use en1 if en0 is empty
```

Write this IP down as `LAN_IP`.

---

### B. Install source on the server

**1. Prerequisites**

- PHP 8.3+, Composer, Node 18+, MySQL 8+ (see [README](../README.md#system-requirements)).
- Git (optional) to clone: `git clone <repo-url> online-clinic`

**2. Create database**

```sql
CREATE DATABASE online_clinic CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```

**3. Bootstrap project**

| OS | Command |
|----|---------|
| Windows | `scripts\install.bat` |
| Linux / macOS | `bash scripts/install.sh` |

**4. Start API bound to LAN (required for `artisan serve` intranet mode)**

| OS | Command |
|----|---------|
| Windows | `scripts\intranet\start-api-intranet.bat` |
| Linux / macOS | `bash scripts/intranet/start-api-intranet.sh` |

This sets `CLINIC_API_HOST=0.0.0.0` so other PCs can reach port `8000`.

Verify from another PC: `http://LAN_IP:8000/api/setup/status` should return JSON.

---

### C. Serve the web app to the LAN

Choose **one** approach.

#### Option 1 — Apache / Nginx on port 80 (recommended for intranet)

Best for clinic staff: one URL, no `:8000` in the address.

**Windows (XAMPP)**

1. Edit `C:\Windows\System32\drivers\etc\hosts` on the **server only** (optional if using IP only):
   ```
   127.0.0.1  clinic-frontend.localdev
   127.0.0.1  clinic-backend.localdev
   ```
2. Apply vhosts: `scripts\apache\apply-xampp-vhost.bat` (adjust `DocumentRoot` paths if your folder is not `D:\www\online-clinic`).
3. Ensure Apache listens on all interfaces — in `httpd.conf`, `Listen 80` (not only `127.0.0.1:80`).
4. **Windows Firewall** → allow **Apache HTTP Server** on Private networks.
5. Build frontend with LAN API URL:
   ```bat
   cd frontend
   set VITE_API_URL=http://LAN_IP/api
   npm run build
   ```
6. Other devices open: `http://LAN_IP/` (if Apache default site points to `frontend/dist`) **or** configure a vhost with `ServerName` and use hosts/DNS on each PC.

See [scripts/apache/README.md](../scripts/apache/README.md) for vhost details. For IP-only access, point `DocumentRoot` to `frontend/dist` on the default host or add a vhost bound to the server IP.

**Linux (Debian/Ubuntu-style)**

```bash
sudo apt install apache2 libapache2-mod-php php-mysql composer
# Enable mod_rewrite, mod_proxy if proxying /api to artisan serve
sudo cp scripts/apache/clinic-frontend.local.dev.conf /etc/apache2/sites-available/online-clinic.conf
# Edit paths and ServerName / LAN IP
sudo a2ensite online-clinic && sudo systemctl reload apache2
sudo ufw allow 80/tcp
```

**macOS**

Use Homebrew Apache/Nginx or `php artisan serve` + Vite only for small pilots; production-like intranet usually uses Apache/Nginx on port 80.

#### Option 2 — Laravel `artisan serve` + built SPA (small LAN)

1. API: `scripts/intranet/start-api-intranet.sh` → `http://LAN_IP:8000`
2. Build frontend:
   ```bash
   cd frontend
   echo "VITE_API_URL=http://LAN_IP:8000/api" > .env
   npm run build
   ```
3. Serve `frontend/dist` with a static server bound to LAN, e.g.:
   ```bash
   npx --yes serve frontend/dist -l 0.0.0.0:8080
   ```
4. Clients open: `http://LAN_IP:8080`
5. Firewall: allow TCP **8000** and **8080** on private profile.

#### Option 3 — Development (Vite + artisan serve)

On the server only:

```bash
export CLINIC_API_HOST=0.0.0.0
bash scripts/start-api.sh
cd frontend && npm run dev -- --host 0.0.0.0
```

Other devices: `http://LAN_IP:5173` (Vite proxies `/api` to port 8000). Not recommended for daily clinic use.

---

### D. Run the installation wizard (intranet)

1. Open `/setup` from the server.
2. **Site & URLs** → **Intranet (local network only)**.
3. Suggested values (replace `LAN_IP`):

| Field | Example |
|-------|---------|
| API URL | `http://LAN_IP:8000` (artisan) or `http://LAN_IP` (Apache backend vhost) |
| Web app URL | `http://LAN_IP` or `http://LAN_IP:8080` |
| Production API URL for build | `http://LAN_IP/api` or `http://LAN_IP:8000/api` |
| Mobile API URL | `http://LAN_IP/api` (must end with `/api`) |

4. Finish install; sign in at `http://LAN_IP/login` from any LAN device.

---

### E. Mobile app on the LAN

1. Install Node/Expo on a dev PC or use the server.
2. Ensure `mobile-app/.env` contains (wizard writes this):
   ```
   EXPO_PUBLIC_API_URL=http://LAN_IP/api
   ```
3. Phone must be on the **same Wi‑Fi** as the server (not guest network).
4. From `mobile-app/`: `npm install` then `npx expo start`.
5. Scan QR code with Expo Go, or build a standalone APK/IPA for clinic devices.

---

### F. Connect from another laptop, tablet, or phone

1. Connect to the same LAN as the server.
2. Open a browser.
3. Go to the **Web app URL** you configured (e.g. `http://192.168.1.50`).
4. Log in with the accounts created in the wizard.

**Troubleshooting**

| Symptom | What to check |
|---------|----------------|
| Page does not load | Ping `LAN_IP` from the client; firewall on server; Apache listening on `0.0.0.0:80` |
| UI loads, API errors | `VITE_API_URL` must use `LAN_IP`, not `localhost`; rebuild frontend; API running with `0.0.0.0` |
| Works on server, not elsewhere | API still on `127.0.0.1` — use intranet start script |
| Mobile cannot connect | Guest Wi‑Fi; wrong `EXPO_PUBLIC_API_URL`; HTTPS mismatch (use `http` on LAN) |
| Slow or 502 on install | Prefer Apache + PHP for `/api` instead of proxy to single-threaded `artisan serve` |

---

## Firewall reference

**Windows Defender (PowerShell as Administrator)**

```powershell
New-NetFirewallRule -DisplayName "Online Clinic HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow -Profile Private
New-NetFirewallRule -DisplayName "Online Clinic API" -Direction Inbound -Protocol TCP -LocalPort 8000 -Action Allow -Profile Private
```

**Linux (ufw)**

```bash
sudo ufw allow from 192.168.0.0/16 to any port 80 proto tcp
sudo ufw allow from 192.168.0.0/16 to any port 8000 proto tcp
```

Adjust subnet to match your LAN.

---

## Security notes (intranet)

- Intranet does **not** replace backups, OS updates, or physical access control.
- Use strong passwords for superadmin and owner accounts.
- Segment clinic Wi‑Fi from public/guest networks.
- If the LAN has internet, keep the server patched; block inbound port forwarding from the router unless you intentionally expose the app.
- For HTTPS on LAN, use an internal CA or reverse proxy with a certificate matching an internal DNS name.

---

## After installation

| Task | Command / location |
|------|---------------------|
| Start API (LAN) | `scripts/intranet/start-api-intranet.*` |
| Auto-start on login | `scripts/autostart/install-autostart.*` with `CLINIC_API_HOST=0.0.0.0` |
| Update app | `scripts/update.sh` / `scripts\update.bat` |
| Full guide | [README](../README.md) |

Deployment mode is stored in `backend/.env` as `DEPLOYMENT_MODE=intranet` and in `backend/storage/app/installed.json` when chosen in the wizard.
