Biblioteca Virtual Trabajo final / Taller de Programación I
Universidad del Caribe / Mayo 2026

Biblioteca
Virtual.

Una plataforma web completa para gestionar el catálogo, los préstamos y las reservas de una biblioteca universitaria. Desarrollada como trabajo final del Taller de Programación I.

.NET 10 React PostgreSQL Cloudflare Tunnel
Universidad del Caribe
Maestro / Victorino Ramírez Reyes 01 / 34
Biblioteca Virtual Sección 01 / Introducción
01 El equipo

Cinco estudiantes, un solo proyecto.

Cada integrante asumió responsabilidad sobre un área del sistema. La presentación está organizada por temas: cuando aparece tu nombre en la barra inferior, te toca exponer.

AA
Alvaro Acevedo Mariano Arquitectura / Despliegue
DA
Dauri Abad Sepúlveda Frontend / UX·UI
DS
Daniel Asencio Backend / API
JB
Johancer Basiel Bonet Base de datos / Modelado
JN
Jason Núñez De Los Santos Administración / Testing
VR
Victorino Ramírez Reyes Maestro / Taller Programación I
Todos / Presenta Alvaro02 / 34
Biblioteca VirtualHoja de ruta
02 Contenido

Lo que vamos a recorrer.

  • Visión general — qué resuelve y para quién
  • Stack tecnológico — las herramientas que elegimos
  • Arquitectura — capas y separación de responsabilidades
  • Base de datos — modelo relacional con once tablas
  • Backend — .NET 10, Entity Framework, JWT
  • Frontend — React, Vite, Tailwind, diseño pastel
  • Funcionalidades — recorrido visual de cada pantalla
  • Despliegue — Docker en servidor casero + Cloudflare Tunnel
  • Dificultades — los problemas reales y cómo los resolvimos
  • Aprendizajes — lo que nos llevamos del proyecto
Alvaro03 / 34
Biblioteca VirtualSección 02 / El proyecto
03 El problema

Una biblioteca con
libreta y lápiz no escala.

En muchas bibliotecas universitarias todavía se controlan los préstamos en cuadernos, las multas se calculan a mano y los catálogos viven en hojas de cálculo dispersas. El resultado: libros perdidos, multas mal cobradas, lectores frustrados.

Quisimos resolver un problema concreto: que cualquier estudiante pueda buscar, reservar y prestar libros desde su celular, mientras el bibliotecario tiene control total y trazabilidad de cada movimiento.

Lo que falla hoy
  • Catálogo desactualizado o inconsistente
  • Reservas que se pierden o se duplican
  • Cálculo manual de multas por retraso
  • Sin trazabilidad de quién hizo qué
Lo que entregamos
  • Plataforma web accesible desde cualquier dispositivo
  • Préstamos, reservas y multas automatizadas
  • Panel administrativo con auditoría completa
Alvaro04 / 34
Biblioteca VirtualVisión general
04 La solución

Una plataforma web con
dos caras y un solo cerebro.

Para el lector

Catálogo en línea

Buscar libros por título, autor, categoría o ISBN. Reservar lo no disponible. Solicitar préstamos en un clic. Recibir notificaciones automáticas.

Para el bibliotecario

Panel de control

Aprobar préstamos, asignar ejemplares físicos, procesar devoluciones y consultar inventario en tiempo real desde un dashboard único.

Para la institución

Auditoría completa

Cada acción queda registrada. El histórico es append-only: nadie puede «borrar» su rastro. Total transparencia operativa.

11
Tablas en la BD
36
Endpoints REST
22
Pantallas en la app
17/17
Tests automatizados
Alvaro05 / 34
Biblioteca VirtualCómo funciona
05 Flujo del sistema

Del catálogo a la devolución.

