82 lines
2.9 KiB
JavaScript
82 lines
2.9 KiB
JavaScript
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);
|
|
});
|