# 🚀 Simple Deployment Guide (No Authentication)

## Quick Overview

Since you don't need authentication, the deployment is much simpler:
- ✅ No login required
- ✅ No user management
- ✅ Direct access to search and view documents
- ✅ Faster implementation (3-5 days instead of 8-13 days)

---

## Option 1: Web Application (Recommended)

### Architecture (Simplified)

```
Browser → API Server (Port 8001) → Database + Files
```

**No authentication needed!** Users can directly search and view documents.

---

### Step-by-Step Implementation

#### Phase 1: Backend (Already Done! ✅)

Your current backend is **ready to use** as-is! No changes needed.

**Current working endpoints:**
- `GET /` - Health check
- `GET /documents/by-document-number?document_number=PL11089` - Search
- `GET /documents/pdf-by-document-number?document_number=PL11089&document_type=103&document_id=10000000013791` - View PDF

**Only update needed: CORS (if accessing from different domain)**

```python
# In aumentum_api.py - already configured!
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Allow all origins (no auth needed)
    allow_credentials=False,  # No credentials needed
    allow_methods=["*"],
    allow_headers=["*"],
)
```

---

#### Phase 2: Simple Web Frontend (1-2 days)

**Option A: Ultra-Simple HTML (Single File)**

Create `public/index.html`:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Aumentum Document Viewer</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }
        
        .container {
            max-width: 1400px;
            margin: 0 auto;
            background: white;
            border-radius: 15px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            overflow: hidden;
        }
        
        header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }
        
        header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }
        
        header p {
            font-size: 1.1em;
            opacity: 0.9;
        }
        
        .search-section {
            padding: 30px;
            background: #f8f9fa;
            border-bottom: 1px solid #dee2e6;
        }
        
        .search-form {
            display: flex;
            gap: 15px;
            max-width: 600px;
            margin: 0 auto;
        }
        
        .search-input {
            flex: 1;
            padding: 15px 20px;
            font-size: 16px;
            border: 2px solid #dee2e6;
            border-radius: 8px;
            transition: all 0.3s;
        }
        
        .search-input:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }
        
        .search-button {
            padding: 15px 40px;
            font-size: 16px;
            font-weight: bold;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            transition: transform 0.2s;
        }
        
        .search-button:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
        }
        
        .search-button:active {
            transform: translateY(0);
        }
        
        .search-button:disabled {
            background: #6c757d;
            cursor: not-allowed;
            transform: none;
        }
        
        .content-section {
            display: flex;
            min-height: 600px;
        }
        
        .results-panel {
            width: 350px;
            border-right: 1px solid #dee2e6;
            overflow-y: auto;
            background: #f8f9fa;
        }
        
        .results-header {
            padding: 20px;
            background: white;
            border-bottom: 1px solid #dee2e6;
            font-weight: bold;
            font-size: 1.1em;
        }
        
        .document-item {
            padding: 20px;
            border-bottom: 1px solid #dee2e6;
            cursor: pointer;
            transition: all 0.2s;
            background: white;
            margin: 10px;
            border-radius: 8px;
        }
        
        .document-item:hover {
            background: #e7f1ff;
            transform: translateX(5px);
        }
        
        .document-item.selected {
            background: #667eea;
            color: white;
        }
        
        .document-type {
            font-weight: bold;
            font-size: 1.1em;
            margin-bottom: 8px;
        }
        
        .document-info {
            font-size: 0.9em;
            opacity: 0.8;
        }
        
        .viewer-panel {
            flex: 1;
            display: flex;
            flex-direction: column;
            background: #f0f0f0;
        }
        
        .viewer-header {
            padding: 20px;
            background: white;
            border-bottom: 1px solid #dee2e6;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .viewer-title {
            font-weight: bold;
            font-size: 1.2em;
        }
        
        .viewer-controls {
            display: flex;
            gap: 10px;
        }
        
        .control-button {
            padding: 8px 15px;
            background: #667eea;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
        }
        
        .control-button:hover {
            background: #5568d3;
        }
        
        .viewer-content {
            flex: 1;
            padding: 20px;
            overflow: auto;
        }
        
        .pdf-container {
            width: 100%;
            height: 100%;
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        iframe {
            width: 100%;
            height: 100%;
            border: none;
            border-radius: 8px;
        }
        
        .loading {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 60px;
            color: #6c757d;
        }
        
        .spinner {
            width: 50px;
            height: 50px;
            border: 5px solid #f3f3f3;
            border-top: 5px solid #667eea;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin-bottom: 20px;
        }
        
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        
        .empty-state {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 60px;
            color: #6c757d;
            text-align: center;
        }
        
        .empty-state-icon {
            font-size: 4em;
            margin-bottom: 20px;
            opacity: 0.3;
        }
        
        .error-message {
            background: #f8d7da;
            color: #721c24;
            padding: 15px 20px;
            margin: 20px;
            border-radius: 8px;
            border: 1px solid #f5c6cb;
        }
        
        footer {
            text-align: center;
            padding: 20px;
            background: #f8f9fa;
            color: #6c757d;
            font-size: 0.9em;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>🗂️ Aumentum Document Viewer</h1>
            <p>Search and view land registry documents instantly</p>
        </header>
        
        <div class="search-section">
            <div class="search-form">
                <input 
                    type="text" 
                    id="documentNumber" 
                    class="search-input"
                    placeholder="Enter document number (e.g., PL11089, PL689, PL10820)"
                    autocomplete="off"
                >
                <button id="searchBtn" class="search-button">Search</button>
            </div>
        </div>
        
        <div class="content-section">
            <div class="results-panel">
                <div class="results-header">Search Results</div>
                <div id="results">
                    <div class="empty-state">
                        <div class="empty-state-icon">🔍</div>
                        <p>Enter a document number above to begin</p>
                    </div>
                </div>
            </div>
            
            <div class="viewer-panel">
                <div class="viewer-header">
                    <div class="viewer-title" id="viewerTitle">Document Viewer</div>
                    <div class="viewer-controls">
                        <button class="control-button" id="downloadBtn" style="display:none;">
                            📥 Download
                        </button>
                        <button class="control-button" id="printBtn" style="display:none;">
                            🖨️ Print
                        </button>
                    </div>
                </div>
                <div class="viewer-content" id="viewer">
                    <div class="empty-state">
                        <div class="empty-state-icon">📄</div>
                        <p>Select a document from the search results to view</p>
                    </div>
                </div>
            </div>
        </div>
        
        <footer>
            <p>Powered by Aumentum Document Management System</p>
        </footer>
    </div>

    <script>
        // Configuration
        const API_BASE = 'http://localhost:8001';
        
        // Elements
        const searchBtn = document.getElementById('searchBtn');
        const documentInput = document.getElementById('documentNumber');
        const resultsDiv = document.getElementById('results');
        const viewerDiv = document.getElementById('viewer');
        const viewerTitle = document.getElementById('viewerTitle');
        const downloadBtn = document.getElementById('downloadBtn');
        const printBtn = document.getElementById('printBtn');
        
        let currentPdfUrl = null;
        
        // Event listeners
        searchBtn.addEventListener('click', searchDocuments);
        documentInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') searchDocuments();
        });
        
        downloadBtn.addEventListener('click', downloadPDF);
        printBtn.addEventListener('click', printPDF);
        
        // Search documents
        async function searchDocuments() {
            const docNumber = documentInput.value.trim().toUpperCase();
            
            if (!docNumber) {
                alert('Please enter a document number');
                return;
            }
            
            // Show loading
            searchBtn.disabled = true;
            searchBtn.textContent = 'Searching...';
            resultsDiv.innerHTML = '<div class="loading"><div class="spinner"></div><p>Searching...</p></div>';
            
            try {
                const response = await fetch(
                    `${API_BASE}/documents/by-document-number?document_number=${encodeURIComponent(docNumber)}`
                );
                
                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }
                
                const data = await response.json();
                displayResults(data);
                
            } catch (error) {
                console.error('Search failed:', error);
                resultsDiv.innerHTML = `
                    <div class="error-message">
                        <strong>Search Failed</strong><br>
                        ${error.message}<br>
                        <small>Make sure the API server is running on port 8001</small>
                    </div>
                `;
            } finally {
                searchBtn.disabled = false;
                searchBtn.textContent = 'Search';
            }
        }
        
        // Display search results
        function displayResults(data) {
            if (!data.items || data.items.length === 0) {
                resultsDiv.innerHTML = `
                    <div class="empty-state">
                        <div class="empty-state-icon">❌</div>
                        <p>No documents found for "${data.document_number}"</p>
                    </div>
                `;
                return;
            }
            
            resultsDiv.innerHTML = '';
            
            data.items.forEach(doc => {
                const div = document.createElement('div');
                div.className = 'document-item';
                div.innerHTML = `
                    <div class="document-type">
                        ${doc.document_type_label || `Type ${doc.document_type}`}
                    </div>
                    <div class="document-info">
                        📄 ${doc.page_count} page${doc.page_count !== 1 ? 's' : ''}<br>
                        🖼️ ${doc.available_images} image${doc.available_images !== 1 ? 's' : ''} available
                    </div>
                `;
                
                div.addEventListener('click', () => {
                    // Remove selection from all items
                    document.querySelectorAll('.document-item').forEach(item => {
                        item.classList.remove('selected');
                    });
                    // Select this item
                    div.classList.add('selected');
                    // View document
                    viewDocument(data.document_number, doc);
                });
                
                resultsDiv.appendChild(div);
            });
        }
        
        // View document
        function viewDocument(docNumber, doc) {
            const url = `${API_BASE}/documents/pdf-by-document-number?` +
                `document_number=${encodeURIComponent(docNumber)}&` +
                `document_type=${doc.document_type}&` +
                `document_id=${doc.id}`;
            
            viewerTitle.textContent = `${docNumber} - ${doc.document_type_label || `Type ${doc.document_type}`}`;
            viewerDiv.innerHTML = '<div class="loading"><div class="spinner"></div><p>Loading PDF...</p></div>';
            
            // Show controls
            downloadBtn.style.display = 'block';
            printBtn.style.display = 'block';
            
            // Store current PDF URL for download/print
            currentPdfUrl = url;
            
            // Display PDF
            setTimeout(() => {
                viewerDiv.innerHTML = `
                    <div class="pdf-container">
                        <iframe src="${url}#toolbar=1&navpanes=1&scrollbar=1" 
                                allowfullscreen>
                        </iframe>
                    </div>
                `;
            }, 500);
        }
        
        // Download PDF
        function downloadPDF() {
            if (!currentPdfUrl) return;
            
            const link = document.createElement('a');
            link.href = currentPdfUrl;
            link.download = `document_${Date.now()}.pdf`;
            link.click();
        }
        
        // Print PDF
        function printPDF() {
            if (!currentPdfUrl) return;
            
            const printWindow = window.open(currentPdfUrl);
            printWindow.addEventListener('load', () => {
                printWindow.print();
            });
        }
    </script>
