Entrada 7
Fecha: 23/03/2025
Inicio: [18:45] | Fin: [21:40] | Total: [3 horas]
Presentes: Matías Benavides Sandoval
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
¿QUÉ HICIMOS HOY?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Sesión enfocada en completar el backend y ordenar la estructura del proyecto.
1. Creamos src/controllers/empleadoController.ts con las dos funciones principales:
- getEmpleados: invoca sp_GetEmpleados y retorna el dataset al frontend como JSON
- insertEmpleado: invoca sp_InsertEmpleado y retorna éxito o error de duplicado según el código
2. Creamos src/routes/empleados.ts que conecta las rutas HTTP con las funciones del controller:
- GET /api/empleados → getEmpleados
- POST /api/empleados → insertEmpleado
3. Actualizamos src/index.ts para:
- Servir la carpeta public/ con express.static (esto hace que el browser pueda cargar el HTML, CSS y JS del frontend)
- Conectar el router de empleados en /api/empleados
4. Reorganizamos la estructura de archivos del proyecto para que sea más clara y ordenada:
- CSS movido a public/css/
- SPs renombrados con sus nombres correctos
- Eliminado el archivo tsconfig duplicado vacío
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PROBLEMAS ENCONTRADOS Y CÓMO SE RESOLVIERON
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Problema 1:
Descripción: El SP se llamaba de forma incorrecta desde index.ts.
Código incorrecto:
.execute('SPordenar')
Código correcto:
.execute('sp_GetEmpleados')
Causa: El nombre del SP en el código no coincidía
con el nombre real en la BD.
Problema 2:
Descripción: El connection.ts tenía la IP de
Hamachi en lugar de localhost.
Causa: Se quedó la IP del compañero de cuando él lo probó en su máquina.
Solución:
Cambiar server a 'localhost' en la máquina del servidor (Matias) y mantener '25.0.119.25' solo en la del compañero.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DUDAS Y DIVERGENCIAS DE CRITERIO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Discutimos si el controller debería validar los campos de entrada además del frontend. Decidimos
hacer una validación mínima en el controller (verificar que nombre y salario no sean undefined) y dejar la validación completa al frontend y al SP, que es donde el enunciado la pide explícitamente.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AVANCE DEL CÓDIGO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
--------------------------Empleados.ts (rutas) -----------------------------------
import { Router } from 'express';
import { getEmpleados, insertEmpleado } from '../controllers/empleadoController';
const router = Router();
// GET /api/empleados → llama a getEmpleados
router.get('/', getEmpleados);
// POST /api/empleados → llama a insertEmpleado
router.post('/', insertEmpleado);
export default router;
------------------------EmpleadosController.ts ----------------------------------
import { Request, Response } from 'express';
import { getPool, sql } from '../db/connection';
// ═══════════════════════════════════════════════
// GET /api/empleados
// Invoca sp_GetEmpleados y retorna el listado
// ═══════════════════════════════════════════════
export async function getEmpleados(
req: Request,
res: Response
): Promise<void> {
try {
const pool = await getPool();
const result = await pool
.request()
.execute('sp_GetEmpleados');
res.json({
success: true,
data: result.recordset
});
} catch (error) {
console.error('Error en getEmpleados:', error);
res.status(500).json({
success: false,
message: 'Error al obtener empleados'
});
}
}
// ═══════════════════════════════════════════════
// POST /api/empleados
// Invoca sp_InsertEmpleado con nombre y salario
// Retorna success o mensaje de duplicado
// ═══════════════════════════════════════════════
export async function insertEmpleado(
req: Request,
res: Response
): Promise<void> {
const { nombre, salario } = req.body;
// Validación mínima en capa lógica
if (!nombre || salario === undefined) {
res.status(400).json({
success: false,
message: 'Nombre y salario son requeridos'
});
return;
}
try {
const pool = await getPool();
const result = await pool
.request()
.input('Nombre', sql.VarChar(128), nombre)
.input('Salario', sql.Money, salario)
.output('Resultado', sql.Int)
.execute('sp_InsertEmpleado');
const codigo: number = result.output.Resultado;
if (codigo === 0) {
res.json({
success: true,
message: 'Inserción exitosa'
});
} else {
res.status(409).json({
success: false,
message: 'Nombre de Empleado ya existe.'
});
}
} catch (error) {
console.error('Error en insertEmpleado:', error);
res.status(500).json({
success: false,
message: 'Error interno del servidor'
});
}
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MORALEJAS / BUENAS PRÁCTICAS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- El nombre del SP en el código debe coincidir exactamente con el nombre en la BD, incluyendo mayúsculas y guiones bajos. Un error de tipeo aquí da un error de runtime difícil de detectar.
- Mantener el connection.ts con localhost en el servidor y la IP de Hamachi en el cliente evita confusiones al hacer commits.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRÓXIMA SESIÓN: ¿QUÉ SIGUE?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Sebastián corrige index.js para que el fetch
apunte a /api/empleados correctamente.
- Probar el flujo completo: lista → insertar →
regresar con tabla actualizada.
- Revisar la rúbrica para verificar que todos
los requisitos están cubiertos.
- Hacer commit final con todos los cambios.
Comentarios
Publicar un comentario