Add 3-level role permissions, organismos operadores, and Histórico de Tomas page

Implements the full ADMIN → ORGANISMO_OPERADOR → OPERATOR permission hierarchy
with scope-filtered data access across all backend services. Adds organismos
operadores management (ADMIN only) and a new Histórico page for viewing
per-meter reading history with chart, consumption stats, and CSV export.

Key changes:
- Backend: 3-level scope filtering on all services (meters, readings, projects, users)
- Backend: Protect GET /meters routes with authenticateToken for role-based filtering
- Backend: Pass requestingUser to reading service for scoped meter readings
- Frontend: New HistoricoPage with meter selector, AreaChart, paginated table
- Frontend: Consumption cards (Actual, Pasado, Diferencial) above date filters
- Frontend: Meter search by name, serial, location, CESPT account, cadastral key
- Frontend: OrganismosPage, updated Sidebar with 3-level visibility
- SQL migrations for organismos_operadores table and FK columns

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Exteban08
2026-02-09 10:21:33 +00:00
parent 61dafa83ac
commit 613fb2d787
43 changed files with 3049 additions and 324 deletions

View File

@@ -0,0 +1,48 @@
import { Router } from 'express';
import { authenticateToken, requireRole } from '../middleware/auth.middleware';
import * as organismoController from '../controllers/organismo-operador.controller';
const router = Router();
/**
* All routes require authentication
*/
router.use(authenticateToken);
/**
* GET /organismos-operadores
* List all organismos operadores (ADMIN and ORGANISMO_OPERADOR)
*/
router.get('/', requireRole('ADMIN', 'ORGANISMO_OPERADOR'), organismoController.getAll);
/**
* GET /organismos-operadores/:id
* Get a single organismo by ID
*/
router.get('/:id', requireRole('ADMIN', 'ORGANISMO_OPERADOR'), organismoController.getById);
/**
* GET /organismos-operadores/:id/projects
* Get projects belonging to an organismo
*/
router.get('/:id/projects', requireRole('ADMIN', 'ORGANISMO_OPERADOR'), organismoController.getProjects);
/**
* POST /organismos-operadores
* Create a new organismo operador (ADMIN only)
*/
router.post('/', requireRole('ADMIN'), organismoController.create);
/**
* PUT /organismos-operadores/:id
* Update an organismo operador (ADMIN only)
*/
router.put('/:id', requireRole('ADMIN'), organismoController.update);
/**
* DELETE /organismos-operadores/:id
* Delete an organismo operador (ADMIN only)
*/
router.delete('/:id', requireRole('ADMIN'), organismoController.remove);
export default router;