</body>
</html>
```

**To use this:**

```bash
# 1. Save the file
mkdir -p /home/plagis/workspace/plagis_aumentum/web_frontend
# Copy the HTML above to: /home/plagis/workspace/plagis_aumentum/web_frontend/index.html

# 2. Make sure API is running
cd /home/plagis/workspace/plagis_aumentum
source venv/bin/activate
python3 aumentum_api.py &

# 3. Serve the frontend
cd web_frontend
python3 -m http.server 3000

# 4. Open browser
# Go to: http://localhost:3000
```

**That's it! No authentication, no complex setup!** 🎉

---

**Option B: React Frontend (More Features)**

If you want a more sophisticated UI later, you can use React:

```bash
# Create React app
npx create-react-app aumentum-web
cd aumentum-web

# Install dependencies
npm install axios @mui/material @emotion/react @emotion/styled react-pdf

# Copy the React components from DEPLOYMENT_PLAN.md (sections 2.2-2.4)
# But remove all authentication code (login, tokens, etc.)

# Start development server
npm start
```

---

#### Phase 3: Production Deployment (1-2 days)

**Option A: Simple Server Setup (No Docker)**

```bash
# 1. Install Nginx
sudo apt update
sudo apt install nginx

# 2. Configure Nginx
sudo nano /etc/nginx/sites-available/aumentum
```

```nginx
server {
    listen 80;
    server_name your-server-ip-or-domain;
    
    # Frontend
    location / {
        root /home/plagis/workspace/plagis_aumentum/web_frontend;
        try_files $uri $uri/ /index.html;
    }
    
    # API (proxy to backend)
    location /api/ {
        rewrite ^/api/(.*) /$1 break;
        proxy_pass http://127.0.0.1:8001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        
        # Increase timeout for PDF generation
        proxy_read_timeout 300s;
        proxy_connect_timeout 300s;
    }
}
```

```bash
# 3. Enable site
sudo ln -s /etc/nginx/sites-available/aumentum /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

