diff --git a/CAMBIOS_SESION.md b/CAMBIOS_SESION.md index 2efbf19..0ee2e01 100644 --- a/CAMBIOS_SESION.md +++ b/CAMBIOS_SESION.md @@ -4,21 +4,80 @@ Registro cronologico de cambios significativos realizados al proyecto. --- -## 2026-02-09: Actualizacion de documentacion +## 2026-02-09: Organismos Operadores + Historico de Tomas + Documentacion ### Resumen -Actualizacion completa de los 4 archivos de documentacion para reflejar el estado real del proyecto. +Implementacion completa del sistema de 3 niveles de roles (ADMIN → ORGANISMO_OPERADOR → OPERATOR), nueva pagina Historico de Tomas, y actualizacion de toda la documentacion. -### Archivos Modificados +### Nuevas Funcionalidades + +**Rol ORGANISMO_OPERADOR (8 fases completas)** +- Nueva tabla `organismos_operadores` con migracion SQL +- JWT actualizado con campo `organismoOperadorId` +- Scope filtering en todos los servicios: meter, reading, project, user, concentrator, notification +- Utility `scope.ts` para centralizar logica de filtrado +- Pagina OrganismosPage.tsx para gestion de organismos (ADMIN only) +- UsersPage actualizada con campo organismo y filtrado por scope +- ProjectsPage con campo organismo_operador_id +- Sidebar con visibilidad de 3 niveles por rol + +**Historico de Tomas** +- Nueva pagina `HistoricoPage.tsx` con selector de medidor searchable +- Busqueda por nombre, serial, ubicacion, cuenta CESPT, clave catastral +- Tarjeta de informacion del medidor seleccionado +- Cards de consumo: Actual (diario), Pasado (1er dia mes anterior), Diferencial con tendencia +- Grafica AreaChart (Recharts) con gradiente y eje Y ajustado al rango de datos +- Tabla paginada de lecturas (10/20/50 por pagina) +- Filtros de rango de fechas +- Exportacion CSV +- authenticateToken en rutas GET de medidores para scope filtering + +**Documentacion** +- Actualizacion completa de 8 archivos de documentacion + +### Archivos Nuevos +| Archivo | Descripcion | +|---------|-------------| +| `src/pages/OrganismosPage.tsx` | Pagina CRUD de organismos operadores | +| `src/pages/historico/HistoricoPage.tsx` | Pagina de historico de tomas | +| `src/api/organismos.ts` | Cliente API para organismos operadores | +| `water-api/src/services/organismo-operador.service.ts` | Servicio backend organismos | +| `water-api/src/controllers/organismo-operador.controller.ts` | Controlador organismos | +| `water-api/src/routes/organismo-operador.routes.ts` | Rutas organismos | +| `water-api/src/utils/scope.ts` | Utility de filtrado por scope | +| `water-api/sql/add_organismos_operadores.sql` | Migracion SQL organismos | +| `water-api/sql/add_user_meter_fields.sql` | Migracion campos usuario/medidor | + +### Archivos Modificados (28+) | Archivo | Cambio | |---------|--------| -| `README.md` | Reescrito completamente: arquitectura full-stack, backend Express, PostgreSQL, todos los modulos, endpoints API, variables de entorno, estructura de directorios actualizada | -| `DOCUMENTATION.md` | Reescrito completamente: documentacion tecnica con JWT real, todos los endpoints del backend, esquema relacional, hooks, sistema de temas, conectores, guia de desarrollo actualizada | -| `ESTADO_ACTUAL.md` | Actualizado con todas las funcionalidades implementadas en febrero 2026: Analytics, Conectores, Dark mode, Notificaciones, Auditoria, Upload Panel, historial de correcciones | -| `CAMBIOS_SESION.md` | Convertido a historial cronologico completo de cambios | +| `src/App.tsx` | Agregados tipos "organismos" y "historico" al Page type | +| `src/components/layout/Sidebar.tsx` | Visibilidad de 3 niveles por rol | +| `src/api/auth.ts` | Helpers de rol actualizados (organismoOperadorId) | +| `src/api/meters.ts` | Interfaces MeterReadingFilters, PaginatedMeterReadings, fetchMeterReadings con paginacion | +| `src/api/users.ts` | Campo organismo_operador_id | +| `src/api/projects.ts` | Campo organismo_operador_id | +| `src/pages/Home.tsx` | Filtrado por scope | +| `src/pages/UsersPage.tsx` | Campo organismo y filtrado | +| `src/pages/projects/ProjectsPage.tsx` | Campo organismo | +| `src/pages/meters/MetersModal.tsx` | Campo project_id | +| `water-api/src/types/index.ts` | organismoOperadorId en tipos | +| `water-api/src/utils/jwt.ts` | organismoOperadorId en JWT payload | +| `water-api/src/middleware/auth.middleware.ts` | Extraccion de organismoOperadorId | +| `water-api/src/services/*.ts` | Scope filtering en todos los servicios | +| `water-api/src/controllers/*.ts` | requestingUser pass-through | +| `water-api/src/routes/*.ts` | authenticateToken en rutas GET | +| `water-api/src/validators/*.ts` | Campos de organismo | + +--- + +## 2026-02-09: Actualizacion de documentacion (anterior) + +### Resumen +Actualizacion de los 4 archivos de documentacion principales. ### Motivo -La documentacion previa describia una version temprana del proyecto (solo frontend, API externa NocoDB, auth con token simple) y no reflejaba el backend Express propio, JWT con refresh tokens, ni los modulos agregados en febrero 2026. +La documentacion previa describia una version temprana del proyecto y no reflejaba el backend Express propio ni los modulos agregados. --- diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index b9be16e..d3fe4a7 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -38,7 +38,7 @@ El proyecto es una aplicacion **full-stack** con tres componentes principales: │ Express Routes → Controllers → Services → PostgreSQL │ ├─────────────────────────────────────────────────────────────┤ │ Capa de Datos │ -│ PostgreSQL: 10 tablas, 2 vistas, triggers, indices │ +│ PostgreSQL: 11 tablas, 2 vistas, triggers, indices │ ├─────────────────────────────────────────────────────────────┤ │ Integraciones Externas │ │ The Things Stack (LoRaWAN), SH-Meters, XMeters │ @@ -67,7 +67,8 @@ export type Page = | "home" | "projects" | "meters" | "concentrators" | "consumption" | "auditoria" | "users" | "roles" | "sh-meters" | "xmeters" | "tts" - | "analytics-map" | "analytics-reports" | "analytics-server"; + | "analytics-map" | "analytics-reports" | "analytics-server" + | "organismos" | "historico"; ``` La navegacion es **state-based** (sin React Router). El estado `currentPage` determina que pagina se renderiza. @@ -91,6 +92,8 @@ La navegacion es **state-based** (sin React Router). El estado `currentPage` det | SH-Meters | `conectores/SHMetersPage.tsx` | Conector SH-Meters | | XMeters | `conectores/XMetersPage.tsx` | Conector XMeters | | TTS | `conectores/TTSPage.tsx` | Conector The Things Stack | +| Organismos | `OrganismosPage.tsx` | Gestion de organismos operadores (ADMIN) | +| Historico | `historico/HistoricoPage.tsx` | Historico de lecturas por medidor con grafica, estadisticas y tabla | ### Componentes de Layout @@ -98,7 +101,10 @@ La navegacion es **state-based** (sin React Router). El estado `currentPage` det - Menu lateral colapsable con hover expansion - Soporte para pin/unpin - Menu jerarquico con submenus (Analytics, Conectores) -- Indicadores visuales de pagina activa +- Visibilidad por rol de 3 niveles: + - ADMIN: ve todo (incluye Organismos, Conectores, Auditoria) + - ORGANISMO_OPERADOR: ve Dashboard, Project Management, Users, Analytics + - OPERATOR: ve Dashboard y Project Management **TopMenu.tsx** - Breadcrumb de navegacion @@ -125,18 +131,22 @@ water-api/src/ ├── config/ │ ├── index.ts # Variables de entorno centralizadas │ └── database.ts # Pool de conexiones pg -├── routes/ # Definicion de rutas (17 archivos) +├── routes/ # Definicion de rutas (18 archivos) +│ └── organismo-operador.routes.ts # Rutas CRUD organismos ├── controllers/ # Controladores HTTP -├── services/ # Logica de negocio (18 modulos) +│ └── organismo-operador.controller.ts +├── services/ # Logica de negocio (19 modulos) +│ └── organismo-operador.service.ts ├── middleware/ -│ ├── auth.middleware.ts # Verificacion JWT + extraccion de rol +│ ├── auth.middleware.ts # Verificacion JWT + extraccion de rol + requireRole │ ├── audit.middleware.ts # Auto-logging de acciones │ └── ttsWebhook.middleware.ts # Verificacion de secreto webhook ├── validators/ # Schemas de validacion Zod ├── utils/ -│ ├── jwt.ts # sign/verify de tokens +│ ├── jwt.ts # sign/verify de tokens (incluye organismoOperadorId) │ ├── password.ts # hash/compare con bcrypt -│ └── logger.ts # Winston con formato timestamp +│ ├── logger.ts # Winston con formato timestamp +│ └── scope.ts # Filtrado por scope de rol (ADMIN/ORGANISMO/OPERATOR) ├── jobs/ │ └── negativeFlowDetection.ts # Cron de deteccion de flujo negativo └── types/ # Interfaces TypeScript @@ -202,12 +212,21 @@ water-api/src/ | PUT | `/:id` | Actualizar dispositivo | Si (ADMIN/OPERATOR) | | DELETE | `/:id` | Eliminar dispositivo | Si (ADMIN) | -#### Usuarios (`/api/users`) - Solo ADMIN +#### Organismos Operadores (`/api/organismos-operadores`) - Solo ADMIN | Metodo | Ruta | Descripcion | Auth | |--------|------|-------------|------| -| GET | `/` | Listar usuarios | Si (ADMIN) | +| GET | `/` | Listar organismos operadores | Si (ADMIN) | +| GET | `/:id` | Obtener organismo operador | Si (ADMIN) | +| POST | `/` | Crear organismo operador | Si (ADMIN) | +| PUT | `/:id` | Actualizar organismo operador | Si (ADMIN) | +| DELETE | `/:id` | Eliminar organismo operador | Si (ADMIN) | + +#### Usuarios (`/api/users`) - ADMIN y ORGANISMO_OPERADOR +| Metodo | Ruta | Descripcion | Auth | +|--------|------|-------------|------| +| GET | `/` | Listar usuarios (filtrado por scope) | Si (ADMIN/ORGANISMO_OPERADOR) | | GET | `/:id` | Obtener usuario | Si (ADMIN o self) | -| POST | `/` | Crear usuario | Si (ADMIN) | +| POST | `/` | Crear usuario | Si (ADMIN/ORGANISMO_OPERADOR) | | PUT | `/:id` | Actualizar usuario | Si (ADMIN o self) | | DELETE | `/:id` | Desactivar usuario | Si (ADMIN) | | PUT | `/:id/password` | Cambiar contrasena | Si (self) | @@ -309,7 +328,7 @@ roles ←─── users ←─── refresh_tokens ``` ### ENUMs de PostgreSQL -- `role_name`: ADMIN, OPERATOR, VIEWER +- `role_name`: ADMIN, ORGANISMO_OPERADOR, OPERATOR - `project_status`: ACTIVE, INACTIVE, COMPLETED - `device_status`: ACTIVE, INACTIVE, OFFLINE, MAINTENANCE, ERROR - `meter_type`: WATER, GAS, ELECTRIC @@ -319,13 +338,15 @@ roles ←─── users ←─── refresh_tokens Ejecutar en orden despues del schema principal: -1. `schema.sql` - Schema principal con 10 tablas, 2 vistas, seed de roles y admin +1. `schema.sql` - Schema principal con tablas base, 2 vistas, seed de roles y admin 2. `add_audit_logs.sql` - Tabla de logs de auditoria 3. `add_notifications.sql` - Tabla de notificaciones 4. `add_meter_extended_fields.sql` - Campos extendidos para medidores 5. `create_meter_types.sql` - Tabla de tipos de medidor 6. `add_meter_project_relation.sql` - Relacion meter-proyecto 7. `add_user_project_relation.sql` - Relacion user-proyecto +8. `add_organismos_operadores.sql` - Tabla organismos_operadores, FK en projects y users, rol ORGANISMO_OPERADOR +9. `add_user_meter_fields.sql` - Campos adicionales en users y meters (cespt_account, cadastral_key) --- @@ -355,7 +376,7 @@ Ejecutar en orden despues del schema principal: ``` ### Tokens -- **Access Token** - JWT con userId, roleId, roleName, projectId. Expira en 15 minutos. +- **Access Token** - JWT con userId, roleId, roleName, projectId, organismoOperadorId. Expira en 15 minutos. - **Refresh Token** - JWT almacenado hasheado en BD. Expira en 7 dias. Revocable. ### Token Refresh Automatico (Frontend) @@ -374,25 +395,42 @@ water_project_settings_v1 → {theme, compactMode} mock_avatar → Avatar en base64 ``` -### Control de Acceso por Rol +### Control de Acceso por Rol (Jerarquia de 3 niveles) -| Recurso | ADMIN | OPERATOR | VIEWER | -|---------|-------|----------|--------| -| Usuarios | CRUD completo | Solo lectura | Sin acceso | -| Proyectos | CRUD completo | Crear/Leer/Actualizar | Solo lectura | -| Dispositivos | CRUD completo | Crear/Leer/Actualizar | Solo lectura | -| Medidores | CRUD completo | Crear/Leer/Actualizar | Solo lectura | -| Lecturas | CRUD + eliminar | Crear/Leer | Solo lectura | -| Configuracion | Completa | Solo lectura | Sin acceso | -| Reportes | Crear/Leer/Exportar | Crear/Leer/Exportar | Solo lectura | +| Recurso | ADMIN | ORGANISMO_OPERADOR | OPERATOR | +|---------|-------|-------------------|----------| +| Organismos | CRUD completo | Sin acceso | Sin acceso | +| Usuarios | CRUD completo | CRUD (su organismo) | Sin acceso | +| Proyectos | CRUD completo | Leer (su organismo) | Leer (su proyecto) | +| Medidores | CRUD completo | Leer (su organismo) | Leer (su proyecto) | +| Lecturas | CRUD + eliminar | Leer (su organismo) | Leer (su proyecto) | +| Historico | Todos los medidores | Medidores de su organismo | Medidores de su proyecto | +| Analytics | Completo | Completo | Sin acceso | +| Conectores | Completo | Sin acceso | Sin acceso | +| Auditoria | Completa | Sin acceso | Sin acceso | + +### Scope Filtering (Backend) + +Todos los servicios aplican filtrado automatico basado en el rol del usuario: + +``` +ADMIN → Sin filtro (ve todos los datos) +ORGANISMO_OP. → project_id IN (SELECT id FROM projects WHERE organismo_operador_id = $N) +OPERATOR → project_id = $N (solo su proyecto asignado) +``` + +El utility `water-api/src/utils/scope.ts` centraliza esta logica. ### Helpers del Frontend ```typescript -getCurrentUserRole() // → "ADMIN" | "OPERATOR" | "VIEWER" -getCurrentUserId() // → UUID string -getCurrentUserProjectId() // → UUID string | undefined -isCurrentUserAdmin() // → boolean +getCurrentUserRole() // → "ADMIN" | "ORGANISMO_OPERADOR" | "OPERATOR" +getCurrentUserId() // → UUID string +getCurrentUserProjectId() // → UUID string | undefined +getCurrentUserOrganismoId() // → UUID string | undefined +isCurrentUserAdmin() // → boolean +isCurrentUserOrganismo() // → boolean +isCurrentUserOperator() // → boolean ``` --- @@ -412,14 +450,15 @@ Wrapper de `fetch` con: | Archivo | Descripcion | |---------|-------------| -| `auth.ts` | Login, logout, refresh, getMe, helpers de roles | +| `auth.ts` | Login, logout, refresh, getMe, helpers de roles (3 niveles) | | `client.ts` | Cliente HTTP base con JWT | -| `meters.ts` | CRUD medidores + lecturas | +| `meters.ts` | CRUD medidores + lecturas historicas paginadas | | `readings.ts` | Lecturas y resumen de consumo | | `projects.ts` | CRUD proyectos + nombres | | `concentrators.ts` | CRUD concentradores | | `users.ts` | CRUD usuarios | | `roles.ts` | CRUD roles | +| `organismos.ts` | CRUD organismos operadores | | `analytics.ts` | Metricas, ubicaciones, reportes | | `notifications.ts` | Notificaciones del usuario | | `audit.ts` | Logs de auditoria | diff --git a/ESTADO_ACTUAL.md b/ESTADO_ACTUAL.md index 9ae0de5..fd7fb5d 100644 --- a/ESTADO_ACTUAL.md +++ b/ESTADO_ACTUAL.md @@ -15,8 +15,8 @@ Sistema full-stack de gestion de medidores de agua con: ### Jerarquia de datos: ``` -Projects → Concentrators → Meters → Readings - → Gateways → Devices ↗ +Organismos Operadores → Projects → Concentrators → Meters → Readings + → Gateways → Devices ↗ ``` ### URLs de produccion: @@ -61,11 +61,11 @@ Projects → Concentrators → Meters → Readings ┌─────────────────────────────────────────────────────────────┐ │ PostgreSQL │ ├─────────────────────────────────────────────────────────────┤ -│ 10 tablas: roles, users, projects, concentrators, │ -│ gateways, devices, meters, meter_readings, │ +│ 11 tablas: roles, users, organismos_operadores, projects, │ +│ concentrators, gateways, devices, meters, meter_readings, │ │ tts_uplink_logs, refresh_tokens │ │ 2 vistas: meter_stats_by_project, device_status_summary │ -│ 7 archivos SQL (schema + 6 migraciones) │ +│ 9 archivos SQL (schema + 8 migraciones) │ │ Triggers de updated_at, indices compuestos, JSONB │ └─────────────────────────────────────────────────────────────┘ ``` @@ -77,18 +77,20 @@ Projects → Concentrators → Meters → Readings ### 1. Autenticacion y Autorizacion - Login con JWT: access token (15 min) + refresh token (7 dias) - Refresh automatico de tokens en el cliente (cola de peticiones) -- 3 roles con permisos JSONB: ADMIN, OPERATOR, VIEWER -- Relacion usuario-proyecto para acceso por scope +- **Jerarquia de 3 niveles:** ADMIN → ORGANISMO_OPERADOR → OPERATOR +- Scope filtering en todos los servicios backend (via `scope.ts`) +- JWT incluye: userId, roleId, roleName, projectId, organismoOperadorId - Hash de contrasenas con bcrypt (12 rounds) - Proteccion de rutas por rol en backend y frontend +- authenticateToken requerido en todas las rutas GET de medidores ### 2. Dashboard (Home) - KPIs: Total medidores, medidores activos, consumo promedio, alertas - Grafico de barras: Medidores por proyecto (Recharts) -- Selector de organismos operadores (CESPT Tijuana, Tecate, Mexicali) +- Selector de organismos operadores (filtrado por rol) - Historial reciente de actividades - Panel de ultimas alertas -- Soporte por rol (ADMIN, OPERATOR, VIEWER) +- Soporte por rol (ADMIN, ORGANISMO_OPERADOR, OPERATOR) ### 3. Gestion de Proyectos - CRUD completo @@ -133,40 +135,58 @@ Projects → Concentrators → Meters → Readings - Sincronizacion programada a las 9:00 AM - Seguimiento de ultima conexion y estado -### 9. Gestion de Usuarios +### 9. Gestion de Organismos Operadores (NUEVO) - CRUD completo (solo ADMIN) -- Asignacion de roles -- Asignacion de proyecto +- Tabla: organismos_operadores (nombre, codigo, contacto, telefono, estado) +- Vinculacion con proyectos (projects.organismo_operador_id) +- Vinculacion con usuarios (users.organismo_operador_id) +- Pagina frontend: OrganismosPage.tsx + +### 10. Gestion de Usuarios +- CRUD completo (ADMIN y ORGANISMO_OPERADOR) +- Asignacion de roles, proyecto y organismo operador +- Filtrado por scope: ADMIN ve todos, ORGANISMO ve los de su organismo - Estados: activo/inactivo - Cambio de contrasena -### 10. Gestion de Roles -- 3 roles predefinidos: ADMIN, OPERATOR, VIEWER +### 11. Gestion de Roles +- 3 roles predefinidos: ADMIN, ORGANISMO_OPERADOR, OPERATOR - Permisos granulares JSONB por recurso - CRUD de roles (solo ADMIN) - Conteo de usuarios por rol -### 11. Auditoria +### 12. Historico de Tomas (NUEVO) +- Pagina dedicada para consultar historial de lecturas por medidor +- Selector de medidor con busqueda por nombre, serial, ubicacion, cuenta CESPT y clave catastral +- Tarjeta de informacion del medidor seleccionado +- Cards de consumo: Consumo Actual (diario), Consumo Pasado (primer dia del mes anterior), Diferencial +- Grafica AreaChart (Recharts) con gradiente, eje Y ajustado al rango de datos +- Tabla paginada de lecturas (10/20/50 por pagina) +- Filtros de rango de fechas +- Exportacion CSV +- Filtrado por scope: cada rol solo ve los medidores asignados + +### 13. Auditoria - Registro automatico de todas las acciones via middleware - Visor de logs con filtros (solo ADMIN) - Actividad del usuario actual (todos los roles) - Estadisticas de auditoria - Busqueda por registro especifico -### 12. Notificaciones +### 14. Notificaciones - Notificaciones in-app - Conteo de no leidas en tiempo real - Marcar como leida (individual y masiva) - Generacion automatica por flujo negativo (cron job) - Dropdown en TopMenu -### 13. Dark Mode +### 15. Dark Mode - Soporte completo: Dark / Light / System - Paleta Zinc de Tailwind - Aplicado a todas las paginas, modales, tablas, formularios - Persistencia en localStorage -### 14. Upload Panel +### 16. Upload Panel - Aplicacion separada (`upload-panel/`) para carga CSV - Dropzone para archivos - Carga de medidores (upsert) @@ -251,6 +271,21 @@ Columnas opcionales: - Mejoras en tiempo de ultima conexion de conectores - Plan de implementacion para rol ORGANISMOS_OPERADORES +### 2026-02-09: Organismos Operadores + Historico de Tomas +- Implementacion completa del rol ORGANISMO_OPERADOR (jerarquia de 3 niveles) +- Nueva tabla `organismos_operadores` con migracion SQL +- Scope filtering en todos los servicios backend (meter, reading, project, user, concentrator, notification) +- JWT actualizado con `organismoOperadorId` +- Pagina OrganismosPage.tsx para gestion de organismos (ADMIN) +- Pagina HistoricoPage.tsx para consulta de historial de lecturas por medidor +- Cards de consumo: Actual, Pasado, Diferencial +- Grafica AreaChart con gradiente y eje Y ajustado +- Busqueda por cuenta CESPT y clave catastral +- authenticateToken en rutas GET de medidores +- Sidebar con visibilidad de 3 niveles +- UsersPage actualizada con asignacion de organismo +- ProjectsPage con campo organismo_operador_id + ### 2026-02-05: Sincronizacion de conectores - Cambio de hora de sincronizacion de 2:00 AM a 9:00 AM @@ -287,8 +322,8 @@ psql -d water_project -f water-api/sql/schema.sql ## Proximos Pasos Sugeridos -1. **Rol ORGANISMOS_OPERADORES** - Implementar nuevo rol segun plan existente -2. **Reportes PDF** - Generacion y descarga de reportes en PDF -3. **Tests** - Suite de tests con Vitest (frontend) y Supertest (backend) -4. **CI/CD** - Pipeline de integracion continua -5. **Docker** - Containerizacion del proyecto completo +1. **Reportes PDF** - Generacion y descarga de reportes en PDF +2. **Tests** - Suite de tests con Vitest (frontend) y Supertest (backend) +3. **CI/CD** - Pipeline de integracion continua +4. **Docker** - Containerizacion del proyecto completo +5. **Alertas avanzadas** - Configuracion de umbrales y notificaciones por email diff --git a/README.md b/README.md index 45977c1..d74b063 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,10 @@ El **Sistema GRH** es una aplicacion web completa para organismos operadores de - **Consumo y Lecturas** - Seguimiento historico de lecturas con filtros y exportacion - **Analytics** - Mapa de medidores, reportes y metricas del servidor - **Conectores** - Integracion con SH-Meters, XMeters y The Things Stack -- **Usuarios y Roles** - Control de acceso basado en roles (ADMIN, OPERATOR, VIEWER) -- **Auditoria** - Registro completo de actividad del sistema +- **Organismos Operadores** - Gestion de organismos operadores de agua (ADMIN) +- **Historico de Tomas** - Consulta de historial de lecturas por medidor con grafica y estadisticas +- **Usuarios y Roles** - Control de acceso basado en roles con jerarquia de 3 niveles +- **Auditoria** - Registro completo de actividad del sistema (ADMIN) - **Notificaciones** - Alertas en tiempo real (flujo negativo, etc.) - **Tema claro/oscuro** - Personalizacion de la interfaz - **Diseno responsive** - Compatible con desktop, tablet y movil @@ -42,7 +44,7 @@ El **Sistema GRH** es una aplicacion web completa para organismos operadores de ▼ ┌─────────────────────────────────────────────────────────────┐ │ PostgreSQL │ -│ 10 tablas + 2 vistas + triggers + indices │ +│ 11 tablas + 2 vistas + triggers + indices │ └─────────────────────────────────────────────────────────────┘ ``` @@ -113,6 +115,8 @@ psql -d water_project -f water-api/sql/add_meter_extended_fields.sql psql -d water_project -f water-api/sql/create_meter_types.sql psql -d water_project -f water-api/sql/add_meter_project_relation.sql psql -d water_project -f water-api/sql/add_user_project_relation.sql +psql -d water_project -f water-api/sql/add_organismos_operadores.sql +psql -d water_project -f water-api/sql/add_user_meter_fields.sql ``` ### 3. Configurar el backend @@ -211,12 +215,13 @@ GRH/ │ ├── api/ # Cliente API (14 modulos) │ │ ├── client.ts # Cliente HTTP con JWT y refresh automatico │ │ ├── auth.ts # Autenticacion y gestion de tokens -│ │ ├── meters.ts # CRUD de medidores +│ │ ├── meters.ts # CRUD de medidores + lecturas historicas │ │ ├── readings.ts # Lecturas de consumo │ │ ├── projects.ts # Proyectos │ │ ├── concentrators.ts # Concentradores │ │ ├── users.ts # Usuarios │ │ ├── roles.ts # Roles +│ │ ├── organismos.ts # CRUD organismos operadores │ │ ├── analytics.ts # Analytics y metricas │ │ ├── notifications.ts # Notificaciones │ │ ├── audit.ts # Auditoria @@ -242,6 +247,7 @@ GRH/ │ │ ├── UsersPage.tsx # Gestion de usuarios │ │ ├── RolesPage.tsx # Gestion de roles │ │ ├── AuditoriaPage.tsx # Visor de logs de auditoria +│ │ ├── OrganismosPage.tsx # Gestion de organismos operadores │ │ ├── projects/ │ │ │ └── ProjectsPage.tsx │ │ ├── meters/ # Modulo de medidores @@ -260,6 +266,8 @@ GRH/ │ │ ├── consumption/ # Modulo de consumo │ │ │ ├── ConsumptionPage.tsx │ │ │ └── ReadingsBulkUploadModal.tsx +│ │ ├── historico/ # Modulo de historico de tomas +│ │ │ └── HistoricoPage.tsx │ │ ├── analytics/ # Modulo de analytics │ │ │ ├── AnalyticsMapPage.tsx │ │ │ ├── AnalyticsReportsPage.tsx @@ -293,19 +301,22 @@ GRH/ │ │ ├── utils/ │ │ │ ├── jwt.ts # Generacion/verificacion de tokens │ │ │ ├── password.ts # Wrappers de bcrypt -│ │ │ └── logger.ts # Configuracion Winston +│ │ │ ├── logger.ts # Configuracion Winston +│ │ │ └── scope.ts # Filtrado por scope de rol │ │ ├── jobs/ │ │ │ └── negativeFlowDetection.ts # Tarea programada │ │ └── types/ # Interfaces TypeScript │ │ │ ├── sql/ # Schema y migraciones -│ │ ├── schema.sql # Schema principal (10 tablas + 2 vistas) +│ │ ├── schema.sql # Schema principal + migraciones (11 tablas + 2 vistas) │ │ ├── add_audit_logs.sql │ │ ├── add_notifications.sql │ │ ├── add_meter_extended_fields.sql │ │ ├── create_meter_types.sql │ │ ├── add_meter_project_relation.sql -│ │ └── add_user_project_relation.sql +│ │ ├── add_user_project_relation.sql +│ │ ├── add_organismos_operadores.sql +│ │ └── add_user_meter_fields.sql │ │ │ ├── package.json │ ├── tsconfig.json @@ -346,9 +357,10 @@ Projects → Concentrators → Meters → Readings | Tabla | Descripcion | |-------|-------------| -| `roles` | Roles del sistema (ADMIN, OPERATOR, VIEWER) con permisos JSONB | -| `users` | Usuarios con email, password hash, rol y estado | -| `projects` | Proyectos de infraestructura hidrica | +| `roles` | Roles del sistema (ADMIN, ORGANISMO_OPERADOR, OPERATOR) con permisos JSONB | +| `users` | Usuarios con email, password hash, rol, proyecto y organismo | +| `organismos_operadores` | Organismos operadores de agua (CESPT Tijuana, Tecate, etc.) | +| `projects` | Proyectos de infraestructura hidrica (vinculados a organismo) | | `concentrators` | Concentradores de datos vinculados a proyectos | | `gateways` | Gateways LoRaWAN con integracion TTS | | `devices` | Dispositivos LoRaWAN (sensores/transmisores) | @@ -370,8 +382,9 @@ Todos los endpoints estan bajo el prefijo `/api/`. La mayoria requieren autentic | Grupo | Prefijo | Descripcion | |-------|---------|-------------| | Auth | `/api/auth` | Login, refresh, logout, perfil | +| Organismos | `/api/organismos-operadores` | CRUD de organismos operadores (ADMIN) | | Projects | `/api/projects` | CRUD de proyectos + estadisticas | -| Meters | `/api/meters` | CRUD de medidores + lecturas | +| Meters | `/api/meters` | CRUD de medidores + lecturas historicas | | Meter Types | `/api/meter-types` | Tipos de medidor | | Concentrators | `/api/concentrators` | CRUD de concentradores | | Gateways | `/api/gateways` | CRUD de gateways + dispositivos | @@ -400,12 +413,12 @@ El sistema usa **JWT con refresh tokens**: 4. El cliente HTTP envia el access token en `Authorization: Bearer ` 5. Al expirar, el cliente automaticamente llama a `POST /api/auth/refresh` -### Roles y permisos -| Rol | Descripcion | -|-----|-------------| -| `ADMIN` | Acceso completo al sistema | -| `OPERATOR` | Gestiona proyectos, dispositivos, medidores (sin configuracion del sistema) | -| `VIEWER` | Solo lectura de datos y reportes | +### Roles y permisos (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 | --- diff --git a/docs/API.md b/docs/API.md index fe21e5a..8f3930d 100644 --- a/docs/API.md +++ b/docs/API.md @@ -187,6 +187,7 @@ Authorization: Bearer {accessToken} 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 | @@ -202,11 +203,50 @@ Authorization: Bearer {accessToken} ### 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 @@ -382,6 +422,54 @@ 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 @@ -389,7 +477,7 @@ GET /csv-upload/readings/template GET /users Authorization: Bearer {accessToken} ``` -*Requiere rol ADMIN* +*Requiere rol ADMIN o ORGANISMO_OPERADOR. Resultados filtrados por scope.* ### Crear Usuario ```http @@ -402,10 +490,11 @@ Content-Type: application/json "password": "contraseña123", "name": "Nombre Usuario", "role_id": "uuid-rol", - "project_id": "uuid-proyecto" + "project_id": "uuid-proyecto", + "organismo_operador_id": "uuid-organismo" } ``` -*Requiere rol ADMIN* +*Requiere rol ADMIN o ORGANISMO_OPERADOR* ### Actualizar Usuario ```http @@ -441,12 +530,12 @@ GET /roles Authorization: Bearer {accessToken} ``` -**Roles disponibles:** -| Rol | Descripcion | -|-----|-------------| -| ADMIN | Acceso completo al sistema | -| OPERATOR | Gestion de medidores y lecturas de su proyecto | -| VIEWER | Solo lectura | +**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 | --- diff --git a/docs/ARQUITECTURA.md b/docs/ARQUITECTURA.md index 5f93631..72ee504 100644 --- a/docs/ARQUITECTURA.md +++ b/docs/ARQUITECTURA.md @@ -54,6 +54,7 @@ │ │ │ - meters │ │ - meter │ │ - meter │ │ │ │ │ │ - readings │ │ - reading │ │ - reading │ │ │ │ │ │ - users │ │ - user │ │ - user │ │ │ +│ │ │ - organismos│ │ - organismo │ │ - organismo │ │ │ │ │ │ - csv-upload│ │ - etc... │ │ - csv-upload│ │ │ │ │ │ - webhooks │ │ │ │ - tts │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ @@ -83,6 +84,7 @@ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ users │ │ projects │ │concentrators│ │ │ │ │ │ roles │ │ gateways │ │ meters │ │ │ +│ │ │ organismos │ │ │ │ │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ @@ -125,11 +127,24 @@ │ id (PK) │──┐ │ id (PK) │ ┌──│ id (PK) │ │ name │ └───▶│ role_id (FK) │ │ │ name │ │ description │ │ project_id (FK) │◀───┤ │ description │ -│ permissions │ │ email │ │ │ area_name │ -└─────────────┘ │ password_hash │ │ │ status │ - │ name │ │ │ created_by (FK) │──▶ users - │ is_active │ │ │ meter_type_id │──▶ meter_types - └─────────────────┘ │ └─────────────────┘ +│ permissions │ │ organismo_op_id │──┐ │ │ area_name │ +└─────────────┘ │ email │ │ │ │ status │ + │ password_hash │ │ │ │ organismo_op_id │──┐ + │ name │ │ │ │ created_by (FK) │──▶ users + │ is_active │ │ │ │ meter_type_id │──▶ meter_types + └─────────────────┘ │ │ └─────────────────┘ │ + │ │ │ + ┌─────────────────┐ │ │ │ + │ organismos_ │◀─┘─┼───────────────────────┘ + │ operadores │ │ + ├─────────────────┤ │ + │ id (PK) │ │ + │ name │ │ + │ code │ │ + │ contact_name │ │ + │ contact_email │ │ + │ is_active │ │ + └─────────────────┘ │ │ │ │ │ ┌─────────────────┐ │ │ @@ -183,6 +198,36 @@ └─────────────────┘ +## Scope Filtering (Control de Acceso por Datos) + +Todos los servicios del backend aplican filtrado automatico basado en el rol del usuario autenticado: + +``` +┌──────────────────────────────────────────────────────────┐ +│ Scope Filtering │ +├──────────────────────────────────────────────────────────┤ +│ │ +│ ADMIN (roleName = 'ADMIN') │ +│ └── Sin filtro, ve TODOS los registros │ +│ │ +│ ORGANISMO_OPERADOR (organismoOperadorId = X) │ +│ └── WHERE project_id IN ( │ +│ SELECT id FROM projects │ +│ WHERE organismo_operador_id = X │ +│ ) │ +│ │ +│ OPERATOR (projectId = Y) │ +│ └── WHERE project_id = Y │ +│ │ +├──────────────────────────────────────────────────────────┤ +│ Utility: water-api/src/utils/scope.ts │ +│ Se aplica en: meter, reading, project, user, │ +│ concentrator, notification services │ +└──────────────────────────────────────────────────────────┘ +``` + +--- + ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ audit_logs │ │ notifications │ │ meter_types │ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤ @@ -206,7 +251,7 @@ | Campo | Tipo | Descripcion | |-------|------|-------------| | id | UUID | Identificador unico | -| name | ENUM | ADMIN, OPERATOR, VIEWER | +| name | ENUM | ADMIN, ORGANISMO_OPERADOR, OPERATOR | | description | TEXT | Descripcion del rol | | permissions | JSONB | Permisos detallados | @@ -219,9 +264,23 @@ | name | VARCHAR | Nombre completo | | role_id | UUID FK | Rol asignado | | project_id | UUID FK | Proyecto asignado (OPERATOR) | +| organismo_operador_id | UUID FK | Organismo asignado (ORGANISMO_OPERADOR) | | is_active | BOOLEAN | Estado de la cuenta | | last_login | TIMESTAMP | Ultimo acceso | +#### `organismos_operadores` +| Campo | Tipo | Descripcion | +|-------|------|-------------| +| id | UUID | Identificador unico | +| name | VARCHAR | Nombre del organismo | +| code | VARCHAR | Codigo unico (ej: CESPT-TJ) | +| contact_name | VARCHAR | Nombre del contacto | +| contact_email | VARCHAR | Email de contacto | +| contact_phone | VARCHAR | Telefono de contacto | +| is_active | BOOLEAN | Estado activo | +| created_at | TIMESTAMP | Fecha de creacion | +| updated_at | TIMESTAMP | Fecha de actualizacion | + #### `refresh_tokens` | Campo | Tipo | Descripcion | |-------|------|-------------| @@ -244,6 +303,7 @@ | area_name | VARCHAR | Nombre del area | | location | TEXT | Ubicacion | | status | ENUM | ACTIVE, INACTIVE, COMPLETED | +| organismo_operador_id | UUID FK | Organismo operador propietario | | meter_type_id | UUID FK | Tipo de medidor por defecto | | created_by | UUID FK | Usuario creador | diff --git a/docs/INSTALACION.md b/docs/INSTALACION.md index 5fc52ac..47c556c 100644 --- a/docs/INSTALACION.md +++ b/docs/INSTALACION.md @@ -49,8 +49,12 @@ psql -U water_user -d water_project -f add_notifications.sql psql -U water_user -d water_project -f add_meter_extended_fields.sql psql -U water_user -d water_project -f add_meter_project_relation.sql psql -U water_user -d water_project -f add_meter_types.sql +psql -U water_user -d water_project -f add_organismos_operadores.sql +psql -U water_user -d water_project -f add_user_meter_fields.sql ``` +**Nota:** `add_organismos_operadores.sql` crea la tabla `organismos_operadores`, agrega columnas FK en `projects` y `users`, y agrega el rol `ORGANISMO_OPERADOR`. `add_user_meter_fields.sql` agrega campos como `cespt_account` y `cadastral_key`. + ### 3. Configurar Variables de Entorno ```bash diff --git a/docs/MANUAL_USUARIO.md b/docs/MANUAL_USUARIO.md index 6c43c6e..83c3bb3 100644 --- a/docs/MANUAL_USUARIO.md +++ b/docs/MANUAL_USUARIO.md @@ -8,10 +8,12 @@ 4. [Gestion de Concentradores](#gestion-de-concentradores) 5. [Gestion de Medidores](#gestion-de-medidores) 6. [Consumo y Lecturas](#consumo-y-lecturas) -7. [Panel de Carga CSV](#panel-de-carga-csv) -8. [Notificaciones](#notificaciones) -9. [Administracion de Usuarios](#administracion-de-usuarios) -10. [Auditoria](#auditoria) +7. [Historico de Tomas](#historico-de-tomas) +8. [Organismos Operadores](#organismos-operadores) +9. [Panel de Carga CSV](#panel-de-carga-csv) +10. [Notificaciones](#notificaciones) +11. [Administracion de Usuarios](#administracion-de-usuarios) +12. [Auditoria](#auditoria) --- @@ -28,13 +30,24 @@ 3. Introduzca su contraseña 4. Haga clic en "Iniciar Sesion" -### Roles de Usuario +### Roles de Usuario (Jerarquia de 3 niveles) -| Rol | Permisos | -|-----|----------| -| **ADMIN** | Acceso completo a todas las funciones | -| **OPERATOR** | Gestion de medidores y lecturas de su proyecto asignado | -| **VIEWER** | Solo visualizacion de datos | +| Rol | Permisos | Visibilidad | +|-----|----------|-------------| +| **ADMIN** | Acceso completo a todas las funciones | Ve todos los datos del sistema | +| **ORGANISMO_OPERADOR** | Gestion de usuarios y visualizacion de su organismo | Ve datos de los proyectos de su organismo | +| **OPERATOR** | Operacion de medidores de su proyecto | Ve datos de su proyecto asignado | + +### Menu Lateral por Rol + +| Seccion | ADMIN | ORGANISMO_OPERADOR | OPERATOR | +|---------|-------|-------------------|----------| +| Dashboard | Si | Si | Si | +| Project Management | Si | Si | Si | +| Users Management | Si | Si | No | +| Organismos Operadores | Si | No | No | +| Conectores | Si | No | No | +| Analytics | Si | Si | No | --- @@ -204,6 +217,83 @@ Los concentradores son dispositivos que agrupan multiples medidores. --- +## Historico de Tomas + +*Disponible para todos los roles. Cada rol solo ve los medidores de su scope.* + +### Acceder al Historico +1. Navegue a **Historico** en la seccion "Project Management" del menu lateral +2. Vera un selector de medidor y un estado vacio inicial + +### Seleccionar Medidor +1. Haga clic en el campo de busqueda +2. Escriba para filtrar por: + - Nombre del medidor + - Numero de serie + - Ubicacion + - Cuenta CESPT + - Clave catastral +3. Seleccione el medidor del dropdown + +### Informacion del Medidor +Al seleccionar un medidor se muestra: +- **Tarjeta de informacion:** Serial, nombre, proyecto, ubicacion, tipo, estado, ultima lectura +- **Cards de consumo:** + - **Consumo Actual:** Lectura mas reciente (consumo diario) + - **Consumo Pasado:** Lectura del primer dia del mes anterior + - **Diferencial:** Diferencia entre actual y pasado (con indicador de tendencia) + +### Filtrar por Fechas +1. Use los campos "Desde" y "Hasta" para definir un rango +2. Los datos se actualizan automaticamente +3. Use el boton "Limpiar" para remover los filtros + +### Grafica de Consumo +- Grafica de area con gradiente azul +- Eje X: fechas, Eje Y: valor de lectura (m3) +- El rango del eje Y se ajusta automaticamente a los datos + +### Tabla de Lecturas +- Columnas: Fecha/Hora, Lectura (m3), Tipo, Bateria, Senal +- Paginacion configurable: 10, 20 o 50 registros por pagina +- Indicadores visuales de bateria y senal + +### Exportar CSV +1. Haga clic en el boton **"Exportar CSV"** en el encabezado +2. Se descargara un archivo `historico_{serial}_{fecha}.csv` + +--- + +## Organismos Operadores + +*Solo disponible para usuarios con rol ADMIN* + +### Ver Organismos +1. Haga clic en **"Organismos Operadores"** en el menu lateral +2. Vera la tabla con todos los organismos registrados + +### Crear Organismo +1. Haga clic en **"Nuevo Organismo"** +2. Complete los campos: + - **Nombre:** Nombre del organismo (ej: CESPT Tijuana) + - **Codigo:** Codigo unico (ej: CESPT-TJ) + - **Contacto:** Nombre de la persona de contacto + - **Email:** Correo electronico de contacto + - **Telefono:** Numero de telefono + - **Estado:** Activo/Inactivo +3. Haga clic en **"Guardar"** + +### Editar Organismo +1. Haga clic en el icono de edicion del organismo +2. Modifique los campos necesarios +3. Haga clic en **"Guardar"** + +### Vincular Proyectos y Usuarios +- Los proyectos se vinculan a un organismo via el campo `organismo_operador_id` en la pagina de Proyectos +- Los usuarios con rol ORGANISMO_OPERADOR se vinculan a un organismo via la pagina de Usuarios + +--- + ## Panel de Carga CSV El panel de carga CSV permite subir datos de medidores y lecturas sin necesidad de autenticacion. @@ -297,11 +387,11 @@ MED002,567.89,2024-01-20 10:35:00,MANUAL,90,-42 ## Administracion de Usuarios -*Solo disponible para usuarios con rol ADMIN* +*Disponible para ADMIN (ve todos) y ORGANISMO_OPERADOR (ve los de su organismo)* ### Ver Usuarios 1. Navegue a **Usuarios** en el menu lateral -2. Vera la lista de todos los usuarios +2. Vera la lista de usuarios filtrada segun su rol ### Crear Usuario 1. Haga clic en **"Nuevo Usuario"** @@ -309,8 +399,9 @@ MED002,567.89,2024-01-20 10:35:00,MANUAL,90,-42 - **Email**: Correo electronico (sera el usuario de login) - **Nombre**: Nombre completo - **Contraseña**: Contraseña inicial - - **Rol**: ADMIN, OPERATOR, o VIEWER - - **Proyecto**: Solo para OPERATOR - proyecto asignado + - **Rol**: ADMIN, ORGANISMO_OPERADOR, u OPERATOR + - **Organismo Operador**: Para ORGANISMO_OPERADOR - organismo asignado + - **Proyecto**: Para OPERATOR - proyecto asignado 3. Haga clic en **"Guardar"** ### Editar Usuario