From 676978146b7f6f99f8a28c048914641794ded2f4 Mon Sep 17 00:00:00 2001 From: Adrian Flores Cortes Date: Mon, 2 Feb 2026 21:21:14 -0600 Subject: [PATCH] feat(frontend): Add HSE API services module Create API service layer for HSE (Health, Safety, Environment) module: - incidentes.api.ts: Incidents management with stats and investigation workflow - capacitaciones.api.ts: Training courses management - inspecciones.api.ts: Inspections with findings tracking - index.ts: Barrel exports All services follow the established pattern from fraccionamientos.api.ts: - TypeScript interfaces for entities, filters, and DTOs - Paginated responses support - Axios integration with automatic auth headers - Complete CRUD operations aligned with backend endpoints Co-Authored-By: Claude Opus 4.5 --- web/src/services/hse/capacitaciones.api.ts | 81 ++++++++++++++ web/src/services/hse/incidentes.api.ts | 115 ++++++++++++++++++++ web/src/services/hse/index.ts | 3 + web/src/services/hse/inspecciones.api.ts | 118 +++++++++++++++++++++ 4 files changed, 317 insertions(+) create mode 100644 web/src/services/hse/capacitaciones.api.ts create mode 100644 web/src/services/hse/incidentes.api.ts create mode 100644 web/src/services/hse/index.ts create mode 100644 web/src/services/hse/inspecciones.api.ts diff --git a/web/src/services/hse/capacitaciones.api.ts b/web/src/services/hse/capacitaciones.api.ts new file mode 100644 index 0000000..e180490 --- /dev/null +++ b/web/src/services/hse/capacitaciones.api.ts @@ -0,0 +1,81 @@ +import api, { PaginatedResponse, PaginationParams } from '../api'; + +export type TipoCapacitacion = 'induccion' | 'especifica' | 'certificacion' | 'reentrenamiento'; + +export interface Capacitacion { + id: string; + tenantId: string; + codigo: string; + nombre: string; + descripcion?: string; + tipo: TipoCapacitacion; + duracionHoras: number; + temario?: string; + objetivos?: string; + requisitos?: string; + activo: boolean; + createdAt: string; + updatedAt: string; +} + +export interface CapacitacionFilters extends PaginationParams { + tipo?: TipoCapacitacion; + activo?: boolean; +} + +export interface CreateCapacitacionDto { + codigo: string; + nombre: string; + descripcion?: string; + tipo: TipoCapacitacion; + duracionHoras: number; + temario?: string; + objetivos?: string; + requisitos?: string; + activo?: boolean; +} + +export interface UpdateCapacitacionDto { + codigo?: string; + nombre?: string; + descripcion?: string; + tipo?: TipoCapacitacion; + duracionHoras?: number; + temario?: string; + objetivos?: string; + requisitos?: string; + activo?: boolean; +} + +export const capacitacionesApi = { + list: async (filters?: CapacitacionFilters): Promise> => { + const response = await api.get>('/hse/capacitaciones', { + params: filters, + }); + return response.data; + }, + + get: async (id: string): Promise => { + const response = await api.get(`/hse/capacitaciones/${id}`); + return response.data; + }, + + create: async (data: CreateCapacitacionDto): Promise => { + const response = await api.post('/hse/capacitaciones', data); + return response.data; + }, + + update: async (id: string, data: UpdateCapacitacionDto): Promise => { + const response = await api.patch(`/hse/capacitaciones/${id}`, data); + return response.data; + }, + + toggleActive: async (id: string): Promise => { + const response = await api.post(`/hse/capacitaciones/${id}/toggle-active`); + return response.data; + }, + + delete: async (id: string): Promise => { + await api.delete(`/hse/capacitaciones/${id}`); + }, +}; diff --git a/web/src/services/hse/incidentes.api.ts b/web/src/services/hse/incidentes.api.ts new file mode 100644 index 0000000..27cdcd7 --- /dev/null +++ b/web/src/services/hse/incidentes.api.ts @@ -0,0 +1,115 @@ +import api, { PaginatedResponse, PaginationParams } from '../api'; + +export type TipoIncidente = 'accidente' | 'incidente' | 'casi_accidente'; +export type GravedadIncidente = 'leve' | 'moderado' | 'grave' | 'fatal'; +export type EstadoIncidente = 'abierto' | 'en_investigacion' | 'cerrado'; + +export interface Incidente { + id: string; + tenantId: string; + fraccionamientoId: string; + tipo: TipoIncidente; + gravedad: GravedadIncidente; + estado: EstadoIncidente; + fecha: string; + hora?: string; + ubicacion?: string; + descripcion: string; + causas?: string; + acciones?: string; + responsableId?: string; + investigadorId?: string; + fechaInvestigacion?: string; + fechaCierre?: string; + observaciones?: string; + createdAt: string; + updatedAt: string; +} + +export interface IncidenteFilters extends PaginationParams { + fraccionamientoId?: string; + tipo?: TipoIncidente; + gravedad?: GravedadIncidente; + estado?: EstadoIncidente; + dateFrom?: string; + dateTo?: string; +} + +export interface CreateIncidenteDto { + fraccionamientoId: string; + tipo: TipoIncidente; + gravedad: GravedadIncidente; + fecha: string; + hora?: string; + ubicacion?: string; + descripcion: string; + causas?: string; + acciones?: string; + responsableId?: string; + observaciones?: string; +} + +export interface UpdateIncidenteDto { + tipo?: TipoIncidente; + gravedad?: GravedadIncidente; + estado?: EstadoIncidente; + fecha?: string; + hora?: string; + ubicacion?: string; + descripcion?: string; + causas?: string; + acciones?: string; + responsableId?: string; + investigadorId?: string; + fechaInvestigacion?: string; + fechaCierre?: string; + observaciones?: string; +} + +export interface IncidenteStats { + total: number; + porTipo: Record; + porGravedad: Record; + porEstado: Record; + abiertos: number; + cerrados: number; +} + +export const incidentesApi = { + list: async (filters?: IncidenteFilters): Promise> => { + const response = await api.get>('/hse/incidentes', { + params: filters, + }); + return response.data; + }, + + getStats: async (): Promise => { + const response = await api.get('/hse/incidentes/stats'); + return response.data; + }, + + get: async (id: string): Promise => { + const response = await api.get(`/hse/incidentes/${id}`); + return response.data; + }, + + create: async (data: CreateIncidenteDto): Promise => { + const response = await api.post('/hse/incidentes', data); + return response.data; + }, + + update: async (id: string, data: UpdateIncidenteDto): Promise => { + const response = await api.patch(`/hse/incidentes/${id}`, data); + return response.data; + }, + + investigate: async (id: string, data: { investigadorId: string; fechaInvestigacion?: string }): Promise => { + const response = await api.post(`/hse/incidentes/${id}/investigate`, data); + return response.data; + }, + + close: async (id: string, data: { fechaCierre?: string; observaciones?: string }): Promise => { + const response = await api.post(`/hse/incidentes/${id}/close`, data); + return response.data; + }, +}; diff --git a/web/src/services/hse/index.ts b/web/src/services/hse/index.ts new file mode 100644 index 0000000..fe24b60 --- /dev/null +++ b/web/src/services/hse/index.ts @@ -0,0 +1,3 @@ +export * from './incidentes.api'; +export * from './capacitaciones.api'; +export * from './inspecciones.api'; diff --git a/web/src/services/hse/inspecciones.api.ts b/web/src/services/hse/inspecciones.api.ts new file mode 100644 index 0000000..dccec31 --- /dev/null +++ b/web/src/services/hse/inspecciones.api.ts @@ -0,0 +1,118 @@ +import api, { PaginatedResponse, PaginationParams } from '../api'; + +export type GravedadHallazgo = 'baja' | 'media' | 'alta' | 'critica'; + +export interface TipoInspeccion { + id: string; + tenantId: string; + codigo: string; + nombre: string; + descripcion?: string; + activo: boolean; + createdAt: string; + updatedAt: string; +} + +export interface Inspeccion { + id: string; + tenantId: string; + tipoInspeccionId: string; + fraccionamientoId: string; + fecha: string; + hora?: string; + responsableId: string; + estado: string; + observaciones?: string; + hallazgos?: Hallazgo[]; + createdAt: string; + updatedAt: string; +} + +export interface Hallazgo { + id: string; + inspeccionId: string; + item: string; + descripcion: string; + gravedad: GravedadHallazgo; + accionCorrectiva?: string; + responsableId?: string; + fechaCompromiso?: string; + fechaCierre?: string; + cerrado: boolean; + evidencia?: string; + createdAt: string; + updatedAt: string; +} + +export interface InspeccionFilters extends PaginationParams { + tipoInspeccionId?: string; + fraccionamientoId?: string; + estado?: string; + dateFrom?: string; + dateTo?: string; +} + +export interface CreateInspeccionDto { + tipoInspeccionId: string; + fraccionamientoId: string; + fecha: string; + hora?: string; + responsableId: string; + observaciones?: string; +} + +export interface CreateHallazgoDto { + item: string; + descripcion: string; + gravedad: GravedadHallazgo; + accionCorrectiva?: string; + responsableId?: string; + fechaCompromiso?: string; +} + +export interface InspeccionStats { + total: number; + porEstado: Record; + hallazgosPorGravedad: Record; + hallazgosAbiertos: number; + hallazgosCerrados: number; +} + +export const inspeccionesApi = { + listTipos: async (): Promise => { + const response = await api.get('/hse/inspecciones/tipos'); + return response.data; + }, + + list: async (filters?: InspeccionFilters): Promise> => { + const response = await api.get>('/hse/inspecciones', { + params: filters, + }); + return response.data; + }, + + getStats: async (): Promise => { + const response = await api.get('/hse/inspecciones/stats'); + return response.data; + }, + + get: async (id: string): Promise => { + const response = await api.get(`/hse/inspecciones/${id}`); + return response.data; + }, + + create: async (data: CreateInspeccionDto): Promise => { + const response = await api.post('/hse/inspecciones', data); + return response.data; + }, + + updateEstado: async (id: string, data: { estado: string; observaciones?: string }): Promise => { + const response = await api.patch(`/hse/inspecciones/${id}/estado`, data); + return response.data; + }, + + addHallazgo: async (id: string, data: CreateHallazgoDto): Promise => { + const response = await api.post(`/hse/inspecciones/${id}/hallazgos`, data); + return response.data; + }, +};