Cada préstamo recorre un camino claro. El lector busca un libro y lo solicita; el bibliotecario aprueba y asigna un ejemplar físico; el lector lo usa por catorce días y lo devuelve. Si se atrasa, el sistema genera la multa de manera automática. Cada paso queda registrado en la auditoría.

  • Lector — busca, solicita, retira, devuelve y, si aplica, paga la multa.
  • Sistema — valida disponibilidad, calcula vencimientos y genera multas.
  • Bibliotecario — aprueba solicitudes, asigna ejemplares y procesa devoluciones.
Cada decisión queda registrada para que nada se pierda.
LECTOR Busca un libro ¿Disponible? stock > 0 LECTOR Solicita no LECTOR Reserva SISTEMA Cola FIFO su turno BIBLIOTECARIO Aprueba y asigna LECTOR Retira ejemplar 14 días de uso LECTOR Devuelve ¿A tiempo? ≤ vencimiento SISTEMA Cierra no SISTEMA Genera multa LECTOR Paga multa
Johancer Basiel06 / 34
Biblioteca VirtualSección 03 / Arquitectura
06 Stack tecnológico

Las herramientas que elegimos.

Cada elección se justifica por una razón concreta. Nada está acá por moda.

Backend

.NET 10

ASP.NET Core Web API. Compilado, fuertemente tipado, rendimiento de primer nivel y soporte oficial de Microsoft a largo plazo.

Frontend

React 18 + Vite

Componentes reutilizables, hot reload instantáneo y build de producción optimizado por defecto. JSX para mantener la lógica cerca del marcado.

Estilos

Tailwind CSS v4

Sistema de diseño basado en utilidades. Paleta pastel personalizada en tailwind.config.js.

Base de datos

PostgreSQL 16

Robusta, gratuita, y la mejor opción open-source. Migraciones gestionadas por Entity Framework Core sobre Npgsql.

Auth

JWT + BCrypt

Tokens firmados con HMAC-SHA256 para sesiones sin estado. Contraseñas con BCrypt — nunca en texto plano.

Testing

Vitest + xUnit

Vitest para el frontend (jsdom + Testing Library). xUnit para los servicios .NET. Playwright para tests E2E.

Contenedores

Docker + Compose

Cada servicio en su contenedor. Una sola red interna. Reproducible en cualquier máquina que tenga Docker.

Despliegue

Cloudflare Tunnel

Servidor casero expuesto sin abrir puertos del router, sin IP pública, con HTTPS automático.

Alvaro07 / 34
Biblioteca VirtualArquitectura
07 Diseño de arquitectura

Tres capas, una responsabilidad cada una.

Separamos la aplicación en tres capas independientes que se comunican por contratos bien definidos. Cada capa puede evolucionar sin romper a las otras.

  • Presentación — React. Lo único que sabe es cómo mostrar datos y cómo enviar peticiones HTTP. Ignora todo lo demás.
  • Aplicación — Controllers + Services en .NET. Recibe peticiones, valida, orquesta lógica de negocio y devuelve respuestas.
  • Datos — Entity Framework Core + PostgreSQL. Persistencia, consultas y migraciones. El esquema vive acá.
Cada capa habla solo con la inmediatamente debajo. Sin atajos.
PRESENTACION / REACT SPA Frontend Vite / React Router / Axios / Tailwind HTTPS / JSON APLICACION / ASP.NET CORE Backend API Controllers / Services / DTOs / Middleware JWT / CORS / Serilog / BCrypt SQL / Npgsql DATOS / POSTGRESQL 16 Base de datos 11 tablas / EF Core / Migraciones versionadas
Johancer Basiel08 / 34
Biblioteca VirtualBase de datos
08 Diseño relacional

Once tablas, relaciones explícitas.

El modelo nació de las entidades del dominio real: libros, autores, categorías, ejemplares físicos, usuarios, préstamos, reservas, multas. Cada relación tiene sentido en el negocio.

  • Libro → tiene muchos Ejemplares
  • Préstamo conecta Usuario + Ejemplar
  • Reserva tiene cola con posicionCola
  • Multa deriva de un Préstamo vencido
  • AuditLog registra TODO (append-only)
