# Church SongLyric - Multi-Device Sync Setup Guide

## Backend Server Setup

### 1. Install Dependencies

```powershell
cd "E:\Documents\Website Projects\Church_SongLyric\backend"
npm install
```

### 2. Start the Backend Server

**Development (auto-restart on changes):**

```powershell
npm run dev
```

**Production:**

```powershell
npm start
```

The server will start on `http://localhost:5000` by default.

---

## Frontend Configuration

### Option 1: Use Settings UI (Recommended)

1. Open the app in your browser
2. Navigate to **Settings** page
3. Configure **Online/DNS Settings**:
   - **Protocol**: `http` or `https`
   - **Hostname**: `localhost` (local) or your No-IP hostname (remote)
   - **Port**: `5000`
   - **Access Mode**: Toggle between Local Storage (offline) and Online (synced)
4. Click **Save Settings**
5. Refresh the page to connect

### Option 2: Manual Configuration

Edit `frontend/src/api.js` and modify:

```javascript
useLocalStorage: false  // Enable backend sync
hostname: "localhost"   // Or your No-IP hostname
```

---

## Local Network Access (Multiple Devices on Same Wi-Fi)

### 1. Find Your Computer's Local IP

```powershell
ipconfig
```

Look for **IPv4 Address** under your active network adapter (e.g., `192.168.1.50`)

### 2. Configure Frontend Settings

- **Hostname**: Use your local IP (e.g., `192.168.1.50`)
- **Port**: `5000`
- **Access Mode**: Online

### 3. Access from Other Devices

Open browser on tablet/phone/laptop and navigate to:

```text
http://192.168.1.50:3000
```

All devices will now share the same database via the backend server.

---

## External Access Setup (No-IP Dynamic DNS)

### Step 1: Create No-IP Account

1. Go to <https://www.noip.com/>
2. Sign up for free account (supports 3 hostnames)
3. Verify email

### Step 2: Create Hostname

1. Login to No-IP dashboard
2. Navigate to **Dynamic DNS** → **No-IP Hostnames**
3. Click **Create Hostname**
4. Choose a hostname: `churchlyrics.ddns.net` (or your preference)
5. Set **Record Type**: A (IPv4 Address)
6. Leave IP auto-detected (your current public IP)
7. Click **Create Hostname**

### Step 3: Assign Static Local IP (Windows)

1. Open **Settings** → **Network & Internet** → **Ethernet** (or Wi-Fi)
2. Click **Properties**
3. Click **Edit** under IP assignment
4. Select **Manual**
5. Enable **IPv4**
6. Set:
   - **IP Address**: `192.168.1.50` (adjust to your subnet)
   - **Subnet Mask**: `255.255.255.0`
   - **Gateway**: Your router IP (usually `192.168.1.1`)
   - **DNS**: `8.8.8.8` (Google DNS)
7. Save

### Step 4: Configure Router Port Forwarding

1. Login to router admin panel (usually `http://192.168.1.1`)
2. Navigate to **Port Forwarding** or **Virtual Server**
3. Add new rule:
   - **Service Name**: ChurchSongLyric API
   - **External Port**: `5000`
   - **Internal IP**: `192.168.1.50` (your static IP)
   - **Internal Port**: `5000`
   - **Protocol**: TCP
4. Add another rule for frontend (if exposing React dev server):
   - **External Port**: `3000`
   - **Internal IP**: `192.168.1.50`
   - **Internal Port**: `3000`
   - **Protocol**: TCP
5. Save and reboot router if required

### Step 5: Install No-IP Dynamic Update Client (DUC)

1. Download from <https://www.noip.com/download>
2. Install and login with your No-IP credentials
3. Select the hostname you created
4. Click **Save**
5. Enable **Start on Windows Startup** in settings
6. The client will auto-update your public IP when it changes

### Step 6: Configure Windows Firewall

**Allow Backend Port:**

```powershell
New-NetFirewallRule -DisplayName "ChurchSongLyric API" -Direction Inbound -Protocol TCP -LocalPort 5000 -Action Allow
```

**Allow Frontend Port (if needed):**

```powershell
New-NetFirewallRule -DisplayName "ChurchSongLyric Frontend" -Direction Inbound -Protocol TCP -LocalPort 3000 -Action Allow
```

Or manually:

1. Open **Windows Security** → **Firewall & Network Protection**
2. Click **Advanced Settings**
3. Select **Inbound Rules** → **New Rule**
4. Choose **Port** → **TCP** → Enter `5000`
5. Select **Allow the connection**
6. Name it: `ChurchSongLyric API`
7. Repeat for port `3000` if needed

