Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Distribuidos-Org/ms-alumnos/llms.txt

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

This page documents the Alumno entity class, which is decorated with @Entity('alumnos') and maps directly to the alumnos PostgreSQL table. It is the canonical data shape returned by every read and write operation in the service — including find_all_alumnos, find_one_alumno, create_alumno, and update_alumno. All column constraints, defaults, and unique indexes described here are enforced at the database level by TypeORM’s schema synchronisation.

Entity definition

import { BeforeInsert, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import * as bcrypt from 'bcrypt';

@Entity('alumnos')
export class Alumno {
  @PrimaryGeneratedColumn({ name: 'alumno_id' })
  alumnoId: number;

  @Column({ length: 50 })
  nombre: string;

  @Column({ name: 'apellido_paterno', length: 50 })
  apellidoPaterno: string;

  @Column({ name: 'apellido_materno', length: 50 })
  apellidoMaterno?: string;

  @Column({ length: 8, unique: true })
  dni: string;

  @Column({ type: 'int', nullable: true })
  edad?: number;

  @Column({ length: 100, unique: true })
  email: string;

  @Column({ length: 15, nullable: true })
  celular?: string;

  @Column({ length: 100, default: 'UNMSM' })
  universidad: string;

  @Column({ length: 100, nullable: true })
  facultad?: string;

  @Column({ length: 50, nullable: true })
  profesion?: string;

  @Column({ length: 50, nullable: true })
  grado?: string;

  @Column({ name: 'egresado_local', default: true })
  egresadoLocal: boolean;

  @Column({ length: 60, name: 'contrasena' })
  contrasena: string;

  @BeforeInsert()
  async hashPassword() {
    this.contrasena = await bcrypt.hash(this.contrasena, 10);
  }
}

Fields

alumnoId
number
Auto-increment primary key. Maps to the alumno_id column. Generated by the database on each INSERT; clients should never supply this value when creating a record.
nombre
string
The student’s first name. Maximum 50 characters. Required on create.
apellidoPaterno
string
Paternal surname. Maps to the apellido_paterno column. Maximum 50 characters. Required on create.
apellidoMaterno
string | undefined
Maternal surname. Maps to the apellido_materno column. Maximum 50 characters. Optional — the column is not marked nullable: true at the database level, but the TypeScript property is optional (?).
dni
string
National identity document number (DNI). Exactly 8 characters long (enforced by the DTO with @MinLength(8) and @MaxLength(8)). Carries a unique constraint — no two alumno rows may share the same DNI.
edad
number | undefined
The student’s age in whole years. Stored as a PostgreSQL INT. Optional and nullable — the column is defined with { type: 'int', nullable: true }.
email
string
Email address. Maximum 100 characters. Carries a unique constraint — no two alumno rows may share the same email address.
celular
string | undefined
Mobile phone number. Maximum 15 characters. Optional and nullable (nullable: true).
universidad
string
Name of the university the student attended. Maximum 100 characters. Defaults to 'UNMSM' if not supplied on create.
facultad
string | undefined
Faculty or school within the university. Maximum 100 characters. Optional and nullable.
profesion
string | undefined
The student’s profession or field of study. Maximum 50 characters. Optional and nullable.
grado
string | undefined
Academic degree level (e.g., 'Bachiller', 'Licenciado', 'Magíster', 'Doctor'). Maximum 50 characters. Optional and nullable.
egresadoLocal
boolean
Whether the student graduated from a local (same-city) campus. Maps to the egresado_local column. Defaults to true if not supplied on create.
contrasena
string
The student’s password, stored as a bcrypt hash. Maps to the contrasena column. Maximum 60 characters in the database, which matches the fixed-length output of a bcrypt hash at any cost factor. The plain-text password provided on create is replaced by its hash before the row is written (see Lifecycle hooks below).

Lifecycle hooks

The entity declares one @BeforeInsert() hook:
@BeforeInsert()
async hashPassword() {
  this.contrasena = await bcrypt.hash(this.contrasena, 10);
}
Every time a new Alumno is persisted with repository.save() on a newly created entity, TypeORM fires hashPassword() before issuing the SQL INSERT. The method replaces this.contrasena with a bcrypt hash computed at a cost factor of 10 rounds. This means:
  • Plain-text passwords are never written to the database.
  • The @BeforeInsert() hook only fires on INSERT, not on UPDATE. Password changes during an update must be handled separately if required.
  • The seed operation benefits from this hook automatically — all 100 sample records have their 'contrasena' string hashed before insertion.

Unique constraints

Two columns carry database-level unique constraints:
ColumnTypeORM optionEffect
dni{ unique: true }No two students may have the same national ID number.
email{ unique: true }No two students may share an email address.
Attempting to insert or update a record with a duplicate dni or email will cause PostgreSQL to raise a unique-violation error. TypeORM surfaces this as an unhandled exception, which NestJS propagates to the NATS caller as a 500-level RpcException unless the service layer catches and re-throws it explicitly.
contrasena is present on the Alumno TypeScript object returned from the repository, but it contains the bcrypt hash, not the plain-text password. The service layer does not strip this field before returning the entity to callers. If you are building a gateway or client that forwards alumno records to end users, make sure to omit the contrasena field from any outward-facing response to avoid leaking credential hashes.

Build docs developers (and LLMs) love