import express from "express"; import pool from "../db/pool.js"; const router = express.Router(); // 1. CREATE Location router.post("/", async (req, res) => { const client = await pool.connect(); try { await client.query("BEGIN"); const { user_id, lat, lng, source_type, // Location Details is_saved_address, location_type, country, state, district, city_village, pincode, } = req.body; // 1. Insert into locations const insertLocationQuery = ` INSERT INTO locations (user_id, lat, lng, source_type) VALUES ($1, $2, $3, $4) RETURNING id, user_id, lat, lng, source_type, created_at `; const locationValues = [user_id, lat, lng, source_type || "manual"]; const locationResult = await client.query(insertLocationQuery, locationValues); const location = locationResult.rows[0]; // 2. Insert into location_details const insertDetailsQuery = ` INSERT INTO location_details ( location_id, is_saved_address, location_type, country, state, district, city_village, pincode ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING * `; const detailsValues = [ location.id, is_saved_address || false, location_type || "other", country, state, district, city_village, pincode, ]; const detailsResult = await client.query(insertDetailsQuery, detailsValues); await client.query("COMMIT"); res.status(201).json({ ...location, details: detailsResult.rows[0], }); } catch (err) { await client.query("ROLLBACK"); console.error("Error creating location:", err); res.status(500).json({ error: "Internal server error" }); } finally { client.release(); } }); // 2. GET User Locations router.get("/user/:userId", async (req, res) => { try { const { userId } = req.params; const queryText = ` SELECT l.*, row_to_json(ld) as details FROM locations l LEFT JOIN location_details ld ON l.id = ld.location_id WHERE l.user_id = $1 AND l.deleted = FALSE ORDER BY l.created_at DESC `; const result = await pool.query(queryText, [userId]); res.json(result.rows); } catch (err) { console.error("Error fetching user locations:", err); res.status(500).json({ error: "Internal server error" }); } }); // 3. GET Single Location router.get("/:id", async (req, res) => { try { const { id } = req.params; const queryText = ` SELECT l.*, row_to_json(ld) as details FROM locations l LEFT JOIN location_details ld ON l.id = ld.location_id WHERE l.id = $1 AND l.deleted = FALSE `; const result = await pool.query(queryText, [id]); if (result.rows.length === 0) { return res.status(404).json({ error: "Location not found" }); } res.json(result.rows[0]); } catch (err) { console.error("Error fetching location:", err); res.status(500).json({ error: "Internal server error" }); } }); // 4. UPDATE Location router.put("/:id", async (req, res) => { const client = await pool.connect(); try { const { id } = req.params; const { lat, lng, source_type, // Location Details is_saved_address, location_type, country, state, district, city_village, pincode, } = req.body; await client.query("BEGIN"); // 1. Update locations const updateLocationQuery = ` UPDATE locations SET lat = COALESCE($1, lat), lng = COALESCE($2, lng), source_type = COALESCE($3, source_type) WHERE id = $4 AND deleted = FALSE RETURNING * `; const locationResult = await client.query(updateLocationQuery, [lat, lng, source_type, id]); if (locationResult.rows.length === 0) { await client.query("ROLLBACK"); return res.status(404).json({ error: "Location not found" }); } // 2. Update location_details // Note: location_details might not exist depending on legacy data, so we use ON CONFLICT or just UPDATE/INSERT logic. // For simplicity and assuming details always exist creation: const updateDetailsQuery = ` UPDATE location_details SET is_saved_address = COALESCE($1, is_saved_address), location_type = COALESCE($2, location_type), country = COALESCE($3, country), state = COALESCE($4, state), district = COALESCE($5, district), city_village = COALESCE($6, city_village), pincode = COALESCE($7, pincode) WHERE location_id = $8 RETURNING * `; const detailsResult = await client.query(updateDetailsQuery, [ is_saved_address, location_type, country, state, district, city_village, pincode, id, ]); await client.query("COMMIT"); res.json({ ...locationResult.rows[0], details: detailsResult.rows[0] || null, }); } catch (err) { await client.query("ROLLBACK"); console.error("Error updating location:", err); res.status(500).json({ error: "Internal server error" }); } finally { client.release(); } }); // 5. DELETE Location router.delete("/:id", async (req, res) => { try { const { id } = req.params; const queryText = ` UPDATE locations SET deleted = TRUE WHERE id = $1 RETURNING id `; const result = await pool.query(queryText, [id]); if (result.rows.length === 0) { return res.status(404).json({ error: "Location not found" }); } // Optionally mark details as deleted if they had a deleted column, but they don't seem to based on schema view earlier? // Checking schema: location_details has 'deleted'. await pool.query("UPDATE location_details SET deleted = TRUE WHERE location_id = $1", [id]); res.json({ message: "Location deleted successfully" }); } catch (err) { console.error("Error deleting location:", err); res.status(500).json({ error: "Internal server error" }); } }); export default router;