Use this file to discover all available pages before exploring further.
All persistent data for Botica Nova Salud lives in a single MySQL 8 database named BoticaNovaSalud_Final. The application layer never issues ad-hoc SQL against the business tables. Instead, every API endpoint calls a named stored procedure, and two triggers on the Detalle_Ventas table enforce stock rules automatically within each transaction.
The backend creates a mysql2 promise-based connection pool configured from environment variables:
db.js
const mysql = require('mysql2/promise');const pool = mysql.createPool({ host: process.env.DB_HOST || 'localhost', user: process.env.DB_USER || 'root', password: process.env.DB_PASSWORD || '', database: process.env.DB_NAME || 'BoticaNovaSalud_Final', port: process.env.DB_PORT || 3306, waitForConnections: true, connectionLimit: 10, queueLimit: 0, multipleStatements: true // required for SPs that return multiple result sets});
multipleStatements: true is required specifically for sp_get_venta_detalle, which returns two result sets in one call: the sale header (cabecera) and the line items (detalle).
Two triggers fire automatically on the Detalle_Ventas table whenever a sale line item is inserted. The application does not need to manage stock — the database handles it transactionally.
Before each line item is inserted, this trigger checks whether the current stock is sufficient to fulfil the requested quantity. If stock is insufficient, the trigger raises a signal error, which aborts the entire transaction and rolls back the sale.
Trigger: trg_validar_stock_antes_ventaEvent: BEFORE INSERT ON Detalle_VentasEffect: Raises SQLSTATE '45000' if stock < quantity required. The full sale transaction is rolled back automatically.
After a line item is successfully inserted, this trigger deducts the sold quantity from stock_actual_unidades, taking the product’s unit equivalence into account.
Trigger: trg_reducir_stock_post_ventaEvent: AFTER INSERT ON Detalle_VentasEffect: Deducts (quantity × unit_equivalence) from stock_actual_unidades.Example: selling 2 blisters of Paracetamol (10 units/blister) → deducts 2 × 10 = 20 units from stock
Internally, the route handler calls CALL sp_registrar_venta(...) with the sale data. The stored procedure inserts the header and each line item, at which point:
trg_validar_stock_antes_venta fires before each insert — if any line fails, the whole call is aborted.
trg_reducir_stock_post_venta fires after each successful insert and deducts stock.
The procedure returns id_venta, serie, numero_doc, and mensaje as OUT parameters.
To inspect or modify stored procedures and triggers, open boticanovasalud_final.sql — it contains the full database definition including all tables, seed data, procedures, and triggers.