const locationMapModel = require("../models/location-map.model"); const { sendError } = require("../utils/http"); const { logError } = require("../utils/logger"); function parsePositiveInteger(value) { const parsed = Number.parseInt(String(value), 10); return Number.isInteger(parsed) && parsed > 0 ? parsed : null; } function canManageMaps(req) { return ["owner", "admin"].includes(req.household?.role); } function getScope(req) { return { householdId: parsePositiveInteger(req.params.householdId), locationId: parsePositiveInteger(req.params.locationId), }; } function validateScope(res, scope) { if (!scope.householdId || !scope.locationId) { sendError(res, 400, "Household ID and location ID must be positive integers"); return false; } return true; } function sendMapState(res, state, req) { if (!state) { return sendError(res, 404, "Store location not found"); } return res.json({ ...state, can_manage: canManageMaps(req), }); } exports.getLocationMap = async (req, res) => { const scope = getScope(req); if (!validateScope(res, scope)) return; try { const state = await locationMapModel.getMapState( scope.householdId, scope.locationId, canManageMaps(req) ); sendMapState(res, state, req); } catch (error) { logError(req, "locationMaps.getLocationMap", error); sendError(res, 500, "Failed to load location map"); } }; exports.createBlankMap = async (req, res) => { const scope = getScope(req); if (!validateScope(res, scope)) return; try { const state = await locationMapModel.saveBlankDraft( scope.householdId, scope.locationId, req.user.id, req.body?.map || req.body || {} ); res.status(201); sendMapState(res, state, req); } catch (error) { logError(req, "locationMaps.createBlankMap", error); sendError(res, 500, "Failed to create blank map"); } }; exports.createMapFromZones = async (req, res) => { const scope = getScope(req); if (!validateScope(res, scope)) return; try { const state = await locationMapModel.createDraftFromZones( scope.householdId, scope.locationId, req.user.id, req.body?.map || req.body || {} ); res.status(201); sendMapState(res, state, req); } catch (error) { logError(req, "locationMaps.createMapFromZones", error); sendError(res, 500, "Failed to create map from zones"); } }; exports.saveDraft = async (req, res) => { const scope = getScope(req); if (!validateScope(res, scope)) return; try { const state = await locationMapModel.saveDraft( scope.householdId, scope.locationId, req.user.id, req.body || {} ); sendMapState(res, state, req); } catch (error) { logError(req, "locationMaps.saveDraft", error); sendError(res, 500, "Failed to save map draft"); } }; exports.publishDraft = async (req, res) => { const scope = getScope(req); if (!validateScope(res, scope)) return; try { const state = await locationMapModel.publishDraft( scope.householdId, scope.locationId, req.user.id ); if (!state) { return sendError(res, 404, "No draft map to publish"); } sendMapState(res, state, req); } catch (error) { logError(req, "locationMaps.publishDraft", error); sendError(res, 500, "Failed to publish map"); } };