214 lines
5.8 KiB
JavaScript
214 lines
5.8 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,
|
|
source_confidence,
|
|
selected_location,
|
|
is_saved_address,
|
|
location_type,
|
|
country,
|
|
state,
|
|
district,
|
|
city_village,
|
|
pincode,
|
|
} = req.body;
|
|
|
|
// Validate user exists if this is a saved address
|
|
let finalUserId = user_id;
|
|
if (is_saved_address && user_id) {
|
|
const userCheck = await client.query("SELECT id FROM users WHERE id = $1 AND deleted = FALSE", [user_id]);
|
|
if (userCheck.rows.length === 0) {
|
|
await client.query("ROLLBACK");
|
|
return res.status(400).json({
|
|
error: `User with id ${user_id} does not exist. Cannot create saved address for non-existent user.`
|
|
});
|
|
}
|
|
} else if (!is_saved_address) {
|
|
// For captured locations (not saved addresses), user_id can be NULL
|
|
finalUserId = null;
|
|
} else if (is_saved_address && !user_id) {
|
|
await client.query("ROLLBACK");
|
|
return res.status(400).json({
|
|
error: "user_id is required when is_saved_address is true"
|
|
});
|
|
}
|
|
|
|
// 1. Insert into locations
|
|
const insertLocationQuery = `
|
|
INSERT INTO locations (
|
|
user_id, lat, lng, source_type, source_confidence, selected_location,
|
|
is_saved_address, location_type, country, state, district, city_village, pincode
|
|
)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
|
|
RETURNING *
|
|
`;
|
|
const locationValues = [
|
|
finalUserId,
|
|
lat,
|
|
lng,
|
|
source_type || "manual",
|
|
source_confidence || "low",
|
|
selected_location || false,
|
|
is_saved_address || false,
|
|
location_type || "other",
|
|
country,
|
|
state,
|
|
district,
|
|
city_village,
|
|
pincode,
|
|
];
|
|
const locationResult = await client.query(insertLocationQuery, locationValues);
|
|
|
|
await client.query("COMMIT");
|
|
|
|
res.status(201).json({
|
|
...locationResult.rows[0],
|
|
});
|
|
} catch (err) {
|
|
await client.query("ROLLBACK");
|
|
console.error("Error creating location:", err);
|
|
|
|
// Provide more specific error messages
|
|
if (err.code === '23503') { // Foreign key violation
|
|
return res.status(400).json({
|
|
error: `Foreign key constraint violation: ${err.detail || 'The provided user_id does not exist in the users table.'}`
|
|
});
|
|
}
|
|
|
|
res.status(500).json({ error: err.message || "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 * FROM locations
|
|
WHERE user_id = $1 AND deleted = FALSE
|
|
ORDER BY 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 * FROM locations
|
|
WHERE id = $1 AND 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) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const {
|
|
lat,
|
|
lng,
|
|
source_type,
|
|
source_confidence,
|
|
selected_location,
|
|
is_saved_address,
|
|
location_type,
|
|
country,
|
|
state,
|
|
district,
|
|
city_village,
|
|
pincode,
|
|
} = req.body;
|
|
|
|
const updateQuery = `
|
|
UPDATE locations
|
|
SET lat = COALESCE($1, lat),
|
|
lng = COALESCE($2, lng),
|
|
source_type = COALESCE($3, source_type),
|
|
source_confidence = COALESCE($4, source_confidence),
|
|
selected_location = COALESCE($5, selected_location),
|
|
is_saved_address = COALESCE($6, is_saved_address),
|
|
location_type = COALESCE($7, location_type),
|
|
country = COALESCE($8, country),
|
|
state = COALESCE($9, state),
|
|
district = COALESCE($10, district),
|
|
city_village = COALESCE($11, city_village),
|
|
pincode = COALESCE($12, pincode)
|
|
WHERE id = $13 AND deleted = FALSE
|
|
RETURNING *
|
|
`;
|
|
|
|
const values = [
|
|
lat, lng, source_type, source_confidence, selected_location,
|
|
is_saved_address, location_type, country, state, district, city_village, pincode,
|
|
id
|
|
];
|
|
|
|
const result = await pool.query(updateQuery, values);
|
|
|
|
if (result.rows.length === 0) {
|
|
return res.status(404).json({ error: "Location not found" });
|
|
}
|
|
|
|
res.json(result.rows[0]);
|
|
} catch (err) {
|
|
console.error("Error updating location:", err);
|
|
res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
});
|
|
|
|
// 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" });
|
|
}
|
|
|
|
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;
|