PostgreSQL 16
Npgsql provider
EF Core migrations
LIBRO PK id titulo / isbn / anio editorial / sinopsis FK autorId / categoriaId stock / disponibles AUTOR PK id nombre / nacionalidad CATEGORIA PK id nombre / descripcion EJEMPLAR PK id / FK libroId codigo / estado tipo / ubicacion USUARIO PK id nombre / email rol / passwordHash PRESTAMO PK id FK usuarioId / ejemplarId estado / fechas RESERVA PK id posicionCola estado / expira MULTA PK id / FK prestamoId monto / diasRetraso estado INTENTO_PAGO PK id / FK multaId referencia / estado AUDIT + NOTIF accion / entidad resultado / fecha tipo / mensaje
Johancer Basiel09 / 34
Biblioteca VirtualSección 04 / Backend
09 .NET 10 + ASP.NET Core

El motor está escrito en C#.

El backend es una API REST construida con ASP.NET Core sobre .NET 10, la versión más reciente y soportada a largo plazo. Está organizado en cuatro capas internas, todas dentro del mismo proyecto.

  • Controllers — exponen los endpoints HTTP. Validan input y delegan al service correspondiente.
  • Services — la lógica de negocio. Calculan multas, gestionan colas de reserva, orquestan préstamos.
  • DbContext — el puente con PostgreSQL. Las migraciones se ejecutan automáticamente al arrancar.
  • DTOs — modelos de transporte. Nunca exponemos entidades directas al cliente.
// Controllers/PrestamosController.cs
[ApiController]
[Route("api/prestamos")]
[Authorize]
public class PrestamosController : ControllerBase
{
    private readonly ICirculacionService _service;

    [HttpPost]
    public async Task<IActionResult> Solicitar(
        SolicitarPrestamoDto dto)
    {
        var prestamo = await
            _service.SolicitarAsync(User, dto);
        return CreatedAtAction(
            nameof(Get),
            new { id = prestamo.Id },
            prestamo);
    }
}
Logging

Serilog

Validación

DataAnnotations

Daniel Asencio10 / 34
Biblioteca VirtualBackend / Seguridad
10 Autenticación

Tokens JWT y contraseñas con BCrypt.

El backend no guarda sesiones. Cada petición protegida lleva un JSON Web Token firmado por el servidor en su header. El token contiene el ID y el rol del usuario, y expira a las 8 horas.

  • Login — el usuario envía email + password. El servidor compara con BCrypt y, si coincide, emite un JWT firmado con HMAC-SHA256.
  • Storage — el frontend guarda el token en localStorage.
  • Cada petición — Axios agrega Authorization: Bearer <token>.
  • Validación — un middleware verifica firma + expiración antes de llegar al controller.
  • Roles — atributos [Authorize(Roles)] protegen los endpoints sensibles.
Las contraseñas nunca salen del backend, ni siquiera para los administradores.
// Login flow
POST /api/auth/login
{
  "email": "lector@test.com",
  "password": "Lector123!"
}

// 200 OK
{
  "token": "eyJhbGciOiJIUzI1...",
  "user": {
    "id": 7,
    "nombre": "Maria Garcia",
    "rol": "Lector"
  }
}

// Peticiones siguientes
GET /api/prestamos
Authorization: Bearer eyJhbGciOiJIUzI1...
Daniel Asencio11 / 34
Biblioteca VirtualBackend / API
11 Endpoints principales

Treinta y seis rutas, todas REST.

Auth & Usuarios
POST   /api/auth/login
POST   /api/auth/registro
GET    /api/usuarios/yo
GET    /api/admin/usuarios
PUT    /api/admin/usuarios/{id}
Catálogo
GET    /api/libros?search=...
GET    /api/libros/{id}
POST   /api/admin/libros
PUT    /api/admin/libros/{id}
DELETE /api/admin/libros/{id}
Circulación
GET    /api/prestamos
POST   /api/prestamos
POST   /api/prestamos/{id}/aprobar
POST   /api/prestamos/{id}/devolver
POST   /api/prestamos/{id}/renovar
Multas & Reservas
GET    /api/reservas
POST   /api/reservas
POST   /api/reservas/{id}/cancelar
GET    /api/multas
POST   /api/multas/{id}/pago

