Skip to content

Archivos de la Carpeta models

La carpeta src/models contiene las definiciones de los modelos de base de datos utilizando Sequelize y sequelize-typescript. Estos modelos son la representación de las tablas de tu base de datos como clases en TypeScript, permitiendo interactuar con los datos de forma orientada a objetos. Son esenciales para la estructura y la persistencia de los datos, definiendo los campos, sus tipos de datos, validaciones y las relaciones entre las diferentes entidades de la aplicación.

student.model.ts

Este archivo define el modelo de la base de datos para la entidad Estudiante, incluyendo sus atributos, tipos de datos y ganchos (hooks) para el manejo de fechas.

  • Descripción: Es una clase TypeScript que extiende Model de sequelize-typescript, decorada con @Table para indicar que es un modelo de Sequelize. Define todas las columnas que corresponden a la tabla de estudiantes en la base de datos, especificando sus tipos de datos, nulabilidad, valores por defecto y validaciones. Incluye un hook BeforeCreate/BeforeUpdate para ajustar las fechas a la zona horaria de Chile.
  • Propósito: Representar la estructura de la tabla students en la base de datos, facilitando las operaciones CRUD (Crear, Leer, Actualizar, Eliminar) sobre los datos de los estudiantes de manera tipada y segura. También asegura la consistencia de las fechas almacenadas.
  • Funcionalidad:
    • Definición de columnas: Cada propiedad de la clase Student con un decorador @Column se mapea a una columna en la tabla students (ej., id, name, email, birthdate, linkDni, studentImageDriveId).
    • Tipos de datos y validaciones: Utiliza decoradores como @IsUUID, @PrimaryKey, @Default, @AllowNull, @Column(DataType.STRING/DATE/TEXT/UUID) para definir las características de la base de datos y las validaciones.
    • @BeforeCreate / BeforeUpdate hook: El método estático adjustDates se ejecuta automáticamente antes de que un nuevo registro de estudiante sea creado o un registro existente sea actualizado.
    • Manejo de zonas horarias: La función adjustDateToChileTimezone (usando luxon) convierte las fechas a la zona horaria de "America/Santiago" antes de guardarlas, garantizando la consistencia horaria.
  • Rol en la aplicación: Es la interfaz principal para la gestión de datos de estudiantes en la base de datos. Permite a los servicios y controladores interactuar con la información de los estudiantes de forma abstracta, sin tener que escribir SQL directamente. La gestión de fechas asegura que los datos temporales sean precisos para la ubicación geográfica de la aplicación.
ts
import {
  AllowNull, // Decorador para especificar si la columna permite valores nulos
  Column, // Decorador para definir una columna de la tabla
  DataType, // Tipos de datos de Sequelize (ej. STRING, DATE, UUID)
  Default, // Decorador para asignar un valor por defecto a la columna
  IsUUID, // Decorador para validar si el valor es un UUID
  Model, // Clase base de Sequelize para definir un modelo
  PrimaryKey, // Decorador para definir la clave primaria de la tabla
  Table, // Decorador para asociar la clase con una tabla de la base de datos
  BeforeCreate, // Hook que se ejecuta antes de crear un registro
  BeforeUpdate, // Hook que se ejecuta antes de actualizar un registro
} from "sequelize-typescript";
import { DateTime } from "luxon"; // Importa DateTime de la librería Luxon para manejo avanzado de fechas

@Table // Decorador que marca la clase 'Student' como un modelo de tabla en Sequelize
export class Student extends Model {
  @IsUUID(4) // Valida que el ID sea un UUID versión 4
  @PrimaryKey // Marca 'id' como la clave primaria de la tabla
  @Default(DataType.UUIDV4) // Asigna automáticamente un UUID v4 por defecto al crear un nuevo registro
  @Column(DataType.UUID) // Define 'id' como una columna de tipo UUID en la base de datos
  declare id: string; // Declaración de la propiedad 'id'

  @AllowNull(true) // Permite que el campo 'email' sea nulo
  @Column(DataType.STRING) // Define 'email' como una columna de tipo cadena
  declare email?: string; // Declaración de la propiedad 'email' (opcional)

  @AllowNull(false) // No permite que el campo 'name' sea nulo (es obligatorio)
  @Column(DataType.STRING) // Define 'name' como una columna de tipo cadena
  declare name: string; // Declaración de la propiedad 'name'

  @AllowNull(false) // No permite que el campo 'lastname' sea nulo (es obligatorio)
  @Column(DataType.STRING) // Define 'lastname' como una columna de tipo cadena
  declare lastname: string; // Declaración de la propiedad 'lastname'

  @Column(DataType.STRING) // Define 'rut' como una columna de tipo cadena
  declare rut?: string; // Declaración de la propiedad 'rut' (opcional)

  @Column(DataType.DATE) // Define 'birthdate' como una columna de tipo fecha
  declare birthdate?: Date | null | undefined; // Declaración de la propiedad 'birthdate' (opcional, puede ser nula)

