Files
temp-history-api/routes/entities.js
AzenKain ea1e12a5bc
Some checks failed
Build and Release / release (push) Failing after 16s
init
2026-04-20 09:29:40 +07:00

104 lines
2.6 KiB
JavaScript

const express = require("express");
const db = require("../db/polygons");
const router = express.Router();
router.get("/", (req, res) => {
const search = typeof req.query.q === "string" ? req.query.q.trim() : "";
let sql = `
SELECT
e.*,
COUNT(eg.geometry_id) AS geometry_count
FROM entities e
LEFT JOIN entity_geometries eg
ON eg.entity_id = e.id
WHERE e.is_deleted = 0
`;
const params = [];
if (search) {
sql += " AND (e.name LIKE ? OR e.slug LIKE ?)";
const pattern = `%${search}%`;
params.push(pattern, pattern);
}
sql += `
GROUP BY e.id
ORDER BY e.name COLLATE NOCASE ASC
`;
const rows = db.prepare(sql).all(...params);
res.json(rows.map(normalizeEntityRow));
});
router.get("/search", (req, res) => {
const name = typeof req.query.name === "string" ? req.query.name.trim() : "";
const limit = normalizeLimit(req.query.limit, 25, 100);
if (!name) {
return res.json([]);
}
const pattern = `%${name}%`;
const rows = db.prepare(`
SELECT
e.*,
COUNT(eg.geometry_id) AS geometry_count
FROM entities e
LEFT JOIN entity_geometries eg
ON eg.entity_id = e.id
WHERE e.is_deleted = 0
AND e.name LIKE ?
GROUP BY e.id
ORDER BY e.name COLLATE NOCASE ASC
LIMIT ?
`).all(pattern, limit);
res.json(rows.map(normalizeEntityRow));
});
router.get("/:id", (req, res) => {
const row = db.prepare(`
SELECT
e.*,
COUNT(eg.geometry_id) AS geometry_count
FROM entities e
LEFT JOIN entity_geometries eg
ON eg.entity_id = e.id
WHERE e.id = ?
AND e.is_deleted = 0
GROUP BY e.id
`).get(req.params.id);
if (!row) {
return res.status(404).json({ error: "Entity not found" });
}
res.json(normalizeEntityRow(row));
});
module.exports = router;
function normalizeEntityRow(row) {
return {
id: row.id,
name: row.name,
slug: row.slug,
description: row.description,
type_id: row.type_id,
status: row.status,
created_at: row.created_at,
updated_at: row.updated_at,
geometry_count: Number(row.geometry_count || 0),
};
}
function normalizeLimit(value, fallback = 25, max = 100) {
const num = Number(value);
if (!Number.isFinite(num)) return fallback;
const intValue = Math.trunc(num);
if (intValue <= 0) return fallback;
return Math.min(intValue, max);
}