Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Zapiony/PUCE_UZDI_2026/llms.txt

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

The Users API manages system accounts stored in the seguridad.prsn PostgreSQL table. Each record represents a staff member (Técnico, Coordinador, or Administrador) who can log in to the UZDI platform. All endpoints require a valid Bearer token — the current implementation does not enforce role-based guards at the controller level.
All endpoints share the global prefix /api/v1. The base path for this resource is /api/v1/users.

Entity — seguridad.prsn

The TypeORM entity maps application field names to the underlying database column names. The table below shows both.
App fieldDB columnTypeConstraintsDescription
idprsn_idint4PK, auto-incrementInternal primary key
uzdi_iduzdi_idint4nullableFK to the UZDI unit
tppr_idtppr_idint4nullableProfile/role (1=Técnico, 2=Coordinador, 3=Administrador)
nombresprsnnmbrvarchar(31)not nullFirst name(s)
apellidosprsnapllvarchar(31)not nullLast name(s)
sexoprsnsexochar(1)nullable'M', 'F', or 'O'
direccionprsndirevarchar(255)nullableStreet address
telefonoprsntelfvarchar(63)nullablePhone number
correoprsnmailvarchar(63)nullableEmail address
loginprsnlognvarchar(30)unique, not nullLogin handle
passwordprsnpassvarchar(63)not nullbcrypt hash — never returned by the API
observacionesprsnobsrvarchar(255)nullableFree-text notes
The password field is always stripped from responses. Plain-text passwords submitted on POST and PATCH are hashed with bcrypt (cost factor 10) by the service before being persisted.

GET /api/v1/users

Returns a lightweight list of all users. Only the fields needed for display are selected (id, nombres, apellidos, correo, login, uzdi_id). Authentication required: Bearer token Request body: None

Success response — 200 OK

message
string
'Listado general de usuarios'
data
array
Array of user summary objects.

Example

curl -X GET https://api.example.com/api/v1/users \
  -H "Authorization: Bearer <token>"
Example response:
{
  "message": "Listado general de usuarios",
  "data": [
    {
      "id": 1,
      "nombres": "María",
      "apellidos": "García",
      "correo": "[email protected]",
      "login": "mgarcia",
      "uzdi_id": 2
    },
    {
      "id": 2,
      "nombres": "Carlos",
      "apellidos": "López",
      "correo": "[email protected]",
      "login": "clopez",
      "uzdi_id": 1
    }
  ]
}

POST /api/v1/users

Creates a new user account. The service checks for login and correo uniqueness before hashing the password and saving the record. The saved password field is stripped before the response is returned. Authentication required: Bearer token

Request body

nombres
string
required
First name(s). Max 31 characters.
apellidos
string
required
Last name(s). Max 31 characters.
login
string
required
Unique login handle. Max 30 characters. Must not already exist in the database.
password
string
required
Plain-text password. The service hashes it with bcrypt before storage — the raw value is never persisted.
correo
string
required
Valid email address. Must not already be registered to another user.
sexo
string
One of 'M' (Masculino), 'F' (Femenino), or 'O' (Otro). Optional.
direccion
string
Street address. Max 255 characters. Optional.
telefono
string
Phone number. Max 63 characters. Optional.
uzdi_id
number
FK to the UZDI unit. Optional.
tppr_id
number
Profile/role identifier. Optional. Accepted values: 1 (Técnico), 2 (Coordinador), 3 (Administrador).
roles_ids
number[]
Array of additional role IDs. Optional — accepted by the DTO but not yet consumed by the service.
observaciones
string
Free-text notes. Max 255 characters. Optional.

Success response — 201 Created

message
string
'Usuario registrado correctamente'
data
object
Full user object (all fields except password).

Error responses

StatusBodyCause
409 Conflict{ "message": "El login o correo ya está en uso" }Duplicate login or correo value.
400 Bad RequestValidation error arrayA required field is missing or fails format validation.

Example

curl -X POST https://api.example.com/api/v1/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "nombres": "Ana",
    "apellidos": "Morales",
    "login": "amorales",
    "password": "secure1234",
    "correo": "[email protected]",
    "tppr_id": 1,
    "uzdi_id": 3
  }'
Example response:
{
  "message": "Usuario registrado correctamente",
  "data": {
    "id": 15,
    "uzdi_id": 3,
    "tppr_id": 1,
    "nombres": "Ana",
    "apellidos": "Morales",
    "sexo": null,
    "direccion": null,
    "telefono": null,
    "correo": "[email protected]",
    "login": "amorales",
    "observaciones": null
  }
}
The login field must be unique across the entire seguridad.prsn table (varchar(30), unique constraint). Attempting to register a duplicate login returns 409 Conflict.

GET /api/v1/users/search?q=

