MaintenanceApp utiliza un Modelo de Seguridad Basado en Contratos. Esta guía explica cómo el sistema segrega la información entre distintas organizaciones y roles especializados.
Control Estratégico y Financiero
Ana es la Directora de Propiedad en Contoso Real Estate. Como Administradora, tiene acceso total al sistema — aprueba CAPEX, supervisa el mantenimiento estructural y gestiona todas las organizaciones del portafolio.
director@contoso.comAcceso a Todo el Portafolio
Miguel es técnico interno de Contoso Real Estate. Gestiona todas las categorías de mantenimiento y tiene acceso a toda la estructura de activos — edificios, espacios y equipos.
internal_tech@contoso.comAlcance Restringido por Categoría
Sara trabaja para Acme HVAC & Systems. Su vista está filtrada por el contrato activo de HVAC — solo accede a activos de climatización e incidentes dentro de esa categoría.
hvac_tech@acme.comSistemas Críticos y Estructurales
Tomás trabaja para Rapid Elevator Solutions. Gestiona renovaciones estructurales y mantenimiento mecánico especializado bajo un contrato de proveedor acotado a sistemas de elevación.
elevator_tech@rapid.comÁreas Exteriores del Sitio
Carlos gestiona los terrenos exteriores para Green Horizons Landscape. Como técnico contratista, se encarga de los servicios blandos no críticos en toda la periferia del sitio.
landscape_tech@horizons.comServicios Blandos
Lucía gestiona las tareas de limpieza para Shiny Cleaning Co. Su alcance se limita a higiene, saneamiento e incidentes de servicios blandos asignados bajo el contrato de limpieza.
cleaning_tech@shiny.comLos permisos no se asignan solo por rol; están acotados por Alcances de Contrato que vinculan a un Proveedor con una Categoría específica.
Un usuario asignado a un Sitio hereda automáticamente el acceso a todos los Edificios, Espacios y Activos hijos dentro de ese árbol.
Separa al Técnico Responsable (Ejecución) del Gerente de Sitio Garante (Verificación y Cierre).
const isAuthorized = async (user, wo) => {
// 1. Check direct internal assignment
if (user.orgId === wo.ownerOrgId) return true;
// 2. Check Contractual Scoping
const contract = await getActiveContract(
user.orgId,
wo.categoryId
);
return !!contract;
};