refactoring
This commit is contained in:
95
server.js
95
server.js
@@ -11,6 +11,7 @@ const { scheduleConfig } = require('./services/pickupScheduler');
|
||||
const adminConfig = require('./services/adminConfig');
|
||||
const { readNotificationSettings, writeNotificationSettings } = require('./services/userSettingsStore');
|
||||
const notificationService = require('./services/notificationService');
|
||||
const { readStoreWatch, writeStoreWatch } = require('./services/storeWatchStore');
|
||||
|
||||
const ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;
|
||||
const adminEmail = (process.env.ADMIN_EMAIL || '').toLowerCase();
|
||||
@@ -20,6 +21,8 @@ const app = express();
|
||||
const port = process.env.PORT || 3000;
|
||||
const storeRefreshJobs = new Map();
|
||||
const cachedStoreSnapshots = new Map();
|
||||
const regionStoreCache = new Map();
|
||||
const REGION_STORE_CACHE_MS = 15 * 60 * 1000;
|
||||
|
||||
app.use(cors());
|
||||
app.use(express.json({ limit: '1mb' }));
|
||||
@@ -88,6 +91,25 @@ function mergeStoresIntoConfig(config = [], stores = []) {
|
||||
return { merged: Array.from(map.values()), changed };
|
||||
}
|
||||
|
||||
function getCachedRegionStores(regionId) {
|
||||
const entry = regionStoreCache.get(String(regionId));
|
||||
if (!entry) {
|
||||
return null;
|
||||
}
|
||||
if (Date.now() - entry.fetchedAt > REGION_STORE_CACHE_MS) {
|
||||
regionStoreCache.delete(String(regionId));
|
||||
return null;
|
||||
}
|
||||
return entry.payload;
|
||||
}
|
||||
|
||||
function setCachedRegionStores(regionId, payload) {
|
||||
regionStoreCache.set(String(regionId), {
|
||||
fetchedAt: Date.now(),
|
||||
payload
|
||||
});
|
||||
}
|
||||
|
||||
function isStoreCacheFresh(session) {
|
||||
if (!session?.storesCache?.fetchedAt) {
|
||||
return false;
|
||||
@@ -368,6 +390,79 @@ app.get('/api/profile', requireAuth, async (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/store-watch/regions', requireAuth, async (req, res) => {
|
||||
try {
|
||||
const details = await foodsharingClient.fetchProfile(req.session.cookieHeader);
|
||||
const regions = Array.isArray(details?.regions)
|
||||
? details.regions.filter((region) => Number(region?.classification) === 1)
|
||||
: [];
|
||||
res.json({ regions });
|
||||
} catch (error) {
|
||||
console.error('[STORE-WATCH] Regionen konnten nicht geladen werden:', error.message);
|
||||
res.status(500).json({ error: 'Regionen konnten nicht geladen werden' });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/store-watch/regions/:regionId/stores', requireAuth, async (req, res) => {
|
||||
const { regionId } = req.params;
|
||||
if (!regionId) {
|
||||
return res.status(400).json({ error: 'Region-ID fehlt' });
|
||||
}
|
||||
const forceRefresh = req.query.force === '1';
|
||||
if (!forceRefresh) {
|
||||
const cached = getCachedRegionStores(regionId);
|
||||
if (cached) {
|
||||
return res.json(cached);
|
||||
}
|
||||
}
|
||||
try {
|
||||
const result = await foodsharingClient.fetchRegionStores(regionId, req.session.cookieHeader);
|
||||
const payload = {
|
||||
total: Number(result?.total) || 0,
|
||||
stores: Array.isArray(result?.stores) ? result.stores : []
|
||||
};
|
||||
setCachedRegionStores(regionId, payload);
|
||||
res.json(payload);
|
||||
} catch (error) {
|
||||
console.error(`[STORE-WATCH] Stores für Region ${regionId} konnten nicht geladen werden:`, error.message);
|
||||
res.status(500).json({ error: 'Betriebe konnten nicht geladen werden' });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/store-watch/subscriptions', requireAuth, (req, res) => {
|
||||
const stores = readStoreWatch(req.session.profile.id);
|
||||
res.json({ stores });
|
||||
});
|
||||
|
||||
app.post('/api/store-watch/subscriptions', requireAuth, (req, res) => {
|
||||
if (!req.body || !Array.isArray(req.body.stores)) {
|
||||
return res.status(400).json({ error: 'Erwartet eine Liste von Betrieben' });
|
||||
}
|
||||
const previous = readStoreWatch(req.session.profile.id);
|
||||
const previousMap = new Map(previous.map((entry) => [entry.storeId, entry]));
|
||||
const normalized = [];
|
||||
req.body.stores.forEach((store) => {
|
||||
const storeId = store?.storeId || store?.id;
|
||||
const regionId = store?.regionId || store?.region?.id;
|
||||
if (!storeId || !regionId) {
|
||||
return;
|
||||
}
|
||||
const entry = {
|
||||
storeId: String(storeId),
|
||||
storeName: store?.storeName || store?.name || `Store ${storeId}`,
|
||||
regionId: String(regionId),
|
||||
regionName: store?.regionName || store?.region?.name || '',
|
||||
lastTeamSearchStatus: previousMap.get(String(storeId))?.lastTeamSearchStatus ?? null
|
||||
};
|
||||
normalized.push(entry);
|
||||
});
|
||||
|
||||
const persisted = writeStoreWatch(req.session.profile.id, normalized);
|
||||
const config = readConfig(req.session.profile.id);
|
||||
scheduleWithCurrentSettings(req.session.id, config);
|
||||
res.json({ success: true, stores: persisted });
|
||||
});
|
||||
|
||||
app.get('/api/config', requireAuth, (req, res) => {
|
||||
const config = readConfig(req.session.profile.id);
|
||||
res.json(config);
|
||||
|
||||
Reference in New Issue
Block a user