Files
GRH/docs/API.md
Exteban08 da976b9003 Update all documentation for 3-level roles, organismos, and Histórico
Reflect current project state across all 8 docs: ADMIN/ORGANISMO_OPERADOR/OPERATOR
role hierarchy, scope filtering, organismos_operadores table, Histórico de Tomas
page, new SQL migrations, and updated API endpoints with auth requirements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:44:16 +00:00

653 lines
12 KiB
Markdown

# Documentacion API
## Informacion General
- **URL Base**: `https://api.gestionrecursoshidricos.com/api`
- **Formato**: JSON
- **Autenticacion**: Bearer Token (JWT)
## Autenticacion
### Login
```http
POST /auth/login
Content-Type: application/json
{
"email": "usuario@ejemplo.com",
"password": "contraseña"
}
```
**Respuesta exitosa:**
```json
{
"success": true,
"data": {
"user": {
"id": "uuid",
"email": "usuario@ejemplo.com",
"name": "Nombre",
"role": "ADMIN"
},
"accessToken": "jwt_token",
"refreshToken": "refresh_token"
}
}
```
### Refresh Token
```http
POST /auth/refresh
Content-Type: application/json
{
"refreshToken": "refresh_token"
}
```
### Logout
```http
POST /auth/logout
Authorization: Bearer {accessToken}
```
### Obtener Perfil
```http
GET /auth/me
Authorization: Bearer {accessToken}
```
---
## Proyectos
### Listar Proyectos
```http
GET /projects?page=1&pageSize=10
Authorization: Bearer {accessToken}
```
**Parametros de consulta:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| page | number | Numero de pagina (default: 1) |
| pageSize | number | Registros por pagina (default: 10) |
| status | string | Filtrar por estado (ACTIVE, INACTIVE) |
| search | string | Buscar por nombre |
### Obtener Proyecto
```http
GET /projects/:id
Authorization: Bearer {accessToken}
```
### Estadisticas del Proyecto
```http
GET /projects/:id/stats
Authorization: Bearer {accessToken}
```
### Crear Proyecto
```http
POST /projects
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"name": "Nombre del Proyecto",
"description": "Descripcion",
"area_name": "Nombre del Area",
"location": "Ubicacion",
"meter_type_id": "uuid-tipo-medidor"
}
```
### Actualizar Proyecto
```http
PUT /projects/:id
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"name": "Nuevo Nombre",
"status": "ACTIVE"
}
```
### Eliminar Proyecto
```http
DELETE /projects/:id
Authorization: Bearer {accessToken}
```
*Requiere rol ADMIN*
---
## Concentradores
### Listar Concentradores
```http
GET /concentrators?project_id=uuid
Authorization: Bearer {accessToken}
```
**Parametros de consulta:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| project_id | uuid | Filtrar por proyecto |
| status | string | Filtrar por estado |
| search | string | Buscar por serial o nombre |
### Obtener Concentrador
```http
GET /concentrators/:id
Authorization: Bearer {accessToken}
```
### Crear Concentrador
```http
POST /concentrators
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"serial_number": "CONC001",
"name": "Concentrador Principal",
"project_id": "uuid-proyecto",
"location": "Ubicacion",
"ip_address": "192.168.1.100"
}
```
### Actualizar Concentrador
```http
PUT /concentrators/:id
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"name": "Nuevo Nombre",
"status": "ACTIVE"
}
```
### Eliminar Concentrador
```http
DELETE /concentrators/:id
Authorization: Bearer {accessToken}
```
---
## Medidores
### Listar Medidores
```http
GET /meters?page=1&pageSize=50
Authorization: Bearer {accessToken}
```
*Resultados filtrados automaticamente por scope del usuario (ADMIN ve todos, ORGANISMO ve su organismo, OPERATOR ve su proyecto)*
**Parametros de consulta:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| page | number | Numero de pagina |
| pageSize | number | Registros por pagina |
| project_id | uuid | Filtrar por proyecto |
| concentrator_id | uuid | Filtrar por concentrador |
| status | string | ACTIVE, INACTIVE, OFFLINE, MAINTENANCE, ERROR |
| type | string | LORA, LORAWAN, GRANDES CONSUMIDORES |
| search | string | Buscar por serial o nombre |
### Obtener Medidor
```http
GET /meters/:id
Authorization: Bearer {accessToken}
```
### Lecturas del Medidor
```http
GET /meters/:id/readings?page=1&pageSize=50
Authorization: Bearer {accessToken}
```
*Resultados filtrados por scope del usuario*
**Parametros de consulta:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| page | number | Numero de pagina |
| pageSize | number | Registros por pagina (max 100) |
| start_date | date | Fecha inicio (YYYY-MM-DD) |
| end_date | date | Fecha fin (YYYY-MM-DD) |
**Respuesta:**
```json
{
"success": true,
"data": [
{
"id": "uuid",
"meter_id": "uuid",
"reading_value": 1234.56,
"reading_type": "AUTOMATIC",
"battery_level": 85,
"signal_strength": -45,
"received_at": "2024-01-20T10:30:00Z",
"meter_serial_number": "MED001",
"meter_name": "Medidor 001",
"project_id": "uuid",
"project_name": "ADAMANT"
}
],
"pagination": {
"page": 1,
"pageSize": 50,
"total": 150,
"totalPages": 3
}
}
```
### Crear Medidor
```http
POST /meters
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"serial_number": "MED001",
"name": "Medidor 001",
"concentrator_id": "uuid-concentrador",
"project_id": "uuid-proyecto",
"area_name": "Zona A",
"location": "Depto 101",
"type": "LORA",
"status": "ACTIVE",
"installation_date": "2024-01-15"
}
```
### Actualizar Medidor
```http
PUT /meters/:id
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"name": "Nuevo Nombre",
"status": "MAINTENANCE"
}
```
### Actualizar Parcial (PATCH)
```http
PATCH /meters/:id
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"status": "ACTIVE"
}
```
### Eliminar Medidor
```http
DELETE /meters/:id
Authorization: Bearer {accessToken}
```
*Requiere rol ADMIN*
---
## Lecturas
### Listar Lecturas
```http
GET /readings?page=1&pageSize=50
```
**Parametros de consulta:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| meter_id | uuid | Filtrar por medidor |
| project_id | uuid | Filtrar por proyecto |
| concentrator_id | uuid | Filtrar por concentrador |
| start_date | date | Fecha inicio (YYYY-MM-DD) |
| end_date | date | Fecha fin (YYYY-MM-DD) |
| reading_type | string | AUTOMATIC, MANUAL, SCHEDULED |
### Resumen de Consumo
```http
GET /readings/summary?project_id=uuid
```
**Respuesta:**
```json
{
"success": true,
"data": {
"totalReadings": 1500,
"totalMeters": 50,
"avgReading": 125.5,
"lastReadingDate": "2024-01-20T10:30:00Z"
}
}
```
### Crear Lectura
```http
POST /readings
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"meter_id": "uuid-medidor",
"reading_value": 1234.56,
"reading_type": "MANUAL",
"battery_level": 85,
"signal_strength": -45,
"received_at": "2024-01-20T10:30:00Z"
}
```
### Eliminar Lectura
```http
DELETE /readings/:id
Authorization: Bearer {accessToken}
```
*Requiere rol ADMIN*
---
## Carga CSV (Sin Autenticacion)
### Subir Medidores CSV
```http
POST /csv-upload/meters
Content-Type: multipart/form-data
file: archivo.csv
```
**Formato CSV:**
```csv
serial_number,name,concentrator_serial,area_name,location,meter_type,status,installation_date
MED001,Medidor 1,CONC001,Zona A,Depto 101,LORA,ACTIVE,2024-01-15
```
**Respuesta:**
```json
{
"success": true,
"message": "Procesamiento completado: 10 insertados, 5 actualizados, 2 errores",
"data": {
"total": 17,
"inserted": 10,
"updated": 5,
"errors": [
{
"row": 15,
"field": "concentrator_serial",
"message": "Concentrador no encontrado"
}
]
}
}
```
### Subir Lecturas CSV
```http
POST /csv-upload/readings
Content-Type: multipart/form-data
file: archivo.csv
```
**Formato CSV:**
```csv
meter_serial,reading_value,received_at,reading_type,battery_level,signal_strength
MED001,1234.56,2024-01-20 10:30:00,MANUAL,85,-45
```
### Descargar Plantilla Medidores
```http
GET /csv-upload/meters/template
```
### Descargar Plantilla Lecturas
```http
GET /csv-upload/readings/template
```
---
## Organismos Operadores
### Listar Organismos
```http
GET /organismos-operadores
Authorization: Bearer {accessToken}
```
*Requiere rol ADMIN*
### Obtener Organismo
```http
GET /organismos-operadores/:id
Authorization: Bearer {accessToken}
```
### Crear Organismo
```http
POST /organismos-operadores
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"name": "CESPT Tijuana",
"code": "CESPT-TJ",
"contact_name": "Juan Perez",
"contact_email": "juan@cespt.gob.mx",
"contact_phone": "664-123-4567",
"is_active": true
}
```
*Requiere rol ADMIN*
### Actualizar Organismo
```http
PUT /organismos-operadores/:id
Authorization: Bearer {accessToken}
Content-Type: application/json
```
### Eliminar Organismo
```http
DELETE /organismos-operadores/:id
Authorization: Bearer {accessToken}
```
*Requiere rol ADMIN*
---
## Usuarios
### Listar Usuarios
```http
GET /users
Authorization: Bearer {accessToken}
```
*Requiere rol ADMIN o ORGANISMO_OPERADOR. Resultados filtrados por scope.*
### Crear Usuario
```http
POST /users
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"email": "nuevo@ejemplo.com",
"password": "contraseña123",
"name": "Nombre Usuario",
"role_id": "uuid-rol",
"project_id": "uuid-proyecto",
"organismo_operador_id": "uuid-organismo"
}
```
*Requiere rol ADMIN o ORGANISMO_OPERADOR*
### Actualizar Usuario
```http
PUT /users/:id
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"name": "Nuevo Nombre",
"is_active": true
}
```
### Cambiar Contraseña
```http
PUT /users/:id/password
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"currentPassword": "actual",
"newPassword": "nueva123"
}
```
---
## Roles
### Listar Roles
```http
GET /roles
Authorization: Bearer {accessToken}
```
**Roles disponibles (jerarquia de 3 niveles):**
| Rol | Descripcion | Scope |
|-----|-------------|-------|
| ADMIN | Acceso completo al sistema | Ve todos los datos |
| ORGANISMO_OPERADOR | Gestiona proyectos de su organismo | Ve datos de proyectos de su organismo |
| OPERATOR | Opera medidores de su proyecto | Ve datos de su proyecto asignado |
---
## Notificaciones
### Listar Notificaciones
```http
GET /notifications?page=1&pageSize=20
Authorization: Bearer {accessToken}
```
### Contador No Leidas
```http
GET /notifications/unread-count
Authorization: Bearer {accessToken}
```
### Marcar como Leida
```http
PATCH /notifications/:id/read
Authorization: Bearer {accessToken}
```
### Marcar Todas como Leidas
```http
PATCH /notifications/read-all
Authorization: Bearer {accessToken}
```
---
## Auditoria
### Listar Logs de Auditoria
```http
GET /audit-logs?page=1&pageSize=50
Authorization: Bearer {accessToken}
```
*Requiere rol ADMIN*
**Parametros de consulta:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| user_id | uuid | Filtrar por usuario |
| action | string | CREATE, UPDATE, DELETE, LOGIN, etc. |
| table_name | string | Filtrar por tabla |
| start_date | date | Fecha inicio |
| end_date | date | Fecha fin |
### Mi Actividad
```http
GET /audit-logs/my-activity
Authorization: Bearer {accessToken}
```
---
## Webhooks TTS (The Things Stack)
### Health Check
```http
GET /webhooks/tts/health
```
### Uplink (Datos de Dispositivos)
```http
POST /webhooks/tts/uplink
X-Downlink-Apikey: {webhook_secret}
Content-Type: application/json
{
"end_device_ids": {
"device_id": "device-001",
"dev_eui": "0004A30B001C1234"
},
"uplink_message": {
"decoded_payload": {
"reading": 1234.56,
"battery": 85
}
}
}
```
### Join Accept
```http
POST /webhooks/tts/join
X-Downlink-Apikey: {webhook_secret}
```
---
## Codigos de Respuesta
| Codigo | Descripcion |
|--------|-------------|
| 200 | Exito |
| 201 | Creado exitosamente |
| 400 | Error en la solicitud |
| 401 | No autorizado |
| 403 | Prohibido (sin permisos) |
| 404 | No encontrado |
| 409 | Conflicto (duplicado) |
| 500 | Error interno del servidor |
## Formato de Error
```json
{
"success": false,
"message": "Descripcion del error",
"error": "CODIGO_ERROR"
}
```