Todos los endpoints siguen las convenciones REST: GET para leer, POST para crear, PUT para actualizar y DELETE para borrar. Los códigos de estado son consistentes (200, 201, 400, 401, 403, 404, 500).

Daniel Asencio12 / 34
Biblioteca VirtualSección 05 / Frontend
12 React + Vite

Una SPA reactiva, sin servidor de render.

El frontend es una Single Page Application escrita en React 18 con Vite como bundler. Todo el routing es en cliente con React Router. La comunicación con el backend pasa por Axios.

  • Componentes — pequeños, reutilizables, con props tipadas. Cada pantalla es una page; cada bloque visual es un componente.
  • Estado global — Context API para autenticación. useAuth() expone el usuario actual, el token y la función de logout.
  • Estado local — useState / useEffect en cada page.
  • Servicios — capa services/ que envuelve Axios. Centraliza interceptores y manejo de errores.
  • Routing — rutas públicas, privadas y de admin con componente ProtectedRoute.
// src/pages/CatalogPage.jsx
import { useState, useEffect } from 'react';
import { fetchBooks } from
  '../services/catalogService';

export default function CatalogPage() {
  const [books, setBooks] = useState([]);
  const [filters, setFilters] = useState({
    search: '',
    categoriaId: ''
  });

  useEffect(() => {
    fetchBooks(filters).then(setBooks);
  }, [filters]);

  return (
    <Layout>
      <Filters value={filters} onChange={setFilters} />
      <BookGrid books={books} />
    </Layout>
  );
}
Dauri Abad13 / 34
Biblioteca VirtualFrontend / Diseño
13 Diseño UX/UI

Una paleta pastel pensada para leer.

La interfaz usa una paleta cálida con tonos pastel: lavanda como primario, durazno y menta como acentos, sobre un fondo crema. La tipografía es Plus Jakarta Sans para que se sienta moderna pero seria.

  • Componentes reutilizables — BookCard, PageHeader, DataCard, StatusMessage.
  • Portadas reales de libros — pedimos las tapas a la API pública de Open Library por ISBN; si no encuentra, caemos a Unsplash por categoría; si todo falla, mostramos un gradiente pastel con iniciales.
  • Responsive — diseño mobile-first. Funciona en celular, tablet y escritorio sin recargar layout.
LAVANDA
DURAZNO
MENTA
CIELO
SOL
CREMA
Plus Jakarta Sans
Tailwind v4
Mobile-first
Pastel / cálido
Dauri Abad14 / 34
Biblioteca VirtualSección 06 / Funcionalidades
14 Catálogo público

Explorar libros sin necesidad de cuenta.

Cualquier visitante puede buscar libros, ver detalles y revisar disponibilidad. La búsqueda es por texto libre (título, autor, ISBN), con filtros por categoría y disponibilidad.

  • Búsqueda en tiempo real
  • Filtros por autor, categoría, formato
  • Ordenamiento (A-Z, por año, por disponibilidad)
  • Paginación cliente-servidor
  • Tapas reales desde Open Library
Catálogo público
/catalogo — GET /api/libros
Dauri Abad15 / 34
Biblioteca VirtualFuncionalidades / Detalle
15 Detalle de libro

Toda la ficha del libro, con acciones contextuales.

Detalle de libro
/catalogo/{id}

La página de detalle muestra la sinopsis, autor, categoría, año, ISBN, editorial, formato y ubicación física. Si hay ejemplares disponibles, el botón es Solicitar préstamo; si no, es Reservar.

  • Información completa del libro
  • Lista de ejemplares físicos disponibles
  • Acción adaptativa según disponibilidad
  • Si no hay sesión, redirige a login
