diff --git a/web-app/package.json b/web-app/package.json index 9c3a400..5b7412b 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -15,8 +15,8 @@ "dependencies": { "@google/genai": "^1.25.0", "@tailwindcss/postcss": "^4.1.14", - "@tailwindcss/vite": "^4.1.14", - "@vitejs/plugin-react": "^5.0.4", + "@tailwindcss/vite": "^4.1.14", + "@vitejs/plugin-react-swc": "^3.7.0", "bootstrap": "^5.3.8", "bootstrap-icons": "^1.13.1", "class-variance-authority": "^0.7.1", @@ -26,6 +26,7 @@ "helmet": "^8.1.0", "lucide-react": "^0.546.0", "motion": "^12.23.24", + "node-fetch": "^3.3.2", "pg": "^8.16.3", "react": "^19.2.0", "react-bootstrap": "^2.10.10", diff --git a/web-app/server.mjs b/web-app/server.mjs index cca7665..ba4431c 100644 --- a/web-app/server.mjs +++ b/web-app/server.mjs @@ -2,25 +2,35 @@ import express from 'express'; import path from 'node:path'; import helmet from 'helmet'; import cors from 'cors'; +import fetch from 'node-fetch'; import { fileURLToPath } from 'node:url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); -const PORT = process.env.PORT || 3000; -const RUST_ENGINE_BASE = process.env.RUST_ENGINE_BASE || 'http://rust-engine:8000'; +const PORT = Number(process.env.PORT) || 3000; +const HOST = process.env.HOST || '0.0.0.0'; +const RUST_ENGINE_BASE = + process.env.RUST_ENGINE_BASE || + process.env.RUST_ENGINE_URL || + 'http://rust-engine:8000'; -app.use(helmet()); +app.set('trust proxy', true); +app.use(helmet({ contentSecurityPolicy: false })); app.use(cors()); app.use(express.json()); +app.get('/api/healthz', (_req, res) => { + res.json({ status: 'ok', upstream: RUST_ENGINE_BASE }); +}); + // Proxy minimal API needed by the UI to the rust-engine container app.post('/api/files/import-demo', async (req, res) => { try { const qs = req.url.includes('?') ? req.url.substring(req.url.indexOf('?')) : ''; const url = `${RUST_ENGINE_BASE}/api/files/import-demo${qs}`; - const upstream = await fetch(url, { method: 'POST' }); + const upstream = await fetch(url, { method: 'POST', headers: { 'content-type': 'application/json' }, body: req.body ? JSON.stringify(req.body) : undefined }); const text = await upstream.text(); res.status(upstream.status).type(upstream.headers.get('content-type') || 'application/json').send(text); } catch (err) { @@ -38,7 +48,7 @@ app.get('*', (req, res) => { res.sendFile(path.join(distDir, 'index.html')); }); -app.listen(PORT, '0.0.0.0', () => { - console.log(`Web app server listening on http://0.0.0.0:${PORT}`); +app.listen(PORT, HOST, () => { + console.log(`Web app server listening on http://${HOST}:${PORT}`); console.log(`Proxying to rust engine at ${RUST_ENGINE_BASE}`); }); diff --git a/web-app/vite.config.js b/web-app/vite.config.js index 489ef37..a0cbe7b 100644 --- a/web-app/vite.config.js +++ b/web-app/vite.config.js @@ -1,5 +1,5 @@ import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; +import react from "@vitejs/plugin-react-swc"; import jsconfigPaths from "vite-jsconfig-paths"; import tailwindcss from "@tailwindcss/vite";