Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#!/bin/sh
echo "🔍 Validando mensaje de commit..."

# Expresión regular del formato: tipo: descripción mínima de 10 caracteres
commit_regex="^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert): .{10,}$"
# Expresión regular mejorada:
# tipo(scope opcional): descripción mínima de 10 caracteres
commit_regex="^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\([a-zA-Z0-9_-]+\))?: ?.{10,}$"
commit_msg=$(cat "$1")

if ! echo "$commit_msg" | grep -Eq "$commit_regex"; then
echo ""
echo "❌ Mensaje de commit inválido."
echo "--------------------------------------------------"
echo "📌 Formato esperado: 'tipo: descripción de al menos 10 caracteres'"
echo "📌 Formato esperado: 'tipo(scope opcional): descripción de al menos 10 caracteres'"
echo "🔧 Tipos válidos:"
echo " feat → Nueva funcionalidad"
echo " fix → Corrección de errores"
Expand All @@ -23,8 +24,9 @@ if ! echo "$commit_msg" | grep -Eq "$commit_regex"; then
echo " build → Cambios que afectan el build"
echo " revert → Revertir un commit"
echo ""
echo "📝 Ejemplo válido:"
echo "📝 Ejemplos válidos:"
echo " feat: Agregar login con Google"
echo " fix(auth): Corregir error al refrescar token"
echo "--------------------------------------------------"
exit 1
fi
Expand Down
12 changes: 6 additions & 6 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
echo "🔍 Verificando archivos antes del commit..."

# Ejecutar pruebas con yarn
echo "🧪 Ejecutando tests..."
if ! yarn test; then
echo "❌ Tests fallaron. Corrige los errores antes de hacer commit."
exit 1
fi
# echo "🧪 Ejecutando tests..."
# if ! yarn test; then
# echo "❌ Tests fallaron. Corrige los errores antes de hacer commit."
# exit 1
# fi

# Formatear código con Prettier
echo "🚀 Ejecutando Prettier..."
if ! yarn run prettier --write .; then
if ! yarn prettier . --write; then
echo "❌ Error al ejecutar Prettier."
exit 1
fi
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
"@formkit/tempo": "^0.1.2",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"argon2": "^0.41.1",
"chalk": "^5.4.1",
"commander": "^13.1.0",
"cors": "^2.8.5",
"express": "^4.21.0",
"express-rate-limit": "^7.5.0",
Expand All @@ -45,6 +43,7 @@
"jsonwebtoken": "^9.0.2",
"morgan": "^1.10.0",
"mysql2": "^3.11.3",
"standard": "^17.1.2",
"swagger-jsdoc": "^6.2.8",
"swagger-themes": "^1.4.3",
"swagger-ui-express": "^5.0.1"
Expand Down
44 changes: 28 additions & 16 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Command } from "commander";
import cors from "cors";
import express from "express";
import helmet from "helmet";
Expand All @@ -7,17 +6,17 @@ import { createServer } from "node:http";

import { setupSwagger } from "./src/config/swaggerConfig.js";
import { corsOptions } from "./src/middleware/cors.js";
import { errorHandler } from "./src/middleware/errorHandler.js";
import { router } from "./src/router/index.js";

const program = new Command();
// Configuración básica del programa
program
.name("backend-kinder-garden")
.description("CRM para el control escolar")
.version("1.0.0");

// Parsear los argumentos de la línea de comandos
program.parse(process.argv);
// Datos del proyecto
const projectInfo = {
name: "CRM Kinder Garden",
description: "CRM para Gestión y Administración de una escuela",
version: "1.0.0",
authorName: "Erick Gonzalez",
githubName: "https://github.com/muke78",
};

const app = express();

Expand All @@ -30,14 +29,27 @@ app.use(express.json({ limit: "10mb" }));
app.use(express.urlencoded({ extended: true, limit: "10mb" }));
app.use(morgan("dev"));
app.use(helmet());
app.use(router);