Dauri Abad16 / 34
Biblioteca VirtualFuncionalidades / Auth
16 Acceso al sistema

Iniciar sesión o crear cuenta.

Login
/login
Registro
/registro

Layout dividido en dos paneles: a la izquierda el branding de Unicaribe con un mensaje de bienvenida, a la derecha el formulario. Las validaciones se hacen en cliente y en servidor. Las contraseñas siempre se envían sobre HTTPS y se almacenan con BCrypt.

Dauri Abad17 / 34
Biblioteca VirtualFuncionalidades / Lector
17 Mi biblioteca

Un dashboard de un vistazo.

Dashboard del lector
/mi-biblioteca

Al iniciar sesión, el lector ve su panel personal con tres tarjetas resumen: préstamos activos, reservas pendientes y multas por pagar.

  • Préstamos activos (máximo 3)
  • Reservas con cuenta regresiva
  • Total de multas en pesos dominicanos
  • Acceso rápido a cada sección
Dauri Abad18 / 34
Biblioteca VirtualFuncionalidades / Lector
18 Mis préstamos

Solicitar, renovar, devolver.

El lector ve todos sus préstamos con estado, ejemplar asignado y fecha de vencimiento. Si está activo, puede renovar. Si vence, se genera multa automática.

  • Estados: Pendiente, Activo, Devuelto, Vencido, Renovado
  • Renovación con un clic
  • Fechas de devolución calculadas (14 días estándar)
  • Multa automática por retraso (RD$50 por día)
Mis préstamos
/prestamos
Dauri Abad19 / 34
Biblioteca VirtualFuncionalidades / Lector
19 Mis reservas

La cola justa para libros sin stock.

Mis reservas
/reservas

Cuando todos los ejemplares de un libro están prestados, el lector se anota en la cola. El sistema le asigna posición y, cuando llega su turno, le da 48 horas para retirarlo.

  • Posición en cola visible
  • Notificación cuando se asigna el ejemplar
  • 48 horas para retirar antes de pasar al siguiente
  • Cancelable desde el panel
Dauri Abad20 / 34
Biblioteca VirtualFuncionalidades / Lector
20 Mis multas

Pagos simulados, registro real.

Las multas se calculan automáticamente al devolver un préstamo vencido. El usuario ve el detalle y puede iniciar un pago simulado (no se conecta a un banco real; es una pasarela de demostración con recibos y referencias generadas).

  • Cálculo automático por días de retraso
  • Pasarela simulada con aprobación/rechazo
  • Historial de intentos de pago
  • Recibo con número de referencia
Mis multas
/multas
Dauri Abad21 / 34
Biblioteca VirtualFuncionalidades / Lector
21 Notificaciones y perfil

Bandeja personal + datos de cuenta.

Notificaciones
/notificaciones
Mi perfil
/perfil

El sistema genera notificaciones internas cuando ocurre algo relevante: préstamo aprobado, reserva asignada, multa generada, pago confirmado. Se guardan en la base de datos y aparecen en la bandeja del usuario (no se envía email ni SMS real).

Dauri Abad22 / 34
Biblioteca VirtualSección 07 / Administración
22 Panel administrativo

Métricas operativas en tiempo real.

Admin Dashboard
/admin — Dashboard ejecutivo

El dashboard de administrador muestra de un vistazo el pulso de la biblioteca: cantidad de libros, usuarios, préstamos activos, vencidos, reservas y multas pendientes.

  • Seis KPIs principales en tarjetas pastel
  • Top libros más prestados
  • Usuarios más activos
  • Préstamos por mes (gráfico de barras)
  • Categorías populares
Jason Núñez23 / 34
Biblioteca VirtualAdministración / Usuarios
23 Gestión de usuarios

Activar, desactivar, cambiar rol.