  @Column(DataType.STRING) // Define 'sex' como una columna de tipo cadena
  declare sex?: string; // Declaración de la propiedad 'sex' (opcional)

  @Column(DataType.TEXT) // Define 'address' como una columna de tipo texto (para cadenas largas)
  declare address?: string; // Declaración de la propiedad 'address' (opcional)

  @Column(DataType.STRING) // Define 'nationality' como una columna de tipo cadena
  declare nationality?: string; // Declaración de la propiedad 'nationality' (opcional)

  @Column(DataType.STRING) // Define 'source' como una columna de tipo cadena
  declare source?: string; // Declaración de la propiedad 'source' (opcional)

  @Column(DataType.TEXT) // Define 'contact' como una columna de tipo texto
  declare contact?: string; // Declaración de la propiedad 'contact' (opcional)

  @AllowNull(true) // Permite que el campo 'phone' sea nulo
  @Column(DataType.STRING) // Define 'phone' como una columna de tipo cadena
  declare phone?: string | null; // Declaración de la propiedad 'phone' (opcional, puede ser nula)

  @Column(DataType.DATE) // Define 'contactDate' como una columna de tipo fecha
  declare contactDate?: Date | null | undefined; // Declaración de la propiedad 'contactDate' (opcional, puede ser nula)

  @Column(DataType.STRING) // Define 'call1' como una columna de tipo cadena
  declare call1?: string; // Declaración de la propiedad 'call1' (opcional)

  @Column(DataType.STRING) // Define 'call2' como una columna de tipo cadena
  declare call2?: string; // Declaración de la propiedad 'call2' (opcional)

  @Column(DataType.STRING) // Define 'call3' como una columna de tipo cadena
  declare call3?: string; // Declaración de la propiedad 'call3' (opcional)

  @Column(DataType.STRING) // Define 'comments1' como una columna de tipo cadena
  declare comments1?: string; // Declaración de la propiedad 'comments1' (opcional)

  @Column(DataType.STRING) // Define 'comments2' como una columna de tipo cadena
  declare comments2?: string; // Declaración de la propiedad 'comments2' (opcional)

  @Column(DataType.STRING) // Define 'comments3' como una columna de tipo cadena
  declare comments3?: string; // Declaración de la propiedad 'comments3' (opcional)

  @Column(DataType.STRING) // Define 'positiveFeedback' como una columna de tipo cadena
  declare positiveFeedback?: string; // Declaración de la propiedad 'positiveFeedback' (opcional)

  @Column(DataType.TEXT) // Define 'linkDni' como una columna de tipo texto (para URL)
  declare linkDni?: string; // Declaración de la propiedad 'linkDni' (opcional)

  @Column(DataType.TEXT) // Define 'birthCertificate' como una columna de tipo texto (para URL)
  declare birthCertificate?: string; // Declaración de la propiedad 'birthCertificate' (opcional)

  @Column(DataType.TEXT) // Define 'studyCertificate' como una columna de tipo texto (para URL)
  declare studyCertificate?: string; // Declaración de la propiedad 'studyCertificate' (opcional)

  @Column(DataType.TEXT) // Define 'studentImage' como una columna de tipo texto (para URL)
  declare studentImage?: string; // Declaración de la propiedad 'studentImage' (opcional)

  // Nuevas columnas para los IDs de Google Drive asociados a los archivos subidos
  @Column(DataType.TEXT)
  declare studentImageDriveId?: string | null; // ID de la imagen del estudiante en Google Drive

  @Column(DataType.TEXT)
  declare birthCertificateDriveId?: string | null; // ID del certificado de nacimiento en Google Drive

  @Column(DataType.TEXT)
  declare studyCertificateDriveId?: string | null; // ID del certificado de estudio en Google Drive

  @Column(DataType.TEXT)
  declare linkDniDriveId?: string | null; // ID del DNI en Google Drive

  @Column(DataType.STRING) // Define 'school' como una columna de tipo cadena
  declare school?: string; // Declaración de la propiedad 'school' (opcional)

  @Column(DataType.STRING) // Define 'course' como una columna de tipo cadena
  declare course?: string; // Declaración de la propiedad 'course' (opcional)

  @Column(DataType.STRING) // Define 'communicationPreference' como una columna de tipo cadena
  declare communicationPreference?: string; // Declaración de la propiedad 'communicationPreference' (opcional)

  @Default(DataType.NOW) // Asigna la fecha y hora actual por defecto al crear un registro
  @Column(DataType.DATE) // Define 'createdAt' como una columna de tipo fecha
  declare createdAt?: Date | null | undefined; // Declaración de la propiedad 'createdAt' (opcional)

