From 2b1eefe2296744e988b365f75f07a8399dae54f4 Mon Sep 17 00:00:00 2001 From: Johannes Baumeister Date: Tue, 28 Apr 2026 12:27:04 +0200 Subject: [PATCH] chore: migrate to node.js backend to support database saving and serve static files --- Dockerfile | 2 +- app.js | 2 +- package.json | 15 +++++++++++++++ backend/server.js => server.js | 19 ++++++++++++------- 4 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 package.json rename backend/server.js => server.js (84%) diff --git a/Dockerfile b/Dockerfile index cc36a2c..63b3cf3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,4 +10,4 @@ COPY . . # Der Server läuft auf Port 3000 EXPOSE 3000 -CMD ["node", "server.js"] \ No newline at end of file +CMD ["node", "server.js"] diff --git a/app.js b/app.js index b905b9b..fb72b15 100644 --- a/app.js +++ b/app.js @@ -1434,7 +1434,7 @@ document.addEventListener('DOMContentLoaded', async () => { })); try { - const response = await fetch('http://localhost:3000/api/wea', { + const response = await fetch('/api/wea', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ projekt_id, turbines: turbineData }) diff --git a/package.json b/package.json new file mode 100644 index 0000000..64326c4 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "bwsamern-ohne-planungstool", + "version": "1.0.0", + "main": "server.js", + "dependencies": { + "body-parser": "^1.20.2", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.19.2", + "pg": "^8.11.5" + }, + "scripts": { + "start": "node server.js" + } +} diff --git a/backend/server.js b/server.js similarity index 84% rename from backend/server.js rename to server.js index 84db9cc..f7a026d 100644 --- a/backend/server.js +++ b/server.js @@ -3,6 +3,7 @@ const express = require('express'); const { Pool } = require('pg'); const bodyParser = require('body-parser'); const cors = require('cors'); +const path = require('path'); const app = express(); const port = process.env.PORT || 3000; @@ -10,6 +11,9 @@ const port = process.env.PORT || 3000; app.use(cors()); app.use(bodyParser.json()); +// Serve static files from the root directory +app.use(express.static(path.join(__dirname, './'))); + const pool = new Pool({ host: process.env.DB_HOST, port: process.env.DB_PORT, @@ -20,7 +24,7 @@ const pool = new Pool({ // Test DB Connection pool.connect() - .then(() => console.log('Connected to PostgreSQL (enwelo_db) successfully')) + .then(() => console.log('Connected to PostgreSQL successfully')) .catch(err => console.error('Connection error', err.stack)); // API to save turbines @@ -32,13 +36,9 @@ app.post('/api/wea', async (req, res) => { await client.query('BEGIN'); // Delete existing turbines for this project before saving new state - // (This ensures we always have the latest state on 'Save') await client.query('DELETE FROM geodaten.wea_standorte WHERE projekt_id = $1', [projekt_id]); for(let t of turbines) { - // Mapping frontend data to geodaten.wea_standorte columns: - // wea_nummer, hersteller, anlagentyp, nabenhoehe, rotordurchmesser, ksf_drehung, projekt_id, geom - await client.query( `INSERT INTO geodaten.wea_standorte ( wea_nummer, hersteller, anlagentyp, nabenhoehe, rotordurchmesser, ksf_drehung, projekt_id, geom @@ -85,6 +85,11 @@ app.get('/api/wea/:projekt_id', async (req, res) => { } }); -app.listen(port, () => { - console.log(`Backend server listening at http://localhost:${port}`); +// Catch-all route to serve index.html for any other request (optional, good for SPAs) +app.get('*', (req, res) => { + res.sendFile(path.join(__dirname, 'index.html')); +}); + +app.listen(port, '0.0.0.0', () => { + console.log(`Server running at http://0.0.0.0:${port}`); });