El administrador puede ver todos los usuarios registrados, su rol (lector o administrador) y su estado (activo o inactivo). Puede activar o desactivar cuentas con un clic.

  • Lista completa con búsqueda
  • Roles: Lector, Administrador
  • Activación/desactivación con confirmación
  • Auditoría: cada cambio queda registrado
Admin Usuarios
/admin/usuarios
Jason Núñez24 / 34
Biblioteca VirtualAdministración / Catálogo
24 CRUD de catálogo

Crear, editar y eliminar libros, autores, categorías.

Admin Catálogo
/admin/catalogo — CRUD completo

El bibliotecario gestiona el catálogo desde acá: agrega libros nuevos, define autores y categorías, edita la información existente o elimina entradas (con confirmación destructiva).

  • Tres formularios paralelos
  • Validación servidor + cliente
  • Confirmación antes de borrar
  • Stock inicial al crear
Jason Núñez25 / 34
Biblioteca VirtualAdministración / Circulación
25 Circulación

Aprobar préstamos, preparar reservas.

El corazón operativo del sistema. Cuando un lector solicita un préstamo, queda en estado pendiente. El bibliotecario revisa la solicitud, asigna un ejemplar físico disponible y aprueba.

  • Solicitudes pendientes de aprobación
  • Préstamos activos (con devolución)
  • Reservas listas para retirar
  • Asignación de ejemplar físico
Admin Circulación
/admin/circulacion
Jason Núñez26 / 34
Biblioteca VirtualAdministración / Inventario
26 Inventario físico

Cada copia tiene su código.

Admin Inventario
/admin/inventario

El sistema distingue entre libro (la entrada del catálogo) y ejemplar (la copia física). Cada ejemplar tiene su código único, estado y ubicación en la biblioteca.

  • Códigos únicos por ejemplar
  • Estados: Disponible, Prestado, Reservado
  • Tipo: Físico o Digital
  • Ubicación: estante físico
Jason Núñez27 / 34
Biblioteca VirtualAdministración / Auditoría
27 Auditoría

Cada acción queda registrada.

La auditoría es append-only: una vez que un evento entra, nadie puede borrarlo ni modificarlo. Es la garantía de trazabilidad para la institución.

  • Quién hizo la acción
  • Qué entidad cambió
  • Cuándo (con timestamp)
  • Resultado (éxito o fallo)
Si no se puede borrar, no se puede ocultar.
Admin Auditoría
/admin/auditoria
Jason Núñez28 / 34
Biblioteca VirtualSección 08 / Despliegue
28 Contenedores Docker

Todo en cajas reproducibles.

Cada componente del sistema corre en un contenedor Docker aislado. Una sola red interna los conecta. Ningún puerto está abierto al exterior — el acceso es exclusivo a través del túnel.

  • postgres — base de datos con volumen persistente
  • backend — ASP.NET con build multi-stage (sdk → runtime)
  • frontend — Vite build sobre nginx alpine
  • cloudflared — el túnel hacia Cloudflare
# docker-compose.prod.yml
services:
  postgres:
    image: postgres:16-alpine
    volumes: [biblioteca_postgres_data:/var/lib/postgresql/data]

  backend:
    build: { dockerfile: backend/Dockerfile }
    depends_on:
      postgres: { condition: service_healthy }

  frontend:
    build: { dockerfile: frontend/Dockerfile }

  cloudflared:
    image: cloudflare/cloudflared:latest
    environment:
      TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN}

networks:
  biblioteca: { driver: bridge }
Alvaro29 / 34
Biblioteca VirtualDespliegue / Red
29 Cloudflare Tunnel

Servidor casero, exposición segura.

El servidor está en una PC vieja en casa. No abrimos puertos del router. No pagamos hosting. Cloudflare Tunnel actúa como puente: el agente cloudflared abre conexiones salientes hacia los edges de Cloudflare. Cuando alguien visita nuestro dominio, Cloudflare manda la petición por el túnel.

  • Cero puertos abiertos en el router
  • HTTPS automático con certificado de Cloudflare
  • IP pública oculta — Cloudflare es la cara
  • Sobrevive a cambios de IP del ISP
  • Protección DDoS incluida en el plan Free
