🗄️ Documentación de Base de Datos — PostgreSQL
Índice
- Filosofía de Diseño
- Conexión
- Funciones SQL por Dominio
- Tablas Principales (Inferidas)
- Patrones de Datos
- JSONB como Patrón de Intercambio
- Integraciones que Escriben en JSONB
- Guía para Modificar Funciones SQL
Filosofía de Diseño
Este sistema sigue un patrón "Database-First" donde la lógica de negocio reside principalmente en funciones SQL almacenadas de PostgreSQL. Los controllers de Node.js actúan como una capa de presentación HTTP liviana que solo orquesta llamadas a estas funciones.
Implicaciones:
- Para modificar lógica de negocio, debes modificar las funciones SQL, no solo el JavaScript.
- Los controllers pasan parámetros posicionales (
$1, $2) y reciben resultados directamente.
- No hay ORM ni capa de abstracción de base de datos.
Conexión
El backend usa pg (node-postgres) con un Pool:
Variables de entorno requeridas: DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME.
Funciones SQL por Dominio
🔐 Autenticación
| Función |
Parámetros |
Retorno |
Descripción |
validarusuario(name_mail_user, user_pass) |
text, text |
{status, rol, user_id, user_name} |
Valida credenciales |
createuser(name_user, id_rol, email, user_pass) |
text, int, text, text |
status |
Crea usuario |
reppassuser(user_mail, new_pass) |
text, text |
status |
Reemplaza contraseña |
👥 Empleados
| Función |
Parámetros |
Retorno |
Descripción |
getemployees() |
— |
setof record |
Lista paginada de empleados |
activeemployeesnumber() |
— |
int |
Total de empleados activos |
getoneemployee(rfcEmployee) |
text |
setof record |
Un empleado por RFC |
newemployee(...) |
12 parámetros |
status |
Inserta empleado |
updateemployee(...) |
12 parámetros |
status |
Actualiza empleado |
getattendance() |
— |
setof record |
Registros de asistencia |
📄 Contratos
| Función |
Parámetros |
Retorno |
Descripción |
getcontracts() |
— |
setof record |
Lista de contratos |
getinfocontract(id) |
int |
setof record |
Info de un contrato |
neartoend() |
— |
setof record |
Contratos próximos a vencer |
newcontract(...) |
varios |
status |
Crea contrato |
updatecontract(...) |
varios |
status |
Actualiza contrato |
positions() |
— |
setof record |
Catálogo de puestos |
areas() |
— |
setof record |
Catálogo de áreas |
bosses() |
— |
setof record |
Catálogo de jefes |
📦 Productos / Inventario
| Función |
Parámetros |
Retorno |
Descripción |
getproducts() |
— |
setof record |
Lista de productos |
getoneproduct(id) |
int |
setof record |
Un producto |
newproduct(..., jsonb, ...) |
11 parámetros |
status |
Crea producto |
updateproduct(..., jsonb, ...) |
12 parámetros |
status |
Actualiza producto |
discardproductsstock(id, quantity, reasons) |
int, numeric, text |
status |
Descarta stock |
getdiscardproduct() |
— |
setof record |
Productos descartados |
report_inventoryv2() |
— |
setof record |
Reporte de inventario |
stockadjusment() |
— |
setof record |
Ajustes pendientes |
setstockadjusmentsv2(jsonb) |
jsonb |
stockadjus |
Aplica ajustes |
consumptionstock(product_id, quantity, date, rfc) |
varios |
status |
Registra consumo |
getconsumptionreport() |
— |
setof record |
Reporte de consumos |
newsupplier(name, rfc, mail, phone) |
4 parámetros |
status |
Crea proveedor |
updatesupplier(id, name, rfc, mail, phone) |
5 parámetros |
status |
Actualiza proveedor |
disableSuppliers(id) |
int |
status |
Deshabilita proveedor |
newsuplier(...) |
varios |
status |
(posible duplicado ortográfico) |
💰 Gastos (Expenses)
| Función |
Parámetros |
Retorno |
Descripción |
newexpensev2(..., jsonb, ...) |
14 parámetros |
status |
Crea gasto |
updateexpensev4(..., jsonb) |
15 parámetros |
status |
Actualiza gasto |
getexpense(id) |
int |
setof record |
Obtiene un gasto |
getpendingappexpenses() |
— |
setof record |
Gastos pendientes de aprobación |
getapprovedappexpenses() |
— |
setof record |
Gastos aprobados |
getrejectedappexpenses() |
— |
setof record |
Gastos rechazados |
setapprovalstatus(id, status, approved_by) |
3 parámetros |
status |
Actualiza estado de aprobación |
setpaymentstatusv2(id, status) |
2 parámetros |
status |
Actualiza estado de pago |
pendingapppayments() |
— |
setof record |
Pagos pendientes |
countdelaypayments() |
— |
int |
Pagos con retraso |
totalspent() |
— |
numeric |
Total gastado |
totalapproved() |
— |
numeric |
Total aprobado |
totalrejected() |
— |
numeric |
Total rechazado |
report_expenses() |
— |
setof record |
Reporte de gastos |
paymentsreport() |
— |
setof record |
Reporte de pagos |
mainsupplier() |
— |
setof record |
Proveedor principal |
gettaxes() |
— |
setof record |
Catálogo de impuestos |
🛒 Compras / Purchase Entries
| Función |
Parámetros |
Retorno |
Descripción |
getpurchases() |
— |
setof record |
Detalles de compras pendientes |
purchaseentry(id, checking) |
int, int |
status |
Registra recepción física |
💳 Pagos Mensuales
| Función |
Parámetros |
Retorno |
Descripción |
newmonthlyexpensev2(...) |
10 parámetros |
status |
Crea gasto mensual |
updatemonthlyexpensev2(...) |
11 parámetros |
status |
Actualiza gasto mensual |
setpaymentstatusmonthlyv2(id, status) |
2 parámetros |
status |
Actualiza estado de pago |
setpaymentstatusmonthlyv2(id, status, tax_id, total) |
4 parámetros |
status |
Actualiza estado y monto |
refresh_monthly_expenses() |
— |
status |
Refresca gastos mensuales |
getmonthlypayments() |
— |
setof record |
Lista de pagos mensuales |
getONEmonthlypayment(id) |
int |
setof record |
Un pago mensual |
needToRefresh(id, boolean) |
2 parámetros |
rows |
Controla actualización automática |
📧 Emails Programáticos
| Función |
Parámetros |
Retorno |
Descripción |
validateendpoint(endpoint_name) |
text |
boolean |
Verifica si se puede ejecutar (1x/mes) |
nearexpiring() |
— |
setof record |
Contratos por vencer |
paymentdelay() |
— |
setof record |
Pagos atrasados |
expensesneartodeadline() |
— |
setof record |
Gastos próximos a fecha límite |
expensesspecial() |
— |
setof record |
Gastos especiales |
birthdays() |
— |
setof record |
Cumpleaños |
contractexpired() |
— |
setof record |
Contratos vencidos |
expiredcontractsmonth() |
— |
setof record |
Contratos vencidos del mes |
📊 Ingresos (Little Hotelier)
| Función |
Parámetros |
Retorno |
Descripción |
getincomes(...) |
varios (filtros) |
setof record |
Lista de ingresos |
totalincomes(...) |
varios |
numeric |
Total de ingresos |
channelscards(...) |
varios |
setof record |
Canales de ingreso |
loadincomes(jsonb) |
jsonb |
status |
Carga masiva de ingresos |
loadproductsales(jsonb) |
jsonb |
status |
Carga masiva de ventas de productos |
loadchequesdetalle(jsonb) |
jsonb |
status |
Carga masiva de cheques |
reportincomes(...) |
varios |
setof record |
Reporte de ingresos |
countticket(...) |
varios |
int |
Conteo de tickets |
efectivo(...), otros(...), propinas(...), tarjeta(...), vales(...) |
varios |
numeric |
Desglose por tipo de pago |
sumatotal(...) |
varios |
numeric |
Suma total |
ticketpromedio(...) |
varios |
numeric |
Ticket promedio |
🏨 Horux / Facturas / Stripe
| Función |
Parámetros |
Retorno |
Descripción |
addhoruxdata(jsonb) |
jsonb |
int (total insertados) |
Inserta facturas masivamente |
getcategoryincome() |
— |
setof record |
Categorías de ingreso |
getinvoiceincome() |
— |
setof record |
Facturas de ingreso |
getaccountincome() |
— |
setof record |
Cuentas de ingreso |
getincomehorux() |
— |
setof record |
Ingresos Horux |
gettotalincome() |
— |
numeric |
Total de ingresos Horux |
getoneincome(id) |
int |
setof record |
Un ingreso Horux |
newincome(account_id, amount, date, invoice, area_id, categories::jsonb) |
6 parámetros |
status |
Crea ingreso Horux |
updateincome(id, account_id, amount, date, invoice, area_id, categories::jsonb) |
7 parámetros |
status |
Actualiza ingreso Horux |
addstripedatav2(jsonb) |
jsonb |
int (inserted) |
Inserta datos de Stripe |
📈 Hotel P&L / Restaurant P&L
| Función |
Parámetros |
Retorno |
Descripción |
cogs(...) |
varios (fechas) |
setof record |
Cost of Goods Sold |
ebitda(...) |
varios |
setof record |
EBITDA |
employeeshare(...) |
varios |
setof record |
Participación de empleados |
grossprofit(...) |
varios |
setof record |
Ganancia bruta |
tips(...) |
varios |
setof record |
Propinas |
totalrevenue(...) |
varios |
setof record |
Ingresos totales |
weightedCategoriesCost(...) |
varios |
setof record |
Costos ponderados por categoría |
💱 Tipo de Cambio
| Función |
Parámetros |
Retorno |
Descripción |
consultexchange(...) |
varios |
setof record |
Consulta tipo de cambio |
getexchanges() |
— |
setof record |
Historial de tipos de cambio |
⚙️ Configuraciones
| Función |
Parámetros |
Retorno |
Descripción |
newroom(...) |
varios |
status |
Crea habitación |
newproperty(...) |
varios |
status |
Crea propiedad |
reportrooms() |
— |
setof record |
Reporte de habitaciones |
reportproperties() |
— |
setof record |
Reporte de propiedades |
approveby() |
— |
setof record |
Usuarios que pueden aprobar |
requestby() |
— |
setof record |
Usuarios que pueden solicitar |
categoryexpense() |
— |
setof record |
Categorías de gasto |
currency() |
— |
setof record |
Monedas |
units() |
— |
setof record |
Unidades de medida |
recurrence() |
— |
setof record |
Recurrencias (mensual, etc.) |
Tablas Principales (Inferidas)
Basado en las funciones SQL y los controllers, las tablas principales son:
| Tabla |
Propósito |
employees |
Datos de empleados |
contracts |
Contratos laborales |
products |
Catálogo de productos |
suppliers |
Proveedores |
expenses |
Gastos/egresos |
purchase_details |
Líneas de compra asociadas a gastos |
inventory_entries / stock_movements |
Movimientos de inventario |
incomes |
Ingresos de Little Hotelier |
income_hrx |
Ingresos de Horux |
invoice_income |
Facturas descargadas |
stripe_data |
Datos de transfers de Stripe |
users |
Usuarios del sistema |
roles |
Roles de usuario |
areas |
Áreas del hotel |
positions |
Puestos de trabajo |
endpoint_logs |
Control de ejecución de emails (1x/mes) |
settings_rooms |
Habitaciones |
settings_properties |
Propiedades |
Patrones de Datos
Paginación Manual
Estados Numéricos
Muchas funciones retornan un status numérico:
1 = Éxito
0 = Error/No permitido
-3 = Condición no cumplida (ej. "gasto no aprobado")
- Otros negativos = Errores específicos
JSONB como Patrón de Intercambio
El sistema usa extensivamente jsonb para pasar datos complejos:
Ejemplo: Productos en un Gasto
Ejemplo: Ajustes de Stock
Ejemplo: Facturas Masivas
Integraciones que Escriben en JSONB
| Integración |
Función SQL |
Tabla Destino |
| Little Hotelier (CSV/XLSX) |
loadincomes(jsonb) |
incomes |
| Facturas API (México) |
addhoruxdata(jsonb) |
income_hrx / invoice_income |
| Stripe |
addstripedatav2(jsonb) |
stripe_data |
Guía para Modificar Funciones SQL
Paso 1: Verificar Dependencias
Busca TODOS los controllers que llaman a la función:
Paso 2: Probar en PostgreSQL Directamente
Paso 3: Considerar Idempotencia
Si la función modifica datos (INSERT/UPDATE), considera:
- ¿Qué pasa si se llama dos veces con los mismos parámetros?
- ¿Debería usar
ON CONFLICT o verificar IF EXISTS?
Paso 4: Actualizar Controllers si Cambia la Firma
Si agregas/quitas parámetros, actualiza TODOS los pool.query(...) que la llaman.
Paso 5: Documentar el Cambio
Actualiza este archivo (docs/DATABASE.md) y DOCUMENTACION_TECNICA.md.