Full-text search across nombres, apellidos, login, and correo columns using SQL LIKE (%query%). Returns a summary projection that omits uzdi_id (unlike GET /users). Authentication required: Bearer token

Query parameters

q
string
required
Search term. Matched case-insensitively against nombres, apellidos, login, and correo.

Success response — 200 OK

message
string
'Resultados de búsqueda para: {q}'
data
array
Array of matching user summary objects (id, nombres, apellidos, correo, login).

Example

curl -G https://api.example.com/api/v1/users/search \
  -H "Authorization: Bearer <token>" \
  --data-urlencode "q=ana"
Example response:
{
  "message": "Resultados de búsqueda para: ana",
  "data": [
    {
      "id": 15,
      "nombres": "Ana",
      "apellidos": "Morales",
      "correo": "[email protected]",
      "login": "amorales"
    }
  ]
}

GET /api/v1/users/:id

Retrieves a single user by primary key. The full entity is returned (minus the password field). Authentication required: Bearer token

Path parameters

id
number
required
The user’s numeric primary key (prsn_id).

Success response — 200 OK

message
string
'Usuario con ID {id}'
data
object
Full user object (all entity fields except password).

Error responses

StatusBodyCause
404 Not Found{ "message": "Usuario no encontrado" }No user with the given id exists.

Example

curl -X GET https://api.example.com/api/v1/users/15 \
  -H "Authorization: Bearer <token>"

PATCH /api/v1/users/:id

Partially updates one or more fields on an existing user. All UpdateUserDto fields are optional — only the fields included in the request body are modified. If password is included it is re-hashed before being saved. Authentication required: Bearer token

Path parameters

id
number
required
Numeric ID of the user to update.

Request body

All fields are optional. Any subset of the CreateUserDto fields may be supplied:
nombres
string
Updated first name(s).
apellidos
string
Updated last name(s).
login
string
Updated login handle (must remain unique, max 30 chars).
password
string
New plain-text password — will be bcrypt-hashed before storage.
correo
string
Updated email address (must remain unique).
sexo
string
One of 'M', 'F', or 'O'.
direccion
string
Updated street address.
telefono
string
Updated phone number.
uzdi_id
number
Updated UZDI unit FK.
tppr_id
number
Updated profile/role identifier.
roles_ids
number[]
Updated array of additional role IDs.
observaciones
string
Updated free-text notes.

Success response — 200 OK

message
string
'Información del usuario actualizada'
data
object
The full updated user object (all entity fields except password).

Error responses

StatusBodyCause
404 Not Found{ "message": "Usuario no encontrado" }No user with the given id exists.
400 Bad RequestValidation error arrayA supplied field fails format validation.

Example

curl -X PATCH https://api.example.com/api/v1/users/15 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "telefono": "0987654321",
    "uzdi_id": 4,
    "observaciones": "Traslado de unidad"
  }'
Example response:
{
  "message": "Información del usuario actualizada",
  "data": {
    "id": 15,
    "uzdi_id": 4,
    "tppr_id": 1,
    "nombres": "Ana",
    "apellidos": "Morales",
    "sexo": null,
    "direccion": null,
    "telefono": "0987654321",
    "correo": "[email protected]",
    "login": "amorales",
    "observaciones": "Traslado de unidad"
  }
}
Sending password in a PATCH body is fully supported. The service detects the presence of the field and bcrypt-hashes it with a fresh salt before calling userRepository.update().

DELETE /api/v1/users/:id

Removes a user from the system. The current implementation performs a hard delete via userRepository.delete(id). Future iterations will introduce a logical deactivation field (estado) to support soft-delete semantics. Authentication required: Bearer token

Path parameters

id
number
required
Numeric ID of the user to remove.

Success response — 200 OK

message
string
'Usuario con ID {id} desactivado/eliminado exitosamente'

Error responses

StatusBodyCause
404 Not Found{ "message": "Usuario no encontrado" }No user with the given id exists.

Example

curl -X DELETE https://api.example.com/api/v1/users/15 \
  -H "Authorization: Bearer <token>"
The current implementation issues a hard DELETE. Until a logical deactivation column (estado) is added to seguridad.prsn, deletion is irreversible. Coordinate with the database administrator before removing accounts in production.

Password handling summary

OperationBehaviour
POST /users (create)Plain-text passwordbcrypt.genSalt(10) + bcrypt.hash → stored in prsnpass
PATCH /users/:id with passwordNew plain-text passwordbcrypt.genSalt(10) + bcrypt.hash → updates prsnpass
POST /auth/change-passwordVerifies currentPassword with bcrypt.compare, then hashes newPassword
Any read responsepassword field is always deleted before the object is serialised
The login field maps to prsnlogn (varchar(30), unique constraint). Attempting to create or update a user with a login that already exists in the table will cause a 409 Conflict error.

Build docs developers (and LLMs) love