const express = require("express"); const db = require("../db/polygons"); const { normalizeEntityContract } = require("../types/contracts"); 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(normalizeEntityContract)); }); 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(normalizeEntityContract)); }); 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(normalizeEntityContract(row)); }); module.exports = router; 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); }