### Step 7: Test External Access

From a mobile device on cellular (not Wi-Fi):

```text
http://churchlyrics.ddns.net:5000/api/songs
```

Should return JSON (empty array initially).

### Step 8: Update Frontend Settings

In Settings UI:

- **Protocol**: `http`
- **Hostname**: `churchlyrics.ddns.net`
- **Port**: `5000`
- **Access Mode**: Online

Save and refresh.

---

## Security Hardening (Recommended)

### 1. Add API Key Authentication

Edit `backend/server.js` and add middleware:

```javascript
const API_KEY = process.env.API_KEY || 'your-secret-key-here';

app.use('/api', (req, res, next) => {
  const key = req.headers['x-api-key'];
  if (key !== API_KEY) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  next();
});
```

Update frontend requests to include header:

```javascript
headers: { 
  "Content-Type": "application/json",
  "X-API-Key": "your-secret-key-here"
}
```

### 2. Enable HTTPS (Production)

Install Caddy (reverse proxy with auto HTTPS):

```powershell
choco install caddy
```

Create `Caddyfile`:

```text
churchlyrics.ddns.net {
  reverse_proxy localhost:5000
}
```

Update port forwarding to 443 (HTTPS) instead of 5000.

### 3. Regular Backups

Schedule automatic backups of `backend/data.json`:

```powershell
# Add to Task Scheduler
Copy-Item "E:\Documents\Website Projects\Church_SongLyric\backend\data.json" `
  -Destination "E:\Backups\church_data_$(Get-Date -Format yyyyMMdd_HHmmss).json"
```

### 4. Restrict WebSocket Origins

In `server.js`:

```javascript
wss.on('connection', (ws, req) => {
  const origin = req.headers.origin;
  const allowed = ['http://localhost:3000', 'http://churchlyrics.ddns.net:3000'];
  if (!allowed.includes(origin)) {
    ws.close();
    return;
  }
  // ... rest of connection logic
});
```

---

## Real-Time Sync Features

### How It Works

- Backend broadcasts changes via WebSocket when any device creates/updates/deletes data
- All connected clients receive notifications and automatically refresh their UI
- No manual page reload needed

### Supported Events

- `songsChanged`: When songs are added/edited/deleted
- `plansChanged`: When worship plans are modified
- `profilesChanged`: When profiles are updated
- `profileSongsChanged`: When profile song associations change

### Testing Sync

1. Open app on two devices (or two browser tabs)
2. Create a new song on Device A
3. Device B will automatically show the new song without refresh

---

## Troubleshooting

### Backend won't start

```powershell
# Check if port is already in use
Get-NetTCPConnection -LocalPort 5000
# Kill the process if needed
Stop-Process -Id <PID>
```

### Can't connect from other devices

1. Verify firewall rules are active
2. Check router port forwarding is saved
3. Ensure static IP is configured correctly
4. Test local connection first (`http://localhost:5000/api/songs`)

### WebSocket disconnects frequently

- Check network stability
- Ensure No-IP DUC is running and updating
- Verify router isn't closing idle connections (adjust timeout settings)

### Data not syncing

1. Open browser console (F12)
2. Check for WebSocket connection logs:
   - `✅ WebSocket connected` = working
   - `❌ WebSocket error` = connection failed
3. Verify `useLocalStorage` is set to `false` in Settings
4. Test API directly: `http://your-host:5000/api/songs`

---

## Performance Optimization

### Enable Compression

Add to `server.js`:

```javascript
import compression from 'compression';
app.use(compression());
```

### Database Migration (Future)

For larger deployments, consider migrating from file-based storage to:

- **SQLite**: Lightweight, file-based SQL database
- **MongoDB**: NoSQL document store
- **PostgreSQL**: Full-featured relational database

---

## Additional Resources

- **No-IP Documentation**: <https://www.noip.com/support>
- **Express.js Guide**: <https://expressjs.com/>
- **WebSocket API**: <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket>

---

## Support

For issues or questions:

1. Check backend console for error logs
2. Check browser console (F12) for frontend errors
3. Verify all ports are open and forwarded correctly
4. Test each layer: localhost → LAN → external

**Quick Test Commands:**

```powershell
# Test local backend
curl http://localhost:5000/api/songs

# Test from LAN
curl http://192.168.1.50:5000/api/songs

# Test external (from mobile cellular)
curl http://churchlyrics.ddns.net:5000/api/songs
```