# 4. Setup API as a service
sudo nano /etc/systemd/system/aumentum-api.service
```

```ini
[Unit]
Description=Aumentum Document API
After=network.target

[Service]
Type=simple
User=plagis
WorkingDirectory=/home/plagis/workspace/plagis_aumentum
Environment="PATH=/home/plagis/workspace/plagis_aumentum/venv/bin"
ExecStart=/home/plagis/workspace/plagis_aumentum/venv/bin/python3 -m uvicorn aumentum_api:app --host 127.0.0.1 --port 8001 --workers 4
Restart=always

[Install]
WantedBy=multi-user.target
```

```bash
# 5. Start service
sudo systemctl daemon-reload
sudo systemctl enable aumentum-api
sudo systemctl start aumentum-api

# 6. Check status
sudo systemctl status aumentum-api

# Done! Access at: http://your-server-ip
```

**Option B: Docker Deployment (Easier)**

Create `docker-compose.yml`:

```yaml
version: '3.8'

services:
  api:
    build: .
    ports:
      - "8001:8001"
    volumes:
      - /mnt/aumentum_contentstore:/mnt/contentstore:ro
      - ./aumentum_pdfs:/tmp/aumentum_pdfs
    environment:
      - CONTENTSTORE_BASE=/mnt/contentstore
    restart: unless-stopped

  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./web_frontend:/usr/share/nginx/html:ro
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - api
    restart: unless-stopped
