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 UZDI backend is built on NestJS’s module system: every domain is a self-contained module with its own controllers, services, DTOs, and TypeORM entity registrations. All modules are imported by AppModule (src/app.module.ts) and share a single PostgreSQL connection provided by TypeOrmModule.forRoot(). The global API prefix is /api/v1, set in main.ts. Eight domain modules cover the full application surface:

Module Map

auth

Endpoints: POST /api/v1/auth/login, POST /api/v1/auth/change-passwordHandles user authentication with bcrypt password comparison. On successful login, returns the serialized user object (including tppr_id and rol) that the frontend stores in localStorage. The change-password endpoint accepts userId, currentPassword, and newPassword, re-hashes with bcrypt, and updates seguridad.prsn.prsnpass.

users

Endpoints: GET /api/v1/users, POST /api/v1/users, PATCH /api/v1/users/:idCRUD operations for system users mapped to the seguridad.prsn entity. Exposes the user list for the Usuarios view in the frontend. New users are created with a bcrypt-hashed initial password. The module does not expose a DELETE endpoint — deactivation is handled via a status flag.

adolescente

Sub-resources: Adolescente, Expediente, MedidaSocioeducativa, Infraccion, GDO, Etnia, EstadoCivil, NacionalidadThe largest domain module. Manages the complete lifecycle of an adolescent under socio-educational measures. Adolescente stores the personal profile; Expediente is the operational case file linking an adolescent to a measure, infraction, and UZDI office. MedidaSocioeducativa, Infraccion, GDO, Etnia, EstadoCivil, and Nacionalidad are catalogue tables consumed as foreign keys.

contexto-familiar

Sub-resources: Representante, TipoParentesco, AdolescenteRepresentanteManages the family context of each adolescent. Representante stores guardian/contact details; TipoParentesco is a seeded kinship catalogue (Madre, Padre, Abuela/o, etc.); AdolescenteRepresentante is the join entity linking an adolescent to their representative with a kinship type and a boolean es_referente flag.

estructura-institucional

Sub-resources: UZDI, Provincia, CantonGeographical and institutional reference data. Provincia and Canton form a two-level hierarchy; Uzdi is the UZDI office record anchored to a canton. These entities are referenced as FKs throughout most other modules.

gestion-documental

Sub-resources: DocumentoExpediente, TipoDocumentoDocument management for case files. TipoDocumento is a seeded catalogue (Oficio judicial, Acta de comparecencia, Informe técnico, etc.); DocumentoExpediente attaches typed documents to an expedition with state tracking (pendiente, recibido, verificado, no aplica, rechazado).

seguridad

Sub-resources: Persona, Perfil, Permiso, Accion, Sesion, HistorialThe security module manages profiles (prfl), discrete system actions (accn), profile-action permission grants (prms), session records (sesn), and the audit trail (historial). Historial is populated by database triggers; the module exposes read endpoints for audit log queries.

talleres-actividades

Sub-resources: Taller, AsistenciaTallerWorkshop and activity management. Taller records a workshop event at a UZDI office with a facilitator (prsn), topic, schedule, and location. AsistenciaTaller logs per-participant attendance with a mutually exclusive constraint: each row references either an adolescent (adlc_id) or an adolescent–representative link (adre_id), never both.

Common Utilities

The src/common/ directory provides cross-cutting infrastructure shared by all domain modules.

SanitizationPipe

A custom NestJS pipe that strips leading/trailing whitespace from every string value in an incoming request body, removes <script> tags, and escapes remaining HTML angle brackets (<&lt;, >&gt;). It is registered globally in main.ts before the standard ValidationPipe:
// UZDI_BACK/src/main.ts (bootstrap)
// Capa de sanitización separada
app.useGlobalPipes(new SanitizationPipe());

// Capa de validación
app.useGlobalPipes(new ValidationPipe({
  whitelist: true,
  forbidNonWhitelisted: true,
  transform: true,
}));
SanitizationPipe traverses the DTO object recursively and sanitizes all string values before ValidationPipe runs. This prevents stored-XSS vectors at the API boundary.

RolesGuard