USER biblioteca.alvaroacevedo.dev CLOUDFLARE EDGE NETWORK TLS termination / DDoS / DNS TUNEL (outbound) CASAOS / DOCKER NETWORK cloudflared frontend:80 backend:8080 postgres:5432
Alvaro30 / 34
Biblioteca VirtualSección 09 / Calidad
30 Testing automatizado

El código se prueba solo.

Cada vez que se modifica el código, los tests se ejecutan automáticamente. Si algo se rompe, lo sabemos antes de que un usuario lo descubra. Es la red de seguridad del proyecto.

17
Tests frontend
9
Suites backend
100%
Verde en CI
Frontend

Vitest + Testing Library

Tests de componentes con jsdom. Mockeo de servicios. Cobertura de pages, contexts y guardas de ruta.

Backend

xUnit + WebApplicationFactory

Tests de integración que arrancan la API real contra una BD en memoria. Validan endpoints, autenticación y reglas de negocio.

End-to-End

Playwright

Recorridos completos en navegador real (Chromium). Simulan flujos: login, reserva, devolución, pago de multa.

Jason Núñez31 / 34
Biblioteca VirtualSección 10 / Lecciones
31 Dificultades

Los problemas reales que enfrentamos.

01

Migraciones de EF Core al arrancar

El backend intentaba conectar antes de que Postgres estuviera listo y fallaba.

Resuelto: depends_on con condition: service_healthy en compose.
02

HTTPS detrás del túnel

ASP.NET creía que la conexión era HTTP y armaba redirects rotos.

Resuelto: middleware ForwardedHeaders confía en X-Forwarded-Proto.
03

Imagen .NET 10 ya trae usuario «app»

El Dockerfile intentaba crear ese usuario y chocaba (novedad de .NET 10).

Resuelto: eliminar el groupadd/useradd, usar el usuario que ya viene.
04

DNS de Docker fallaba con Cloudflare

cloudflared no resolvía argotunnel.com vía el resolver embebido (127.0.0.11).

Resuelto: forzamos DNS público (1.1.1.1) en el container del túnel.
05

SSL universal solo cubre un nivel

api.biblioteca.alvaroacevedo.dev fallaba el handshake — son dos niveles.

Resuelto: renombramos a api-biblioteca (un solo nivel).
06

Tapas de libros de ISBN ficticios

El seed usa ISBN 978-0-00-X que no existen en Open Library.

Resuelto: cascada portadaUrl → Open Library → Unsplash → gradiente.
Alvaro32 / 34
Biblioteca VirtualAprendizajes
32 Lo que nos llevamos

Lo que aprendimos en el camino.

Sobre programar

  • Separar capas no es burocracia; es lo que hace que el código siga vivo en seis meses.
  • Validar dos veces: en el cliente para UX, en el servidor para seguridad. Nunca solo uno.
  • Los tipos fuertes (C#) detectan errores que JavaScript te deja pasar.
  • Los nombres importan. Un método bien nombrado es documentación gratis.

Sobre construir software

  • Docker no es magia: es el seguro contra «en mi máquina sí funciona».
  • Los tests no son opcionales; son lo que permite cambiar código sin miedo.
  • La trazabilidad (auditoría, logs) salva carreras en producción.
  • Deployar es la mitad del proyecto. Codear local es la parte fácil.
Programar es resolver problemas. Las herramientas cambian; el método se queda.
Todos33 / 34
Biblioteca VirtualFin
33 Cierre

Gracias por escucharnos.

El proyecto está vivo en biblioteca.alvaroacevedo.dev y el código fuente está abierto en github.com/varocode/biblioteca-virtual.

Alvaro Acevedo Dauri Abad Daniel Asencio Johancer Basiel Jason Núñez

¿Preguntas?

Todos34 / 34