This commit is contained in:
2025-10-16 19:49:50 +00:00
parent ba6b4fef4f
commit c4097bc737
119 changed files with 3765 additions and 14390 deletions
View File
+36
View File
@@ -9,6 +9,9 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@suitecoffee/db": "file:../../packages/core/db",
"@suitecoffee/redis": "file:../../packages/core/redis",
"@suitecoffee/scripts": "file:../../packages/core/scripts",
"bcrypt": "^6.0.0",
"chalk": "^5.6.0",
"connect-redis": "^9.0.0",
@@ -36,6 +39,27 @@
"nodemon": "^3.1.10"
}
},
"../../packages/core/db": {
"name": "@suitecoffee/db",
"version": "1.0.0",
"peerDependencies": {
"pg": "^8.16.3"
}
},
"../../packages/core/redis": {
"name": "@suitecoffee/redis",
"version": "1.0.0",
"peerDependencies": {
"pg": "^8.16.3"
}
},
"../../packages/core/scripts": {
"name": "@suitecoffee/scripts",
"version": "1.0.0",
"peerDependencies": {
"pg": "^8.16.3"
}
},
"node_modules/@epic-web/invariant": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
@@ -109,6 +133,18 @@
"@redis/client": "^5.8.3"
}
},
"node_modules/@suitecoffee/db": {
"resolved": "../../packages/core/db",
"link": true
},
"node_modules/@suitecoffee/redis": {
"resolved": "../../packages/core/redis",
"link": true
},
"node_modules/@suitecoffee/scripts": {
"resolved": "../../packages/core/scripts",
"link": true
},
"node_modules/@types/body-parser": {
"version": "1.19.6",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
+8 -3
View File
@@ -15,6 +15,12 @@
"nodemon": "^3.1.10"
},
"dependencies": {
"@suitecoffee/db": "file:../../packages/core/db",
"@suitecoffee/redis": "file:../../packages/core/redis",
"@suitecoffee/scripts": "file:../../packages/core/scripts",
"@suitecoffee/middlewares": "file:../../packages/core/middlewares",
"bcrypt": "^6.0.0",
"chalk": "^5.6.0",
"connect-redis": "^9.0.0",
@@ -39,9 +45,8 @@
},
"imports": {
"#v1Router": "./src/api/v1/routes/routes.js",
"#pages": "./src/pages/pages.js",
"#db": "./src/db/poolSingleton.js"
"#pages": "./src/pages/pages.js"
},
"keywords": [],
"description": ""
}
}
-82
View File
@@ -1,82 +0,0 @@
// Coneción Singleton a base de datos.
import { Pool } from 'pg';
class DatabaseCore {
constructor() {
if (DatabaseCore.instance) {
return Database.instance;
}
const config = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
port: process.env.DB_LOCAL_PORT ? Number(process.env.DB_LOCAL_PORT) : undefined,
ssl: process.env.PGSSL === 'true' ? { rejectUnauthorized: false } : undefined,
};
this.connection = new Pool(config);
DatabaseCore.instance = this;
}
async query(sql, params) {
return this.connection.query(sql,params);
}
async connect() { /* Definida solo para evitar errores */
return this.connection.connect();
}
async getClient() {
return this.connection.connect();
}
async release() {
await this.connection.end();
}
}
class DatabaseTenants {
constructor() {
if (DatabaseTenants.instance) {
return Database.instance;
}
const config = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
port: process.env.DB_LOCAL_PORT ? Number(process.env.DB_LOCAL_PORT) : undefined,
ssl: process.env.PGSSL === 'true' ? { rejectUnauthorized: false } : undefined,
};
this.connection = new Pool(config);
DatabaseTenants.instance = this;
}
async query(sql, params) {
return this.connection.query(sql,params);
}
async connect() { /* Definida solo para evitar errores */
return this.connection.connect();
}
async getClient() {
return this.connection.connect();
}
async release() {
await this.connection.end();
}
}
// const db = new Database();
// db.query('SELECT * FROM users');
const poolCore = new DatabaseCore();
const poolTenants = new DatabaseTenants();
export default {poolCore, poolTenants};
export { poolCore, poolTenants };
+11 -58
View File
@@ -9,7 +9,9 @@ import 'dotenv/config'; // Variables de Entorno
import express from 'express';
import expressLayouts from 'express-ejs-layouts';
import { poolCore, poolTenants } from '#db'; // dbCore y dbTenants
import { poolCore, poolTenants, verificarConexionCore, verificarConexionTenants } from '@suitecoffee/db'; // dbCore y dbTenants desde paquete
import { redisAuthentik, verificarConexionRedisAuthentik} from '@suitecoffee/redis';
import { checkRequiredEnvVars } from '@suitecoffee/scripts';
import path from 'path';
import { fileURLToPath } from 'url';
@@ -23,35 +25,17 @@ const __dirname = path.dirname(__filename);
// Validación de entorno mínimo (ajusta nombres si difieren)
// -----------------------------------------------------------------------------
// Función para verificar que ciertas variables de entorno estén definida
function checkRequiredEnvVars(...requiredKeys) {
const missingKeys = requiredKeys.filter((key) => !process.env[key]); // Filtramos las que NO existen en process.env
if (missingKeys.length > 0) { // Si falta alguna, mostramos una advertencia
console.warn(
`[PLUGIN] No se encontraron las siguientes variables de entorno: \n\n-> ${missingKeys.join('\n-> ')}`+
`\n`
);
}
}
checkRequiredEnvVars(
'PORT',
'CORE_DB_HOST', 'CORE_DB_PORT', 'CORE_DB_NAME',
'TENANTS_DB_HOST', 'TENANTS_DB_PORT', 'TENANTS_DB_NAME'
'PORT'
);
// ----------------------------------------------------------
// Variables del sistema
// ----------------------------------------------------------
const PORT = process.env.PORT;
const CORE_DB_HOST = process.env.CORE_DB_HOST;
const CORE_DB_PORT = process.env.CORE_DB_PORT;
const CORE_DB_NAME = process.env.CORE_DB_NAME;
const TENANTS_DB_HOST = process.env.TENANTS_DB_HOST;
const TENANTS_DB_PORT = process.env.TENANTS_DB_PORT;
const TENANTS_DB_NAME = process.env.TENANTS_DB_NAME;
// ----------------------------------------------------------
// App + Motor de vistas EJS
@@ -72,38 +56,6 @@ app.use(expressLayouts); // Carga los layouts que usara el renderizado
app.use(cookieParser(process.env.SESSION_SECRET));
// ----------------------------------------------------------
// Verificación de conexión
// ----------------------------------------------------------
async function verificarConexionCore() {
try {
console.log(`[PLUGINS] Comprobando accesibilidad a la db ${CORE_DB_NAME} del host ${CORE_DB_HOST} ...`);
const client = await poolCore.connect();
const { rows } = await client.query('SELECT NOW() AS ahora');
console.log(`\n[PLUGINS] Conexión con ${CORE_DB_NAME} OK. Hora DB:`, rows[0].ahora);
client.release();
} catch (error) {
console.error('[PLUGINS] Error al conectar con la base de datos al iniciar:', error.message);
console.error('[PLUGINS] Revisar credenciales, accesos de red y firewall.');
}
}
async function verificarConexionTenants() {
try {
console.log(`[PLUGINS] Comprobando accesibilidad a la db ${TENANTS_DB_NAME} del host ${TENANTS_DB_HOST} ...`);
const client = await poolTenants.connect();
const { rows } = await client.query('SELECT NOW() AS ahora');
console.log(`\n[PLUGINS] Conexión con ${TENANTS_DB_NAME} OK. Hora DB:`, rows[0].ahora);
client.release();
} catch (error) {
console.error('[PLUGINS] Error al conectar con la base de datos al iniciar:', error.message);
console.error('[PLUGINS] Revisar credenciales, accesos de red y firewall.');
}
}
// ----------------------------------------------------------
@@ -123,10 +75,11 @@ app.use((req, res, next) => {
// Inicio del servidor
// ----------------------------------------------------------
app.listen(PORT, () => {
app.listen(PORT, async () => {
console.log(`[PLUGINS] http://localhost:${PORT}`);
verificarConexionCore();
verificarConexionTenants();
await verificarConexionCore();
await verificarConexionTenants();
await verificarConexionRedisAuthentik();
});
@@ -135,6 +88,6 @@ app.listen(PORT, () => {
// Healthcheck
// -----------------------------------------------------------------------------
app.get('/health', (_req, res) => {
res.status(200).json({ status: 'ok'}),
console.log(`[PLUGINS] Saludable`)
res.status(200).json({ status: 'ok'})
// console.log(`[PLUGINS] Saludable`)
});