A NestJS CanActivate guard that reads @Roles() metadata from the route handler (or controller class) via Reflector.getAllAndOverride and compares the required Rol[] array against request.user.rol. If no @Roles() annotation is present the guard returns true (open endpoint). If the user object is missing or has no rol property, a 403 ForbiddenException is thrown.
// Usage on a controller
@Controller('adolescente')
@UseGuards(RolesGuard)
export class AdolescenteController {
  @Post()
  @Roles(Rol.ADMINISTRADOR, Rol.SUPERADMINISTRADOR)
  create(@Body() dto: CreateAdolescenteDto) { ... }

  @Get()
  @Roles(Rol.ADMINISTRADOR, Rol.SUPERADMINISTRADOR,
         Rol.TRABAJADOR_SOCIAL, Rol.PSICOLOGO, Rol.EDUCADOR, Rol.JURIDICO)
  findAll() { ... }
}
See Roles & Permissions for the full guard implementation and role reference.

MockAuthMiddleware

A NestJS middleware that inspects the incoming Authorization header and, when a Bearer token is present, injects a synthetic request.user object into the request. It is wired globally in AppModule:
// UZDI_BACK/src/app.module.ts
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(MockAuthMiddleware).forRoutes('*');
  }
}
This allows backend endpoints to be tested locally without a real JWT workflow — as long as the request carries an Authorization: Bearer <any-value> header. The mock user object includes a rol field set to one of the Rol enum string values.
To test different access levels locally, update the rol value inside MockAuthMiddleware and restart the dev server. Remember to disable or replace this middleware with a real JWT guard before deploying to a shared environment.

BooleanVfTransformer

A TypeORM value transformer used on CHAR(1) columns that store boolean-like data as 'V' (true) or 'F' (false). Applied via the transformer option in @Column():
// Example from adolescente.entity.ts
@Column({
  name: 'reincide',
  type: 'char',
  length: 1,
  default: 'F',
  transformer: BooleanVF,
})
reincide: boolean;
The transformer converts 'V'true and 'F'false on read, and true'V' / false'F' on write, so all API consumers work with standard TypeScript booleans while the database constraint CHECK (reincide IN ('V', 'F')) is always satisfied.

Frontend Services Mapping

The Vue 3 frontend communicates with the backend exclusively through typed service modules located in UZDI_FRONT/src/services/.

api.ts — Axios base instance

All service modules import a shared axios instance from api.ts:
// UZDI_FRONT/src/services/api.ts
import axios from 'axios'

const api = axios.create({
  baseURL: `${import.meta.env.VITE_API_BASE_URL}/api/v1`,
  headers: { 'Content-Type': 'application/json' },
})

// JWT interceptor: attaches Authorization header from localStorage
api.interceptors.request.use((config) => {
  const token = localStorage.getItem('uzdi_token')
  if (token) config.headers.Authorization = `Bearer ${token}`
  return config
})

// 401 interceptor: clears session and redirects to login
api.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response?.status === 401) {
      localStorage.removeItem('uzdi_token')
      localStorage.removeItem('uzdi_user')
      window.location.href = '/login'
    }
    return Promise.reject(error)
  }
)

export default api
The base URL is driven by the VITE_API_BASE_URL environment variable, enabling the same build artifact to point to different backend hosts across environments.

Service modules

Service fileBackend moduleEndpoints consumed
auth.service.tsauthPOST /auth/login
adolescente.service.tsadolescenteGET /adolescente, POST /adolescente, PATCH /adolescente/:id, DELETE /adolescente/:id
expediente.service.tsadolescenteGET /expediente, POST /expediente, PATCH /expediente/:id, DELETE /expediente/:id
medida.service.tsadolescenteGET /medida-socioeducativa, POST /medida-socioeducativa, PATCH /medida-socioeducativa/:id, DELETE /medida-socioeducativa/:id
usuario.service.tsusersGET /users, POST /users, PATCH /users/:id
uzdi.service.tsestructura-institucionalGET /uzdi/:id, PATCH /uzdi/:id
catalogo.service.tsadolescente, estructura-institucionalGET /nacionalidad, GET /estado-civil, GET /etnia, GET /gdo, GET /canton, GET /uzdi, GET /infraccion, GET /medida-socioeducativa — reference catalogue endpoints used by form dropdowns
catalogo.service.ts is consumed by the useCatalogos composable, which lazy-loads all eight reference catalogues once per session and caches them in reactive state. Form components (e.g., AdolescenteForm, MedidaForm) read from this composable rather than making individual API calls per form mount.

Build docs developers (and LLMs) love