api-v1/routes/locationRoutes.js

222 lines
6.0 KiB
JavaScript

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;