Skip to main content

Database Configuration

The application uses MySQL for data persistence. Database configuration is managed through two main files:

Connection Settings

File: src/keys.js
src/keys.js
module.exports = {
  host: 'localhost',
  database: 'asuntos_publicos',
  user: 'adminurbaneja',
  password: 'Admin*app*2021',
  multipleStatements: true
};
host
string
default:"localhost"
MySQL server hostname
database
string
default:"asuntos_publicos"
Database name (must match the created database)
user
string
MySQL username with access to the database
password
string
MySQL user password
multipleStatements
boolean
default:true
Allows executing multiple SQL statements in a single query

Database Pool

File: src/database.js The application uses connection pooling for efficient database access:
src/database.js
const mysql = require('mysql');
const { promisify } = require('util');

const pool = mysql.createPool(require('./keys.js'));

pool.getConnection((err, connection) => {
  if (err) {
    if (err.code == 'PROTOCOL_CONNECTION_LOST') {
      console.log('¡La conexión con la Base de Datos ha sido cerrada!');
    } else if (err.code == 'ER_CON_COUNT_ERROR') {
      console.log('¡La Base de Datos tiene muchas conexiones!');
    } else if (err.code == 'ECONNREFUSED') {
      console.log('¡La conexión con la Base de Datos ha sido rechazada!');
    }
  } else {
    connection.release();
    console.log('¡Base de Datos Conectada!');
  }
});

pool.query = promisify(pool.query);

module.exports = pool;
The pool automatically manages connections and supports promisified queries for async/await syntax.

Server Configuration

File: src/index.js

Basic Settings

src/index.js
const app = express();

// Port Configuration
app.set('port', 4000);

// View Engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
port
number
default:4000
Server port number. The application listens on this port for HTTP requests.
view engine
string
default:"ejs"
Template engine for rendering views. The application uses EJS (Embedded JavaScript).

Session Configuration

src/index.js
app.use(session({
  key: 'permisos_municipales_pass',
  secret: 'permisos_municipales',
  resave: false,
  saveUninitialized: false
}));
key
string
default:"permisos_municipales_pass"
Session cookie name
secret
string
default:"permisos_municipales"
Secret used to sign the session ID cookie
resave
boolean
default:false
Forces session to be saved back to the session store
saveUninitialized
boolean
default:false
Forces uninitialized session to be saved to the store
Change the session secret to a strong, random value in production. Never commit secrets to version control.

Static Files

src/index.js
app.use(express.static(path.join(__dirname, 'public')));
Static files are served from src/public/ directory, including:
  • CSS stylesheets
  • JavaScript files
  • Images
  • Uploaded documents

File Upload Configuration

The application uses Multer for handling file uploads. Files are stored in specific directories based on permit type.

Upload Paths

// Path: src/public/server-files/temps/
// Used for: Initial file upload before processing

const storage = multer.diskStorage({
  destination: path.join(__dirname, '../public/server-files/temps/'),
  filename: (req, file, cb) => {
    cb(null, file.fieldname + '_de_pago_' + Date.now() + 
       file.originalname.substr(file.originalname.lastIndexOf('.')));
  }
});

File Naming Convention

Uploaded files are automatically renamed with timestamps:
  • Payment receipts: comprobante_de_pago_[timestamp].[ext]
  • Authorized permits: permiso_autorizado[timestamp].[ext]
This prevents filename collisions and maintains file organization.

Environment Variables

For production deployments, use environment variables instead of hardcoded values:
DB_HOST=localhost
DB_NAME=asuntos_publicos
DB_USER=adminurbaneja
DB_PASSWORD=Admin*app*2021
PORT=4000
SESSION_SECRET=your_strong_random_secret
NODE_ENV=development

Using Environment Variables

Update src/keys.js to use environment variables:
src/keys.js
module.exports = {
  host: process.env.DB_HOST || 'localhost',
  database: process.env.DB_NAME || 'asuntos_publicos',
  user: process.env.DB_USER || 'root',
  password: process.env.DB_PASSWORD || '',
  multipleStatements: true
};
Create a .env file in the project root and add it to .gitignore to prevent committing sensitive data.

Socket.IO Configuration

The application uses Socket.IO for real-time updates:
src/index.js
const server = app.listen(app.get('port'), () => {
  console.log('¡Servidor Iniciado Correctamente!');
});

const SocketIO = require('socket.io');
const io = SocketIO(server);

io.on('connection', (socket) => {
  console.log('¡Se ha detectado una conexión!', socket.id);
  // Socket event handlers...
});
Socket events are used for:
  • Real-time permit updates
  • New permit notifications
  • Permit approval/cancellation notifications

Routes Configuration

The application defines the following route modules:
src/index.js
app.use(require('./routes/authentications.js'));
app.use('/venta_de_bebidas', require('./routes/bebidas.js'));
app.use('/eventos_especiales', require('./routes/eventos.js'));
app.use('/publicidad_y_propaganda', require('./routes/publicidad.js'));
app.use('/usuarios', require('./routes/usuarios.js'));

/

Authentication routes (login, logout)

/venta_de_bebidas

Alcoholic beverage permits

/eventos_especiales

Special event permits

/publicidad_y_propaganda

Advertising and propaganda permits

/usuarios

User management (admin only)

Production Recommendations

1

Use Process Manager

Use PM2 or similar to manage the Node.js process:
npm install -g pm2
pm2 start src/index.js --name "municipal-permits"
pm2 save
pm2 startup
2

Configure Reverse Proxy

Use Nginx or Apache as a reverse proxy:
server {
  listen 80;
  server_name your-domain.com;
  
  location / {
    proxy_pass http://localhost:4000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}
3

Enable HTTPS

Use Let’s Encrypt for free SSL certificates:
certbot --nginx -d your-domain.com
4

Configure Firewall

Only expose necessary ports:
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Next Steps

Security

Configure security settings and best practices

API Reference

Explore the API endpoints

Build docs developers (and LLMs) love