// packages/api/v1/routes/handlers/comandas.js import { listComandas, getDetalleItems, abrirComanda, cerrarComanda, restaurarComanda, eliminarComanda as eliminarComandaRepo, patchComanda } from '../../repositories/comandasRepo.mjs'; const asBoolean = (v) => { const s = (v ?? '').toString().trim().toLowerCase(); return s === 'true' ? true : s === 'false' ? false : null; }; export async function listarComandas(req, res, next) { try { const abierta = asBoolean(req.query.abierta); const limit = req.query.limit; const rows = await listComandas({ schema: req.tenant.schema, abierta, limit }); res.json(rows); } catch (e) { next(e); } } export async function detalleComanda(req, res, next) { try { const id = parseId(req.params.id); const rows = await getDetalleItems({ schema: req.tenant.schema, id }); res.json(rows); } catch (e) { next(e); } } export async function actualizarComanda(req, res, next) { try { const id = parseId(req.params.id); const { accion, ...patch } = req.body || {}; if (accion === 'abrir') { const data = await abrirComanda({ schema: req.tenant.schema, id }); return data ? res.json(data) : res.status(404).json({ error: 'Comanda no encontrada' }); } if (accion === 'cerrar') { const data = await cerrarComanda({ schema: req.tenant.schema, id }); return data ? res.json(data) : res.status(404).json({ error: 'Comanda no encontrada' }); } if (accion === 'restaurar') { const data = await restaurarComanda({ schema: req.tenant.schema, id }); return data ? res.json(data) : res.status(404).json({ error: 'Comanda no encontrada' }); } const result = await patchComanda({ schema: req.tenant.schema, id, payload: patch }); if (!result) return res.status(404).json({ error: 'Comanda no encontrada' }); if (result?.error) return res.status(400).json({ error: result.error }); res.json(result); } catch (e) { if (e?.http?.status) return res.status(e.http.status).json({ error: e.message }); // PG codes comunes if (e?.code === '23503') return res.status(409).json({ error: 'Violación de clave foránea', detail: e.detail }); if (e?.code === '23505') return res.status(400).json({ error: 'Violación de unicidad', detail: e.detail }); if (e?.code === '23514') return res.status(400).json({ error: 'Violación de CHECK', detail: e.detail }); if (e?.code === '23502') return res.status(400).json({ error: 'Campo NOT NULL faltante', detail: e.detail }); next(e); } } export async function eliminarComanda(req, res, next) { try { const id = parseId(req.params.id); const data = await eliminarComandaRepo({ schema: req.tenant.schema, id }); return data ? res.json(data) : res.status(404).json({ error: 'Comanda no encontrada' }); } catch (e) { if (e?.http?.status) return res.status(e.http.status).json({ error: e.message }); if (e?.code === '23503') return res.status(409).json({ error: 'Violación de clave foránea', detail: e.detail }); if (e?.code === '23505') return res.status(400).json({ error: 'Violación de unicidad', detail: e.detail }); if (e?.code === '23514') return res.status(400).json({ error: 'Violación de CHECK', detail: e.detail }); if (e?.code === '23502') return res.status(400).json({ error: 'Campo NOT NULL faltante', detail: e.detail }); next(e); } } function parseId(value) { const id = Number(value); if (!Number.isInteger(id) || id <= 0) { const err = new Error('id inválido'); err.http = { status: 400 }; throw err; } return id; }