// Middleware de manejo de errores
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json("🔴 Error interno del servidor");
// ✅ Ruta raíz: información del proyecto
app.get("/", (request, response) => {
response.status(200).json({
description: projectInfo.description,
name: projectInfo.name,
version: projectInfo.version,
author: {
name: projectInfo.authorName,
github: projectInfo.githubName,
},
api: "/api/v1",
status: "🟢 API funcionando correctamente",
});
});

app.use(router);

// ✅ Middleware global de errores profesional
app.use(errorHandler);

// Crear y arrancar el servidor
let currentPort = 3000;
const server = createServer(app);
Expand All @@ -49,7 +61,7 @@ const tryListen = (port) => {
server.on("error", (error) => {
if (error.code === "EADDRINUSE") {
console.log(
`El puerto ${currentPort} está en uso. Intentando con el puerto ${currentPort + 1}...`,
`⚠️ El puerto ${currentPort} está en uso. Intentando con el puerto ${currentPort + 1}...`,
);
currentPort++;
tryListen(currentPort);
Expand Down
78 changes: 21 additions & 57 deletions src/config/config.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,31 @@
import dotenv from "dotenv";
import inquirer from "inquirer";
import mysql from "mysql2";

import { loadChalk } from "../middleware/loadChalk.js";

dotenv.config();

export async function selectDatabaseConnection() {
const chalk = await loadChalk();
const { envChoice } = await inquirer.prompt([
{
type: "list",
name: "envChoice",
message: "¿Qué base de datos deseas usar?",
choices: [
{ name: "🔧 Local", value: "local" },
{ name: "🚀 Producción", value: "prod" },
],
},
]);

console.log(
chalk.green(
`✔ Conectando a la base de datos ${envChoice === "prod" ? "de Producción" : "Local"}...\n`,
),
);

const dbConfig = {
local: {
host: process.env.DB_HOST_LOCAL,
user: process.env.DB_USER_LOCAL,
password: process.env.DB_PASS_LOCAL,
database: process.env.DB_NAME_LOCAL,
},
prod: {
host: process.env.DB_HOST_PROD,
user: process.env.DB_USER_PROD,
password: process.env.DB_PASS_PROD,
database: process.env.DB_NAME_PROD,
},
};
// process.loadEnvFile();

const selectedConfig = {
...dbConfig[envChoice],
connectTimeout: 30000,
waitForConnections: true,
connectionLimit: 100,
queueLimit: 0,
};
// Configuracion de la conexion a la base de datos
const dbConnection = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
connectTimeout: 30000,
waitForConnections: true,
connectionLimit: 100,
queueLimit: 0,
};

const pool = mysql.createPool(selectedConfig);
const pool = mysql.createPool(dbConnection);

pool.on("connection", (connection) => {
console.log(chalk.cyan("✅ Conexión establecida con la base de datos"));
connection.query("SET SESSION wait_timeout = 28800");
});
pool.on("connection", (connection) => {
console.log("Conexion exitosa a la basde de datos");
connection.query("SET SESSION wait_timeout = 28800");
});

pool.on("error", (err) => {
console.error(
chalk.red("❌ Error en la conexión a la base de datos:"),
err,
);
});
pool.on("error", (err) => {
console.error("Error a la conexion de la base de datos", err);
});

return pool;
}
export { pool };
2 changes: 1 addition & 1 deletion src/config/swaggerConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const swaggerDefinition = {
openapi: "3.1.0",
openapi: "3.0.0",
info: {
title: "API Gestion y Administracion de una escuela",
version: "1.0.0",
Expand Down
34 changes: 6 additions & 28 deletions src/controllers/users/functions/deleteUser.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
import {
methodError,
methodIncorrect,
methodNotFound,
methodOK,
} from "../../../server/serverMethods.js";
import {
deleteUserBulkService,
deleteUserService,
} from "../../../services/users/index.js";

export const EliminarUsuario = async (req, res) => {
try {
const deletedUser = await deleteUserService(req.params);
methodOK(req, res, {
message: `El usuario ${deletedUser.NameUser} fue eliminado correctamente`,
});
} catch (error) {
if (error.status === 400) return methodIncorrect(req, res, error.message);
if (error.status === 404) return methodNotFound(req, res, error.message);
return methodError(req, res, { message: error });
}
export const EliminarUsuario = async (userId) => {
const deletedUser = await deleteUserService(userId);
return deletedUser;
};

export const DeleteUserBulk = async (req, res) => {
try {
await deleteUserBulkService(req.body);

methodOK(req, res, {
message: `Se eliminaron ${req.body.ids.length} usuarios correctamente`,
});
} catch (error) {
if (error.status === 400) return methodIncorrect(req, res, error.message);
return methodError(req, res, { message: error });
}
export const DeleteUserBulk = async (ids) => {
const deleteUserBulk = await deleteUserBulkService(ids);
return deleteUserBulk;
};
28 changes: 3 additions & 25 deletions src/controllers/users/functions/editUser.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,6 @@
import {
methodConflicts,
methodError,
methodNotFound,
methodOK,
} from "../../../server/serverMethods.js";
import { updateUserService } from "../../../services/users/index.js";

export const EditarUsuario = async (req, res) => {
try {
const actualizado = await updateUserService(req.body);

if (actualizado) {
return methodOK(req, res, {
message: "El recurso fue actualizado correctamente.",
});
} else {
return methodNotFound(req, res, {
message: "No se encontró el recurso para actualizar.",
});
}
} catch (error) {
if (error.status === 409)
return methodConflicts(req, res, { message: error.message });
if (error.status === 404) return methodNotFound(req, res, error.message);
return methodError(req, res, { message: error });
}
export const EditarUsuario = async (userId, userData) => {
const actualizado = await updateUserService(userId, userData);
return actualizado;
};
37 changes: 6 additions & 31 deletions src/controllers/users/functions/insertUsers.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,14 @@
import {
methodConflicts,
methodCreated,
methodError,
methodIncorrect,
} from "../../../server/serverMethods.js";
import {
insertUserMasiveService,
insertUserService,
} from "../../../services/users/index.js";

export const InsertarUsario = async (req, res) => {
try {
const newuser = await insertUserService(req.body);
return methodCreated(req, res, newuser);
} catch (error) {
if (error.status === 400) return methodIncorrect(req, res, error.message);
if (error.status === 409)
return methodConflicts(req, res, { message: error.message });
return methodError(req, res, { message: error });
}
export const InsertarUsario = async (user) => {
const newuser = await insertUserService(user);
return newuser;
};

export const InsertarUsuariosRunnerMasive = async (req, res) => {
try {
const newUserMasive = await insertUserMasiveService(req.body);

return methodCreated(
req,
res,
`Se insertaron correctamente ${newUserMasive.length} usuarios como prueba`,
);
} catch (error) {
if (error.status === 400) return methodIncorrect(req, res, error.message);
if (error.status === 409)
return methodConflicts(req, res, { message: error.message });
return methodError(req, res, { message: error });
}
export const InsertarUsuariosRunnerMasive = async (countInsert) => {
const newUserMasive = await insertUserMasiveService(countInsert);
return newUserMasive;
};
17 changes: 3 additions & 14 deletions src/controllers/users/functions/listUsers.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
import {
methodError,
methodNotFound,
methodOK,
} from "../../../server/serverMethods.js";
import { listUsersService } from "../../../services/users/index.js";

export const ObtenerTodosLosUsuarios = async (req, res) => {
try {
const result = await listUsersService(req.params, req.query);

methodOK(req, res, result);
} catch (error) {
if (error.status === 400) return methodNotFound(req, res);
return methodError(req, res, { message: error });
}
export const ObtenerTodosLosUsuarios = async (listUsers) => {
const result = await listUsersService(listUsers);
return result;
};
Loading
Loading