# Deployment Guide — boha-app-ts (Ubuntu Server)

Migration from PHP boha-app to TypeScript boha-app-ts on the same Ubuntu server.
Both apps share the same MySQL database. The PHP app stays running during migration.

---

## Prerequisites

- Ubuntu server with the PHP boha-app already running
- nginx with SSL (Let's Encrypt) already configured
- MySQL database already running with production data
- NAS storage mounted (e.g., `/mnt/nas/02_PROJEKTY`)
- SSH access to the server

---

## Phase 1: Prepare on Dev Machine (Windows)

### 1.1 Create Prisma migration baseline

```bash
cd D:\cortex\boha-app-ts
mkdir -p prisma/migrations/0_init
npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
npx prisma migrate resolve --applied 0_init
git add prisma/migrations/
git commit -m "chore: create Prisma migration baseline"
```

### 1.2 Build the application

```bash
npm run build
```

This creates:
- `dist/` — compiled server (Node.js)
- `dist-client/` — compiled frontend (static files)

### 1.3 Generate new production secrets

```bash
openssl rand -hex 32
# Save this as JWT_SECRET

openssl rand -hex 32
# Save this as TOTP_ENCRYPTION_KEY (only if you want a new key)
```

### 1.4 Test the production build locally (optional)

```bash
APP_ENV=production JWT_SECRET=<your-dev-key> TOTP_ENCRYPTION_KEY=<your-dev-key> DATABASE_URL=<your-dev-db> node dist/server.js
```

Verify it starts and responds at `http://localhost:3001/api/health`.

---

## Phase 2: Prepare Ubuntu Server

### 2.1 Install Node.js 22

```bash
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v
npm -v
```

### 2.2 Install PM2

```bash
sudo npm install -g pm2
```

### 2.3 Create application directory

```bash
sudo mkdir -p /var/www/boha-app-ts
sudo chown $USER:$USER /var/www/boha-app-ts
```

---

## Phase 3: Transfer Files to Server

### 3.1 Copy built files

From your Windows machine (Git Bash or PowerShell with SCP):

```bash
scp -r dist/ dist-client/ package.json package-lock.json prisma/ scripts/ .env.example user@server:/var/www/boha-app-ts/
```

Or use rsync if available:

```bash
rsync -avz --exclude node_modules --exclude .env dist/ dist-client/ package.json package-lock.json prisma/ scripts/ .env.example user@server:/var/www/boha-app-ts/
```

### 3.2 Install production dependencies on server

```bash
ssh user@server
cd /var/www/boha-app-ts
npm install --production
npx prisma generate
```

---

## Phase 4: Configure Environment

### 4.1 Create production .env

```bash
cd /var/www/boha-app-ts
cp .env.example .env
nano .env
```

Fill in:

```env
# Database — same as the PHP app
DATABASE_URL=mysql://user:password@localhost:3306/your_db_name

# Server
PORT=3001
HOST=127.0.0.1
APP_ENV=production

# Auth — use the NEW secrets generated in step 1.3
JWT_SECRET=<paste-new-jwt-secret>
ACCESS_TOKEN_EXPIRY=900
REFRESH_TOKEN_SESSION_EXPIRY=3600
REFRESH_TOKEN_REMEMBER_EXPIRY=2592000

# TOTP — use SAME key as PHP app (unless you want to re-encrypt)
TOTP_ENCRYPTION_KEY=<same-key-as-php-app>

# NAS — Linux mount point
NAS_PATH=/mnt/nas/02_PROJEKTY
MAX_UPLOAD_SIZE=52428800

# Email
CONTACT_EMAIL_TO=manager@boha-automation.cz
CONTACT_EMAIL_FROM=web@boha-automation.cz
SMTP_FROM=noreply@boha-automation.cz

# CORS — your production domain(s)
CORS_ORIGINS=https://app.boha-automation.cz,https://www.boha-automation.cz
```

**Important decisions:**

| Setting | Recommendation |
|---------|---------------|
| `JWT_SECRET` | **New key.** All PHP sessions will be invalid — users re-login. This is expected. |
| `TOTP_ENCRYPTION_KEY` | **Same key as PHP app.** Avoids re-encrypting all TOTP secrets. |
| `DATABASE_URL` | **Same database as PHP app.** Both apps share it. |
| `NAS_PATH` | **Linux mount point** instead of Windows drive letter. |

---

## Phase 5: Database Setup

### 5.1 Mark Prisma baseline as applied

```bash
cd /var/www/boha-app-ts
npx prisma migrate resolve --applied 0_init
```

This tells Prisma the database already has all tables. No SQL is executed.

### 5.2 Verify database connection

```bash
npx prisma db pull --print | head -20
```

Should show your existing tables.

---

## Phase 6: TOTP Key Rotation (only if using new encryption key)

**Skip this section if you're using the same `TOTP_ENCRYPTION_KEY` as the PHP app.**

If you generated a new encryption key:

```bash
cd /var/www/boha-app-ts

# Dry run — verify all secrets can be decrypted and re-encrypted
npx tsx scripts/rotate-totp-key.ts <old-key> <new-key> --dry-run

# If all [OK], run for real
npx tsx scripts/rotate-totp-key.ts <old-key> <new-key>
```

After this, the PHP app's TOTP verification will break (secrets are now encrypted with the new key). Only do this when you're ready to cut over.

---

## Phase 7: Start Application with PM2

### 7.1 Create PM2 config

```bash
cd /var/www/boha-app-ts
cat > ecosystem.config.js << 'EOF'
module.exports = {
  apps: [{
    name: 'boha-app-ts',
    script: 'dist/server.js',
    cwd: '/var/www/boha-app-ts',
    instances: 1,
    env: {
      NODE_ENV: 'production',
    },
  }]
};
EOF
```

### 7.2 Start the app

```bash
pm2 start ecosystem.config.js
pm2 save
pm2 startup
# Follow the printed command to enable auto-start on boot
```

### 7.3 Verify

```bash
pm2 status
pm2 logs boha-app-ts --lines 20
curl http://localhost:3001/api/health
```

Expected: `{"status":"ok","timestamp":"..."}`

---

## Phase 8: Nginx Configuration

### 8.1 Create nginx config

```bash
sudo nano /etc/nginx/sites-available/boha-app-ts
```

Paste:

```nginx
server {
    listen 443 ssl http2;
    server_name app.boha-automation.cz;

    ssl_certificate /etc/letsencrypt/live/app.boha-automation.cz/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.boha-automation.cz/privkey.pem;

    client_max_body_size 55M;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

server {
    listen 80;
    server_name app.boha-automation.cz;
    return 301 https://$host$request_uri;
}
```

Adjust `server_name` and SSL paths to match your setup.

### 8.2 Enable and reload

```bash
sudo ln -s /etc/nginx/sites-available/boha-app-ts /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
```

---

## Phase 9: Testing

### 9.1 Verify in browser

Open `https://app.boha-automation.cz` and test:

- [ ] Login page loads
- [ ] Login works (users will need to re-login due to new JWT_SECRET)
- [ ] TOTP verification works (if using same encryption key)
- [ ] Dashboard loads with data
- [ ] Offers — list, create, edit, PDF export
- [ ] Orders — list, create from offer, status transitions
- [ ] Invoices — list, create, PDF with QR code
- [ ] Projects — list, create, file manager (upload/download)
- [ ] Attendance — clock in/out, admin view, print
- [ ] Trips — list, history
- [ ] Settings — company settings, users, roles

### 9.2 Check logs for errors

```bash
pm2 logs boha-app-ts --lines 50
```

---

## Phase 10: Cutover Strategy

Both apps run simultaneously on the same database. Recommended approach:

1. **Week 1:** Run both apps. Use the TS app for daily work. Fall back to PHP if issues arise.
2. **Week 2:** If stable, redirect the main domain to the TS app.
3. **Week 3:** Stop the PHP app.

To redirect the PHP domain to the TS app, update the nginx config for the PHP domain to proxy to port 3001 instead.

---

## Future Updates

When you push code changes:

```bash
# On dev machine
npm run build
git push

# On server
cd /var/www/boha-app-ts
git pull
npm install --production
npx prisma generate
npx prisma migrate deploy    # runs any new migrations
pm2 restart boha-app-ts
```

---

## Troubleshooting

| Problem | Solution |
|---------|----------|
| `EADDRINUSE: port 3001` | `pm2 stop boha-app-ts` then `pm2 start` |
| Prisma connection error | Check `DATABASE_URL` in `.env` |
| TOTP verification fails | Verify `TOTP_ENCRYPTION_KEY` matches the key used to encrypt secrets |
| NAS files not accessible | Check mount: `ls /mnt/nas/02_PROJEKTY`, verify permissions |
| 502 Bad Gateway | App not running: `pm2 status`, check logs: `pm2 logs` |
| CSS/JS not loading | Verify `dist-client/` was copied, check `APP_ENV=production` |
| CORS errors | Check `CORS_ORIGINS` in `.env` matches your domain exactly |

---

## Quick Reference

| Command | Purpose |
|---------|---------|
| `pm2 start ecosystem.config.js` | Start the app |
| `pm2 restart boha-app-ts` | Restart after update |
| `pm2 stop boha-app-ts` | Stop the app |
| `pm2 logs boha-app-ts` | View logs |
| `pm2 monit` | Live monitoring |
| `npx prisma migrate deploy` | Apply database migrations |
| `npx prisma studio` | Database GUI (dev only) |
