erp-mecanicas-diesel/docs/02-definicion-modulos/MMD-001-fundamentos/historias-usuario/US-MMD001-006-rls-aislamiento.md

5.5 KiB

US-MMD001-006: Aplicar RLS por Taller

Metadata

Campo Valor
ID US-MMD001-006
Epica EPIC-MMD-001 - Fundamentos
Modulo fundamentos
Prioridad P0
Story Points 5
Sprint Sprint 1
Estado Backlog
Asignado a Por asignar

Historia de Usuario

Como sistema, quiero aplicar Row-Level Security (RLS) en todas las tablas por workshop_id, para garantizar que cada taller solo vea y modifique sus propios datos.

Descripcion Detallada

RLS (Row-Level Security) es una caracteristica de PostgreSQL que permite filtrar filas automaticamente basandose en el usuario actual. Cada query se filtra automaticamente por el workshop_id del usuario logueado, garantizando aislamiento total de datos entre talleres.


Criterios de Aceptacion

Escenario 1: Aislamiento de datos entre talleres

DADO que existen 2 talleres: "Diesel Express" y "Mecanica Industrial"
CUANDO un usuario de "Diesel Express" consulta ordenes de servicio
ENTONCES solo ve las ordenes de "Diesel Express"
Y no ve ninguna orden de "Mecanica Industrial"

Escenario 2: Contexto de sesion automatico

DADO que un usuario inicia sesion en "Diesel Express"
CUANDO el sistema establece la sesion
ENTONCES se configura automaticamente app.current_workshop_id = 'uuid-diesel-express'
Y todas las queries filtran por ese workshop_id

Escenario 3: Insercion con workshop_id automatico

DADO que un usuario de "Diesel Express" crea una nueva orden
CUANDO inserta el registro
ENTONCES el sistema asigna automaticamente workshop_id del contexto
Y no se requiere especificar workshop_id manualmente

Escenario 4: Proteccion contra acceso cruzado

DADO que un usuario de "Diesel Express" intenta acceder a orden de "Mecanica Industrial"
CUANDO hace GET /api/orders/{id-de-mecanica-industrial}
ENTONCES el sistema retorna 404 Not Found
Y no revela que el registro existe en otro taller

Escenario 5: SuperAdmin ve todos los talleres

DADO que un SuperAdmin accede al sistema
CUANDO consulta datos
ENTONCES puede ver registros de todos los talleres
Y puede filtrar por taller especifico

Implementacion Tecnica

Configuracion de Contexto

-- Funcion para establecer contexto
CREATE OR REPLACE FUNCTION set_workshop_context(p_workshop_id UUID)
RETURNS VOID AS $$
BEGIN
  PERFORM set_config('app.current_workshop_id', p_workshop_id::TEXT, FALSE);
END;
$$ LANGUAGE plpgsql;

-- Funcion para obtener contexto
CREATE OR REPLACE FUNCTION get_current_workshop_id()
RETURNS UUID AS $$
BEGIN
  RETURN NULLIF(current_setting('app.current_workshop_id', TRUE), '')::UUID;
END;
$$ LANGUAGE plpgsql;

Politicas RLS por Tabla

-- Ejemplo: Tabla service_orders
ALTER TABLE service_management.service_orders ENABLE ROW LEVEL SECURITY;

-- Politica de lectura
CREATE POLICY service_orders_select ON service_management.service_orders
  FOR SELECT
  USING (workshop_id = get_current_workshop_id() OR is_superadmin());

-- Politica de insercion
CREATE POLICY service_orders_insert ON service_management.service_orders
  FOR INSERT
  WITH CHECK (workshop_id = get_current_workshop_id());

-- Politica de actualizacion
CREATE POLICY service_orders_update ON service_management.service_orders
  FOR UPDATE
  USING (workshop_id = get_current_workshop_id());

-- Politica de eliminacion
CREATE POLICY service_orders_delete ON service_management.service_orders
  FOR DELETE
  USING (workshop_id = get_current_workshop_id());

Tablas a Proteger

Schema Tabla RLS
workshop_core workshops Solo SuperAdmin
workshop_core work_bays Por workshop_id
workshop_core service_catalog Por workshop_id
service_management service_orders Por workshop_id
service_management diagnostics Por workshop_id
parts_management parts Por workshop_id
parts_management movements Por workshop_id
vehicle_management vehicles Por workshop_id

Tareas Tecnicas

Database:

  • DB-015: Crear funcion set_workshop_context()
  • DB-016: Crear funcion get_current_workshop_id()
  • DB-017: Crear funcion is_superadmin()
  • DB-018: Aplicar RLS a todas las tablas de negocio
  • DB-019: Crear trigger para auto-asignar workshop_id en INSERT

Backend:

  • BE-020: Middleware para establecer contexto al inicio de request
  • BE-021: Ejecutar set_workshop_context() en cada conexion
  • BE-022: Tests de penetracion entre tenants

Frontend:

  • No aplica (transparente para frontend)

Dependencias

Depende de:

  • US-MMD001-001: Configurar taller
  • MGN-004 Tenants (Core)

Bloquea:

  • Todas las demas US (requieren RLS activo)

Tests de Seguridad Requeridos

Test Descripcion Resultado Esperado
Cross-tenant SELECT Intentar leer datos de otro taller 0 registros
Cross-tenant UPDATE Intentar modificar datos de otro taller 0 registros afectados
Cross-tenant DELETE Intentar eliminar datos de otro taller 0 registros afectados
Direct ID access Acceder por ID a registro de otro taller 404 Not Found
SuperAdmin access SuperAdmin accede a cualquier taller Exito

Definition of Done (DoD)

  • RLS habilitado en todas las tablas
  • Contexto se establece automaticamente
  • Tests de penetracion pasando
  • SuperAdmin puede ver todo
  • Documentacion de seguridad

Creada por: Requirements-Analyst Fecha: 2025-12-06