Marco de referencia
Metodología
Fundamentos teóricos y prácticas de trabajo comunes a los frentes de la pasantía. Las decisiones particulares de cada desarrollo —arquitectura, ramas, despliegue— se documentan en su ficha.
Ciclo de vida del software aplicado
El ciclo de vida del software describe las etapas por las que pasa un producto desde que surge una necesidad hasta que deja de operar. En el modelo en cascada esas etapas se recorren una sola vez y en orden estricto; cada una debe cerrarse antes de iniciar la siguiente. Ese esquema funciona cuando los requisitos son estables, pero en una dependencia que atiende solicitudes de muchas unidades académicas los requisitos cambian con frecuencia y la retroalimentación temprana vale más que un plan cerrado.
Por eso el trabajo se aproximó a un modelo iterativo e incremental: cada iteración atraviesa análisis, diseño, construcción, verificación y entrega sobre un conjunto acotado de funcionalidades, y el resultado se presenta a quien lo solicitó antes de continuar. Así se obtiene una versión utilizable pronto y los cambios se absorben sin rehacer lo construido.
- Levantamiento y análisis
- Identificar quién necesita el producto, qué problema resuelve y con qué restricciones: tiempos, infraestructura disponible y lineamientos de imagen institucional.
- Diseño
- Definir la arquitectura, el modelo de datos, los contratos de la API y las maquetas de interfaz antes de escribir código.
- Construcción
- Implementar por módulos, integrando con frecuencia en el repositorio y manteniendo un historial de cambios legible.
- Verificación
- Comprobar cada funcionalidad contra sus criterios de aceptación y revisar aspectos no funcionales como accesibilidad, rendimiento y seguridad.
- Despliegue
- Publicar en la infraestructura de destino, configurar variables de entorno y procesos, y dejar documentado cómo repetir el procedimiento.
- Mantenimiento
- Corregir incidencias y atender ajustes solicitados después de la puesta en producción.
No todos los frentes recorren el ciclo de la misma manera. Los micrositios institucionales se acercan a un mantenimiento evolutivo: los sitios ya existen y el trabajo consiste en actualizarlos, unificarlos y corregirlos. Los aplicativos nuevos, en cambio, recorren el ciclo completo desde el levantamiento de requerimientos hasta el despliegue.
Scrum como marco de trabajo
Scrum es un marco ágil para desarrollar productos complejos mediante iteraciones de duración fija llamadas sprints. Se apoya en tres pilares empíricos: transparencia (el trabajo y su estado son visibles para todos), inspección (el avance se revisa con frecuencia) y adaptación (el plan se ajusta con lo aprendido). Scrum no prescribe técnicas de programación; organiza cómo se decide qué construir, cómo se divide el trabajo y cómo se revisa el resultado.
Roles
- Product Owner
- Responsable de maximizar el valor del producto. Mantiene y ordena el backlog y decide qué se construye primero. En un proyecto institucional corresponde a la persona de la dependencia solicitante que conoce el proceso y puede tomar decisiones sobre el alcance.
- Scrum Master
- Facilita el proceso, ayuda a remover impedimentos y vela por que los eventos cumplan su propósito. En equipos pequeños este rol suele compartirse con el equipo o asumirlo quien coordina el trabajo.
- Equipo de desarrollo
- Quienes construyen el incremento en cada sprint. En esta pasantía, el equipo estuvo conformado por los dos pasantes.
Artefactos
- Product Backlog
- Lista ordenada de todo lo que el producto podría necesitar. Cada elemento se expresa, por lo general, como una historia de usuario.
- Sprint Backlog
- Subconjunto del backlog que el equipo se compromete a completar en el sprint, junto con el plan para lograrlo.
- Incremento
- Versión utilizable del producto que cumple la Definición de Terminado: el código está integrado en la rama principal, sus criterios de aceptación fueron verificados y puede desplegarse.
Sprints y eventos
Un sprint dura entre una y cuatro semanas y contiene cuatro eventos: la planeación, donde se elige qué historias entran y cómo se abordarán; la reunión diaria, breve, para sincronizar avances e impedimentos; la revisión, donde se muestra el incremento a los interesados; y la retrospectiva, donde el equipo evalúa su forma de trabajar y acuerda mejoras.
El caso más estructurado de la pasantía fue ReservaLab (antes SigueLab), cuyo alcance se descompuso en 31 historias de usuario distribuidas en 9 sprints.
Historias de usuario
Una historia de usuario describe una funcionalidad desde la perspectiva de quien la usa, con la estructura Como <rol>, quiero <acción>, para <beneficio>. Su valor está en mantener la conversación centrada en el problema del usuario y no en la solución técnica.
Una buena historia cumple el criterio INVEST: es independiente de otras, negociable en su detalle, valiosa para el usuario, estimable por el equipo, pequeña para caber en un sprint y verificable mediante criterios claros.
Ejemplo de formato. Como docente, quiero reservar un laboratorio en una franja horaria, para asegurar el espacio de mi práctica.
Criterios de aceptación
Los criterios de aceptación definen cuándo una historia está completa. Se redactan como escenarios verificables con la forma Dado / Cuando / Entonces, lo que permite convertirlos casi directamente en casos de prueba.
Dado que el laboratorio está libre de 8:00 a 10:00, cuando el docente envía la reserva para esa franja, entonces el sistema la registra y la franja deja de aparecer como disponible.
Dado que la franja ya está reservada, cuando otro usuario intenta reservarla, entonces el sistema rechaza la solicitud e informa el conflicto.
Priorización MoSCoW
Para ordenar el backlog se usa la técnica MoSCoW, que clasifica cada requisito según su importancia para la entrega:
| Categoría | Significado | Criterio práctico |
|---|---|---|
| Must have | Imprescindible | Sin esta funcionalidad el producto no cumple su propósito; la entrega no es viable. |
| Should have | Importante | Aporta mucho valor, pero existe una alternativa temporal si no alcanza a construirse. |
| Could have | Deseable | Mejora la experiencia; se incluye si el tiempo lo permite. |
| Won't have (esta vez) | Fuera de alcance | Se reconoce y se registra, pero se aplaza explícitamente a una versión futura. |
Hacer explícito lo que queda fuera es tan importante como lo que entra: evita que el alcance crezca sin control y deja un registro claro para quien continúe el desarrollo.
GitHub Issues y Milestones
El backlog se gestiona sobre el mismo lugar donde vive el código. Cada historia de usuario, tarea técnica o error se registra como un issue de GitHub, con una descripción, sus criterios de aceptación y etiquetas que indican el tipo de trabajo, la prioridad y el módulo afectado.
Issues como tablero kanban
Los issues se organizan en un tablero de GitHub Projects con columnas que representan el flujo de trabajo: Por hacer, En curso, En revisión y Terminado. Mover una tarjeta entre columnas hace visible el estado del sprint sin necesidad de reuniones adicionales y permite detectar cuellos de botella, como varias tareas detenidas en revisión.
Milestones como sprints
Cada sprint se modela como un milestone con fecha de cierre. Los issues comprometidos en el sprint se asignan a ese milestone y GitHub calcula el avance como la proporción de issues cerrados. Al terminar el sprint, lo no completado se traslada al siguiente milestone o vuelve al backlog.
Trazabilidad
Cuando un pull request incluye en su descripción una referencia como Closes #12, GitHub cierra el issue al integrarse el cambio. Así cada requisito queda vinculado con el código que lo implementa, la revisión que lo aprobó y el sprint en que se entregó.
Control de versiones con Git
Git es un sistema de control de versiones distribuido: cada copia del repositorio contiene el historial completo. Permite trabajar en paralelo sin pisar el trabajo ajeno, volver a cualquier estado anterior y saber quién cambió qué y por qué.
Flujo de ramas
El trabajo se organiza en ramas con propósitos distintos. Un esquema habitual, del que parten las estrategias de cada repositorio, es el siguiente:
| Rama | Propósito | Origen y destino |
|---|---|---|
main | Código estable, equivalente a lo que está en producción. | Recibe integraciones revisadas. |
develop | Integración de funcionalidades terminadas antes de liberar. | Sale de main; vuelve a main en cada entrega. |
feature/… | Una funcionalidad o historia de usuario. | Sale de develop; vuelve por pull request. |
fix/… | Corrección de un error detectado en desarrollo. | Sale de develop; vuelve por pull request. |
hotfix/… | Corrección urgente sobre producción. | Sale de main; vuelve a main y a develop. |
Cuando el despliegue se automatiza, es común añadir una rama de salida que contiene solo el resultado compilado, separada del código fuente. La estrategia concreta de cada repositorio se registra en su ficha de proyecto.
Convención de commits
Los mensajes de commit siguen la especificación Conventional Commits: tipo(ámbito): descripción, con la descripción en imperativo y en minúscula. Un historial con esta forma se lee como una bitácora del proyecto y permite generar notas de versión de manera automática.
| Tipo | Uso | Ejemplo |
|---|---|---|
feat | Nueva funcionalidad | feat(reservas): validar choque de franjas |
fix | Corrección de un error | fix(auth): renovar token expirado |
docs | Documentación | docs: describir variables de entorno |
style | Formato sin cambio de lógica | style: aplicar prettier |
refactor | Reestructuración sin cambio de comportamiento | refactor(usuarios): extraer servicio |
test | Pruebas | test(reservas): cubrir cancelación |
chore | Mantenimiento y dependencias | chore: actualizar dependencias |
ci | Integración y despliegue continuo | ci: compilar en cada push a main |
Arquitectura cliente-servidor y API REST
En la arquitectura cliente-servidor, la interfaz que usa la persona (el cliente, en este caso una aplicación web que corre en el navegador) está separada del componente que guarda los datos y aplica las reglas de negocio (el servidor). Ambos se comunican por la red mediante peticiones y respuestas. La separación permite evolucionar cada parte por su cuenta, desplegarlas en lugares distintos y atender con un mismo servidor a varios clientes.
El servidor se organiza en capas: los controladores reciben la petición HTTP y validan la entrada; los servicios contienen la lógica de negocio; la capa de acceso a datos traduce las operaciones a consultas sobre la base de datos. Cada capa conoce solo a la inmediatamente inferior, lo que facilita probar y modificar el código. Frameworks como NestJS, usado en varios de los desarrollos, imponen esta estructura mediante módulos, controladores, proveedores e inyección de dependencias.
Principios REST
REST es un estilo para diseñar APIs sobre HTTP. Los datos se exponen como recursos identificados por URL (/laboratorios, /laboratorios/7/reservas), las operaciones se expresan con los métodos HTTP y el resultado se comunica con códigos de estado. Cada petición es sin estado: lleva consigo toda la información necesaria, incluida la credencial, de modo que el servidor no depende de sesiones en memoria. Los datos viajan en formato JSON.
| Método | Operación | Respuesta habitual |
|---|---|---|
GET | Consultar un recurso o una colección | 200 OK |
POST | Crear un recurso | 201 Created |
PUT / PATCH | Reemplazar o modificar parcialmente | 200 OK |
DELETE | Eliminar un recurso | 204 No Content |
Los errores también son parte del contrato: 400 para datos inválidos, 401 cuando falta autenticación, 403 cuando el usuario no tiene permiso, 404 cuando el recurso no existe, 409 ante un conflicto —como una reserva duplicada— y 500 ante una falla inesperada del servidor.
Seguridad y documentación
Como el cliente y el servidor suelen estar en dominios distintos, el servidor declara mediante CORS qué orígenes pueden consumirlo. La autenticación sin estado se resuelve habitualmente con tokens firmados (JWT) enviados en cada petición. Para que la API pueda usarse sin leer el código, se documenta con la especificación OpenAPI, que herramientas como Swagger convierten en una página interactiva.
Levantamiento de requerimientos
El levantamiento de requerimientos busca entender qué necesita realmente quien solicita un desarrollo, que no siempre coincide con lo que pide en la primera conversación. Un requisito mal entendido es el error más costoso de corregir, porque se descubre tarde y arrastra decisiones de diseño.
Técnicas
- Entrevistas y reuniones con la dependencia solicitante para conocer el proceso actual, sus problemas y quiénes intervienen.
- Revisión de lo existente: sitios publicados, formatos, hojas de cálculo o procedimientos manuales que el sistema va a reemplazar.
- Prototipos y maquetas para validar flujos e interfaces antes de programarlos.
- Validación iterativa: cada entrega del sprint se convierte en una nueva oportunidad para confirmar o corregir lo entendido.
Funcionales y no funcionales
Los requerimientos funcionales describen lo que el sistema debe hacer: registrar una reserva, asignar un punto a un estudiante, publicar una noticia. Los no funcionales describen cómo debe hacerlo: tiempos de respuesta, compatibilidad con dispositivos móviles, accesibilidad, seguridad de los datos personales, alineación con la imagen institucional y restricciones de la infraestructura disponible para alojarlo.
Del requisito a la historia
Los requisitos levantados se traducen en historias de usuario con sus criterios de aceptación, se priorizan con MoSCoW y se registran como issues. De este modo, la conversación inicial con la dependencia queda conectada, sin pasos intermedios, con el backlog, el código y la entrega.