```

```bash
# Deploy
docker-compose up -d

# View logs
docker-compose logs -f

# Stop
docker-compose down
```

---

## Option 2: Desktop Application (No Authentication Needed)

Since there's no authentication, the desktop app is even simpler!

### Quick Desktop App (Electron)

**1. Setup (5 minutes)**

```bash
mkdir aumentum-desktop
cd aumentum-desktop
npm init -y
npm install electron
```

**2. Create `main.js`:**

```javascript
const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
    const win = new BrowserWindow({
        width: 1400,
        height: 900,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true
        }
    });
    
    // Load the web version
    win.loadFile('index.html');
    // OR load from server:
    // win.loadURL('http://localhost:3000');
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});
```

**3. Copy your HTML file:**

```bash
# Copy the web frontend HTML
cp /home/plagis/workspace/plagis_aumentum/web_frontend/index.html .

# Update API_BASE in the HTML to point to your server
# Change: const API_BASE = 'http://localhost:8001';
# To: const API_BASE = 'http://your-server-ip:8001';
```

**4. Add to `package.json`:**

```json
{
  "name": "aumentum-desktop",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "build": "electron-builder"
  },
  "devDependencies": {
    "electron": "^27.0.0",
    "electron-builder": "^24.6.0"
  },
  "build": {
    "appId": "com.aumentum.viewer",
    "productName": "Aumentum Viewer",
    "win": {
      "target": "nsis"
    },
    "linux": {
      "target": ["AppImage", "deb"]
    }
  }
}
```

**5. Run:**

```bash
npm start
```

**6. Build executable:**

```bash
npm install electron-builder --save-dev
npm run build

# Output in dist/ folder
```

---

## Security Considerations (Without Authentication)

Since you don't want authentication, consider these alternatives:

### Option 1: Network-Level Security
```bash
# Only allow access from office network
# In nginx.conf:
location / {
    allow 192.168.1.0/24;  # Your office network
    deny all;
}
```

### Option 2: VPN Access
- Users connect via VPN
- Application only accessible on internal network

### Option 3: IP Whitelist
- Firewall rules to allow specific IPs only

### Option 4: Read-Only Access
- Current setup is already read-only (no modification endpoints)
- Users can search and view, but not modify data

---

## Quick Start Checklist

**For Web Application (30 minutes):**

- [x] ✅ Backend already working
- [ ] Create web_frontend folder
- [ ] Copy HTML file
- [ ] Update API_BASE URL
- [ ] Test locally (python -m http.server)
- [ ] Deploy to production server

**For Desktop Application (1 hour):**

- [ ] Install Node.js and npm
- [ ] Create Electron project
- [ ] Copy HTML file
- [ ] Update API_BASE URL
- [ ] Test (npm start)
- [ ] Build executable (npm run build)

---

## Recommended: Start with Web

**Why web first?**
- ✅ Faster to deploy (30 minutes)
- ✅ Works on any device (PC, tablet, phone)
- ✅ Easier to update
- ✅ No installation needed
- ✅ Can make desktop version later

**Timeline:**
- Today: Deploy simple HTML version (30 min)
- Test with users (1-2 days)
- If needed: Add React version (3-5 days)
- If needed: Create desktop app (1-2 days)

---

## Next Steps

1. **Choose:** Web or Desktop?
2. **Deploy:** Follow the quick start above
3. **Test:** Try with PL11089, PL689, etc.
4. **Share:** Send URL to users

**Want me to help you deploy right now?** Just let me know!

