v2.5.6: Open-Meteo weather, WebSocket fixes, admin improvements

- Replace OpenWeatherMap with Open-Meteo (no API key needed)
  - 16-day forecast (up from 5 days)
  - Historical climate averages as fallback beyond 16 days
  - Auto-upgrade from climate to real forecast when available
- Fix Vacay WebSocket sync across devices (socket-ID exclusion instead of user-ID)
- Add GitHub release history tab in admin panel
- Show cluster count "1" for single map markers when zoomed out
- Add weather info panel in admin settings (replaces OpenWeatherMap key input)
- Update i18n translations (DE + EN)
This commit is contained in:
Maurice
2026-03-24 10:02:03 +01:00
parent faa8c84655
commit e4607e426c
22 changed files with 631 additions and 327 deletions

View File

@@ -107,23 +107,6 @@ app.use('/api/weather', weatherRoutes);
app.use('/api/settings', settingsRoutes);
app.use('/api/backup', backupRoutes);
// Exchange rates (cached 1h, authenticated)
const { authenticate: rateAuth } = require('./middleware/auth');
let _rateCache = { data: null, ts: 0 };
app.get('/api/exchange-rates', rateAuth, async (req, res) => {
const now = Date.now();
if (_rateCache.data && now - _rateCache.ts < 3600000) return res.json(_rateCache.data);
try {
const r = await fetch('https://api.frankfurter.app/latest?from=EUR');
if (!r.ok) return res.status(502).json({ error: 'Failed to fetch rates' });
const data = await r.json();
_rateCache = { data, ts: now };
res.json(data);
} catch {
res.status(502).json({ error: 'Failed to fetch rates' });
}
});
// Serve static files in production
if (process.env.NODE_ENV === 'production') {
const publicPath = path.join(__dirname, '../public');