const express = require('express'); const bodyParser = require('body-parser'); const fs = require('fs').promises; const path = require('path'); const app = express(); const PORT = 3000; const DATA_DIR = process.env.DATA_DIR || '/data'; // Fallback for local dev, Docker will set via supervisord const DATA_FILE_NAME = 'weight-tracker-data.json'; const DATA_FILE_PATH = path.join(DATA_DIR, DATA_FILE_NAME); const DEFAULT_DATA = { weights: [], meals: [] }; app.use(bodyParser.json({ limit: '2mb' })); // Use body-parser to handle JSON POST requests, limit size // Middleware for basic logging app.use((req, res, next) => { console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`); next(); }); // GET endpoint to retrieve data app.get('/', async (req, res) => { try { await fs.access(DATA_FILE_PATH); const fileContent = await fs.readFile(DATA_FILE_PATH, 'utf8'); res.json(JSON.parse(fileContent)); } catch (error) { if (error.code === 'ENOENT') { // File doesn't exist, return default data console.log(`Data file not found at ${DATA_FILE_PATH}, returning default data.`); res.json(DEFAULT_DATA); } else { console.error('Error reading data file:', error); res.status(500).json({ message: 'Error reading data file', error: error.message }); } } }); // PUT endpoint to save data app.put('/', async (req, res) => { const newData = req.body; // Basic Input Validation if (typeof newData !== 'object' || newData === null) { return res.status(400).json({ message: 'Invalid data format: body must be an object.' }); } if (!Array.isArray(newData.weights)) { return res.status(400).json({ message: 'Invalid data format: weights must be an array.' }); } if (!Array.isArray(newData.meals)) { return res.status(400).json({ message: 'Invalid data format: meals must be an array.' }); } // Add more specific validation for array items if needed try { await fs.writeFile(DATA_FILE_PATH, JSON.stringify(newData, null, 2), 'utf8'); res.status(200).json({ message: 'Data saved successfully.' }); } catch (error) { console.error('Error writing data file:', error); res.status(500).json({ message: 'Error writing data file', error: error.message }); } }); app.listen(PORT, '0.0.0.0', () => { console.log(`Data API server listening on port ${PORT}`); console.log(`Expecting data file at: ${DATA_FILE_PATH}`); }); // Basic error handling for uncaught exceptions process.on('uncaughtException', (error) => { console.error('Uncaught Exception:', error); // Optionally, exit the process or perform other cleanup // process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled Rejection at:', promise, 'reason:', reason); // Optionally, exit the process or perform other cleanup // process.exit(1); });