Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/camiloivcode/biblioteca-la-palabra/llms.txt

Use this file to discover all available pages before exploring further.

La base de datos del sistema utiliza MySQL 8 como motor relacional y Prisma ORM como capa de acceso a datos. Todos los nombres de tablas y columnas están mapeados al español mediante las directivas @@map y @map del schema. El esquema se sincroniza con la base de datos usando db push en lugar de migraciones versionadas (el directorio migrations/ está en .gitignore).

Modelos y relaciones

El diagrama de relaciones entre entidades es el siguiente:
User (1) ──── <no relation>
Socio (1) ──── (N) Prestamo (N) ──── (1) Material
Autor (1) ──── (N) Material
Categoria (1) ──── (N) Material
Cada modelo tiene su tabla correspondiente en MySQL:
ModeloTablaDescripción
UserusersUsuarios del sistema con rol ADMIN o BIBLIOTECARIO
SociosociosSocios registrados de la biblioteca
AutorautoresAutores de los materiales del catálogo
CategoriacategoriasCategorías temáticas con icono configurable
MaterialmaterialesCatálogo de materiales: libros, revistas, DVD, etc.
PrestamoprestamosPréstamos de materiales a socios con fechas y estado
Todas las tablas usan IDs autoincrementales (Int @id @default(autoincrement())), y la mayoría incluyen timestamps created_at y updated_at gestionados automáticamente por Prisma.

Enums

El schema define cinco enumeraciones que controlan los estados y tipos posibles en el sistema:
EnumValoresUsado en
RoleADMIN, BIBLIOTECARIOUser.role
EstadoSocioACTIVO, SUSPENDIDO, MOROSOSocio.estado
EstadoMaterialDISPONIBLE, PRESTADO, EN_REPARACION, DADO_DE_BAJAMaterial.estado
EstadoPrestamoACTIVO, DEVUELTO, MORAPrestamo.estado
TipoMaterialLIBRO, REVISTA, DVD, PERIODICO, OTROMaterial.tipo

Schema Prisma

El schema completo define los generadores, el datasource y los seis modelos de la aplicación:
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

enum Role {
  ADMIN
  BIBLIOTECARIO
}

enum EstadoSocio {
  ACTIVO
  SUSPENDIDO
  MOROSO
}

enum EstadoMaterial {
  DISPONIBLE
  PRESTADO
  EN_REPARACION
  DADO_DE_BAJA
}

enum EstadoPrestamo {
  ACTIVO
  DEVUELTO
  MORA
}

enum TipoMaterial {
  LIBRO
  REVISTA
  DVD
  PERIODICO
  OTRO
}

model User {
  id                   Int       @id @default(autoincrement())
  nombre               String    @db.VarChar(100)
  email                String    @unique @db.VarChar(150)
  password             String    @db.VarChar(255)
  role                 Role      @default(BIBLIOTECARIO)
  activo               Boolean   @default(true)
  passwordResetToken   String?   @map("password_reset_token") @db.VarChar(255)
  passwordResetExpires DateTime? @map("password_reset_expires")
  createdAt            DateTime  @default(now()) @map("created_at")
  updatedAt            DateTime  @updatedAt @map("updated_at")

  @@map("users")
}

model Socio {
  id          Int         @id @default(autoincrement())
  nombre      String      @db.VarChar(100)
  apellido    String      @db.VarChar(100)
  dni         String      @unique @db.VarChar(20)
  email       String?     @unique @db.VarChar(150)
  telefono    String?     @db.VarChar(20)
  direccion   String?     @db.VarChar(255)
  fechaNac    DateTime?   @map("fecha_nac") @db.Date
  estado      EstadoSocio @default(ACTIVO)
  createdAt   DateTime    @default(now()) @map("created_at")
  updatedAt   DateTime    @updatedAt @map("updated_at")
  prestamos   Prestamo[]

  @@map("socios")
}

model Autor {
  id           Int        @id @default(autoincrement())
  nombre       String     @db.VarChar(100)
  apellido     String     @db.VarChar(100)
  nacionalidad String?    @db.VarChar(80)
  biografia    String?    @db.Text
  createdAt    DateTime   @default(now()) @map("created_at")
  updatedAt    DateTime   @updatedAt @map("updated_at")
  materiales   Material[]

  @@unique([nombre, apellido])
  @@map("autores")
}