  /*
   * Hook de Sequelize que se ejecuta antes de que un nuevo registro sea creado
   * o antes de que un registro existente sea actualizado.
   * Su propósito es ajustar las fechas a la zona horaria específica de Chile.
   */
  @BeforeCreate
  @BeforeUpdate
  static adjustDates(instance: Student) {
    /*
     * Función auxiliar para ajustar una fecha a la zona horaria de Santiago, Chile.
     * Si la fecha es nula o indefinida, la retorna tal cual.
     * Utiliza Luxon para parsear la fecha y establecer la zona horaria antes de convertirla de nuevo a un objeto Date.
     */
    const adjustDateToChileTimezone = (date: Date | undefined | null) => {
      if (!date) return date;
      return DateTime.fromJSDate(date).setZone("America/Santiago").toJSDate();
    };

    // Aplica el ajuste de zona horaria a la fecha de nacimiento si existe.
    if (instance.birthdate) {
      instance.birthdate = adjustDateToChileTimezone(instance.birthdate);
    }

    // Aplica el ajuste de zona horaria a la fecha de contacto si existe.
    if (instance.contactDate) {
      instance.contactDate = adjustDateToChileTimezone(instance.contactDate);
    }

    // Aplica el ajuste de zona horaria a la fecha de creación si existe.
    // Aunque @Default(DataType.NOW) ya pone la fecha, el hook permite ajustarla a la TZ correcta.
    if (instance.createdAt) {
      instance.createdAt = adjustDateToChileTimezone(instance.createdAt);
    }
  }
}

user.model.ts

Este archivo define el modelo de la base de datos para la entidad Usuario, especificando sus atributos y propiedades.

  • Descripción: Es una clase TypeScript que extiende Model de sequelize-typescript, decorada con @Table para indicar que es un modelo de Sequelize. Define las columnas id, email, password y role, estableciendo sus tipos, nulabilidad y restricciones únicas para el email.
  • Propósito: Representar la estructura de la tabla users en la base de datos, lo que permite a la aplicación gestionar la autenticación y la autorización de usuarios de forma estructurada y segura.
  • Funcionalidad:
    • Definición de columnas: Cada propiedad de la clase User con un decorador @Column se mapea a una columna en la tabla users.
    • id: Clave primaria, UUID v4, con valor por defecto generado automáticamente.
    • email: Columna de tipo cadena, no nula y con restricción Unique, asegurando que no haya dos usuarios con el mismo email.
    • password: Columna de tipo cadena, no nula, para almacenar la contraseña (generalmente un hash).
    • role: Columna de tipo cadena, no nula, para definir el rol del usuario (ej., "admin", "catcher").
    • Tipos de datos y validaciones: Utiliza decoradores como @IsUUID, @PrimaryKey, @Default, @AllowNull, @Unique, @Column(DataType.STRING/UUID).
  • Rol en la aplicación: Es fundamental para la gestión de la identidad y el acceso de los usuarios. Permite a la aplicación registrar, autenticar y autorizar a los usuarios, controlando el acceso a diferentes funcionalidades y recursos de la API.
ts
import {
  AllowNull, // Decorador para especificar si la columna permite valores nulos
  Column, // Decorador para definir una columna de la tabla
  DataType, // Tipos de datos de Sequelize (ej. STRING, UUID)
  Default, // Decorador para asignar un valor por defecto a la columna
  IsUUID, // Decorador para validar si el valor es un UUID
  Model, // Clase base de Sequelize para definir un modelo
  PrimaryKey, // Decorador para definir la clave primaria de la tabla
  Table, // Decorador para asociar la clase con una tabla de la base de datos
  Unique, // Decorador para asegurar que los valores en esta columna sean únicos
} from "sequelize-typescript";

@Table // Decorador que marca la clase 'User' como un modelo de tabla en Sequelize
export class User extends Model {
  @IsUUID(4) // Valida que el ID sea un UUID versión 4
  @PrimaryKey // Marca 'id' como la clave primaria de la tabla
  @Default(DataType.UUIDV4) // Asigna automáticamente un UUID v4 por defecto al crear un nuevo registro
  @Column(DataType.UUID) // Define 'id' como una columna de tipo UUID en la base de datos
  declare id: string; // Declaración de la propiedad 'id'

  @AllowNull(false) // No permite que el campo 'email' sea nulo (es obligatorio)
  @Unique // Asegura que cada email sea único en la tabla (no puede haber dos usuarios con el mismo email)
  @Column(DataType.STRING) // Define 'email' como una columna de tipo cadena
  declare email: string; // Declaración de la propiedad 'email'

  @AllowNull(false) // No permite que el campo 'password' sea nulo (es obligatorio)
  @Column(DataType.STRING) // Define 'password' como una columna de tipo cadena
  declare password: string; // Declaración de la propiedad 'password' (generalmente se almacena un hash de la contraseña)

  @AllowNull(false) // No permite que el campo 'role' sea nulo (es obligatorio)
  @Column(DataType.STRING) // Define 'role' como una columna de tipo cadena
  declare role: string; // Declaración de la propiedad 'role' (ej. "admin", "editor", "visit")
}