model Categoria {
  id          Int        @id @default(autoincrement())
  nombre      String     @unique @db.VarChar(100)
  descripcion String?    @db.Text
  icono       String     @default("category") @db.VarChar(50)
  createdAt   DateTime   @default(now()) @map("created_at")
  materiales  Material[]

  @@map("categorias")
}

model Material {
  id          Int            @id @default(autoincrement())
  titulo      String         @db.VarChar(255)
  isbn        String?        @unique @db.VarChar(30)
  tipo        TipoMaterial   @default(LIBRO)
  anioPubl    Int?           @map("anio_publ")
  editorial   String?        @db.VarChar(150)
  descripcion String?        @db.Text
  stock       Int            @default(1)
  estado      EstadoMaterial @default(DISPONIBLE)
  autorId     Int            @map("autor_id")
  categoriaId Int            @map("categoria_id")
  createdAt   DateTime       @default(now()) @map("created_at")
  updatedAt   DateTime       @updatedAt @map("updated_at")
  autor       Autor          @relation(fields: [autorId], references: [id])
  categoria   Categoria      @relation(fields: [categoriaId], references: [id])
  prestamos   Prestamo[]

  @@map("materiales")
}

model Prestamo {
  id              Int            @id @default(autoincrement())
  socioId         Int            @map("socio_id")
  materialId      Int            @map("material_id")
  fechaPrestamo   DateTime       @default(now()) @map("fecha_prestamo")
  fechaDevolucion DateTime       @map("fecha_devolucion")
  fechaDevReal    DateTime?      @map("fecha_dev_real")
  estado          EstadoPrestamo @default(ACTIVO)
  observaciones   String?        @db.Text
  createdAt       DateTime       @default(now()) @map("created_at")
  updatedAt       DateTime       @updatedAt @map("updated_at")
  socio           Socio          @relation(fields: [socioId], references: [id])
  material        Material       @relation(fields: [materialId], references: [id])

  @@map("prestamos")
}

Reglas de negocio

Todas las reglas se aplican en la capa de servicios del backend, antes de ejecutar cualquier operación sobre la base de datos.
  • Máximo 3 préstamos activos por socio. Intentar crear un cuarto préstamo activo devuelve error 400.
  • Un socio en estado MOROSO no puede tomar nuevos préstamos hasta que regularice su situación.
  • Los préstamos con más de 30 días de retraso pasan automáticamente al estado MORA cuando se consultan o actualizan.
  • No se puede prestar un material con stock igual a 0 o cuyo estado sea distinto de DISPONIBLE.
  • Al registrar un préstamo: se decrementa el stock del material (stock--). Si el stock llega a 0, el estado del material cambia a PRESTADO.
  • Al registrar una devolución: se incrementa el stock (stock++). Si el stock vuelve a ser mayor que 0, el estado cambia a DISPONIBLE.
  • No se puede eliminar un autor que tenga materiales asociados en el catálogo.
  • No se puede eliminar un socio que tenga préstamos activos pendientes de devolución.
  • No se puede eliminar una categoría que tenga materiales asociados en el catálogo.

Gestión del schema

Dado que el proyecto usa db push en lugar de migraciones, el flujo de trabajo para modificar el schema es:
  1. Editar backend/prisma/schema.prisma.
  2. Regenerar el cliente Prisma con los nuevos tipos:
# Dentro de backend/
npm run db:generate
  1. Sincronizar el schema con la base de datos (aplica los cambios directamente):
npm run db:push
  1. Opcionalmente, repoblar la base de datos con datos de prueba:
npm run db:seed
# equivalente a: node prisma/seed.js
El seed es idempotente: usa upsert() internamente, por lo que puede ejecutarse múltiples veces sin generar registros duplicados.

Datos del seed

Al ejecutar db:seed, se insertan los siguientes datos iniciales:
EntidadCantidadDetalle
Usuarios21 ADMIN + 1 BIBLIOTECARIO
Categorías6Literatura, Historia, Ciencias, Filosofía, Arte, Tecnología
Autores5García Márquez, Borges, Allende, Vargas Llosa, Cortázar
Socios3María González, Carlos López, Ana Martínez
Materiales2Cien Años de Soledad, Ficciones
Las credenciales de acceso creadas por el seed son:
RolEmailContraseña
ADMINadmin@biblioteca.comAdmin2024!
BIBLIOTECARIObibliotecario@biblioteca.comBiblio2024!

Build docs developers (and LLMs) love