-- ═══════════════════════════════════════════════════════════════════════════════ -- SEED 02: USUARIOS Y PERFILES -- ═══════════════════════════════════════════════════════════════════════════════ -- Proyecto: ERP Construcción -- Autor: Claude Opus 4.5 -- Fecha: 2026-02-03 -- Descripción: Roles, permisos y usuarios demo del sistema -- Dependencias: 01-core-catalogs.sql -- ═══════════════════════════════════════════════════════════════════════════════ -- UUIDs determinísticos: -- Prefijo: 00000000-0000-0000-0002-XXXXXXXXXXXX para usuarios/roles BEGIN; -- ───────────────────────────────────────────────────────────────────────────────── -- 1. ROLES DEL SISTEMA -- ───────────────────────────────────────────────────────────────────────────────── INSERT INTO auth.roles (id, code, name, description, is_system, is_active, created_at) VALUES ('00000000-0000-0000-0002-000000000001', 'super_admin', 'Super Administrador', 'Acceso total al sistema, gestión de tenants', true, true, NOW()), ('00000000-0000-0000-0002-000000000002', 'director', 'Director General', 'Acceso ejecutivo, reportes gerenciales, aprobaciones finales', false, true, NOW()), ('00000000-0000-0000-0002-000000000003', 'gerente_obra', 'Gerente de Obra', 'Gestión completa de proyectos asignados', false, true, NOW()), ('00000000-0000-0000-0002-000000000004', 'residente', 'Residente de Obra', 'Supervisión diaria, captura de avances, estimaciones', false, true, NOW()), ('00000000-0000-0000-0002-000000000005', 'supervisor', 'Supervisor de Campo', 'Control de obra, bitácora, avances', false, true, NOW()), ('00000000-0000-0000-0002-000000000006', 'almacenista', 'Almacenista', 'Control de inventario, entradas/salidas', false, true, NOW()), ('00000000-0000-0000-0002-000000000007', 'contabilidad', 'Contador', 'Gestión financiera, pólizas, CxP, CxC', false, true, NOW()), ('00000000-0000-0000-0002-000000000008', 'rrhh', 'Recursos Humanos', 'Gestión de personal, nómina, capacitación', false, true, NOW()), ('00000000-0000-0000-0002-000000000009', 'hse', 'Seguridad e Higiene', 'Gestión HSE, inspecciones, incidentes', false, true, NOW()), ('00000000-0000-0000-0002-000000000010', 'calidad', 'Control de Calidad', 'Inspecciones, checklists, no conformidades', false, true, NOW()), ('00000000-0000-0000-0002-000000000011', 'comprador', 'Comprador', 'Requisiciones, órdenes de compra, proveedores', false, true, NOW()), ('00000000-0000-0000-0002-000000000012', 'cliente_visor', 'Cliente (Solo Lectura)', 'Visualización de avances de su propiedad', false, true, NOW()) ON CONFLICT (id) DO NOTHING; -- ───────────────────────────────────────────────────────────────────────────────── -- 2. PERMISOS DEL SISTEMA -- ───────────────────────────────────────────────────────────────────────────────── INSERT INTO auth.permissions (id, code, name, module, action, description, is_active, created_at) VALUES -- Módulo: Proyectos (construction) ('00000000-0000-0000-0002-000000001001', 'construction.view', 'Ver Proyectos', 'construction', 'view', 'Ver proyectos y fraccionamientos', true, NOW()), ('00000000-0000-0000-0002-000000001002', 'construction.create', 'Crear Proyectos', 'construction', 'create', 'Crear nuevos proyectos', true, NOW()), ('00000000-0000-0000-0002-000000001003', 'construction.edit', 'Editar Proyectos', 'construction', 'edit', 'Modificar proyectos existentes', true, NOW()), ('00000000-0000-0000-0002-000000001004', 'construction.delete', 'Eliminar Proyectos', 'construction', 'delete', 'Eliminar proyectos', true, NOW()), ('00000000-0000-0000-0002-000000001005', 'construction.approve', 'Aprobar Proyectos', 'construction', 'approve', 'Aprobar cambios en proyectos', true, NOW()), -- Módulo: Presupuestos (budgets) ('00000000-0000-0000-0002-000000001010', 'budgets.view', 'Ver Presupuestos', 'budgets', 'view', 'Ver presupuestos', true, NOW()), ('00000000-0000-0000-0002-000000001011', 'budgets.create', 'Crear Presupuestos', 'budgets', 'create', 'Crear presupuestos', true, NOW()), ('00000000-0000-0000-0002-000000001012', 'budgets.edit', 'Editar Presupuestos', 'budgets', 'edit', 'Modificar presupuestos', true, NOW()), ('00000000-0000-0000-0002-000000001013', 'budgets.approve', 'Aprobar Presupuestos', 'budgets', 'approve', 'Aprobar presupuestos', true, NOW()), -- Módulo: Avances (progress) ('00000000-0000-0000-0002-000000001020', 'progress.view', 'Ver Avances', 'progress', 'view', 'Ver avances de obra', true, NOW()), ('00000000-0000-0000-0002-000000001021', 'progress.capture', 'Capturar Avances', 'progress', 'create', 'Capturar avances', true, NOW()), ('00000000-0000-0000-0002-000000001022', 'progress.review', 'Revisar Avances', 'progress', 'review', 'Revisar avances capturados', true, NOW()), ('00000000-0000-0000-0002-000000001023', 'progress.approve', 'Aprobar Avances', 'progress', 'approve', 'Aprobar avances', true, NOW()), -- Módulo: Estimaciones (estimates) ('00000000-0000-0000-0002-000000001030', 'estimates.view', 'Ver Estimaciones', 'estimates', 'view', 'Ver estimaciones', true, NOW()), ('00000000-0000-0000-0002-000000001031', 'estimates.create', 'Crear Estimaciones', 'estimates', 'create', 'Crear estimaciones', true, NOW()), ('00000000-0000-0000-0002-000000001032', 'estimates.edit', 'Editar Estimaciones', 'estimates', 'edit', 'Modificar estimaciones', true, NOW()), ('00000000-0000-0000-0002-000000001033', 'estimates.submit', 'Enviar Estimaciones', 'estimates', 'submit', 'Enviar a revisión', true, NOW()), ('00000000-0000-0000-0002-000000001034', 'estimates.approve', 'Aprobar Estimaciones', 'estimates', 'approve', 'Aprobar estimaciones', true, NOW()), -- Módulo: Contratos (contracts) ('00000000-0000-0000-0002-000000001040', 'contracts.view', 'Ver Contratos', 'contracts', 'view', 'Ver contratos', true, NOW()), ('00000000-0000-0000-0002-000000001041', 'contracts.create', 'Crear Contratos', 'contracts', 'create', 'Crear contratos', true, NOW()), ('00000000-0000-0000-0002-000000001042', 'contracts.edit', 'Editar Contratos', 'contracts', 'edit', 'Modificar contratos', true, NOW()), ('00000000-0000-0000-0002-000000001043', 'contracts.approve', 'Aprobar Contratos', 'contracts', 'approve', 'Aprobar contratos', true, NOW()), -- Módulo: Calidad (quality) ('00000000-0000-0000-0002-000000001050', 'quality.view', 'Ver Calidad', 'quality', 'view', 'Ver inspecciones y NC', true, NOW()), ('00000000-0000-0000-0002-000000001051', 'quality.inspect', 'Realizar Inspecciones', 'quality', 'create', 'Ejecutar inspecciones', true, NOW()), ('00000000-0000-0000-0002-000000001052', 'quality.approve', 'Aprobar Inspecciones', 'quality', 'approve', 'Aprobar inspecciones', true, NOW()), -- Módulo: HSE (hse) ('00000000-0000-0000-0002-000000001060', 'hse.view', 'Ver HSE', 'hse', 'view', 'Ver módulo HSE', true, NOW()), ('00000000-0000-0000-0002-000000001061', 'hse.incidents', 'Gestionar Incidentes', 'hse', 'create', 'Registrar incidentes', true, NOW()), ('00000000-0000-0000-0002-000000001062', 'hse.training', 'Gestionar Capacitación', 'hse', 'create', 'Gestionar capacitaciones', true, NOW()), ('00000000-0000-0000-0002-000000001063', 'hse.permits', 'Permisos de Trabajo', 'hse', 'create', 'Gestionar permisos', true, NOW()), -- Módulo: RRHH (hr) ('00000000-0000-0000-0002-000000001070', 'hr.view', 'Ver RRHH', 'hr', 'view', 'Ver empleados', true, NOW()), ('00000000-0000-0000-0002-000000001071', 'hr.manage', 'Gestionar RRHH', 'hr', 'manage', 'Gestionar empleados', true, NOW()), -- Módulo: Finanzas (finance) ('00000000-0000-0000-0002-000000001080', 'finance.view', 'Ver Finanzas', 'finance', 'view', 'Ver módulo financiero', true, NOW()), ('00000000-0000-0000-0002-000000001081', 'finance.entries', 'Pólizas Contables', 'finance', 'create', 'Crear pólizas', true, NOW()), ('00000000-0000-0000-0002-000000001082', 'finance.payments', 'Pagos', 'finance', 'create', 'Registrar pagos', true, NOW()), ('00000000-0000-0000-0002-000000001083', 'finance.reconcile', 'Conciliaciones', 'finance', 'create', 'Realizar conciliaciones', true, NOW()), -- Módulo: Inventario (inventory) ('00000000-0000-0000-0002-000000001090', 'inventory.view', 'Ver Inventario', 'inventory', 'view', 'Ver almacén', true, NOW()), ('00000000-0000-0000-0002-000000001091', 'inventory.manage', 'Gestionar Inventario', 'inventory', 'manage', 'Movimientos de almacén', true, NOW()), -- Módulo: Compras (purchase) ('00000000-0000-0000-0002-000000001100', 'purchase.view', 'Ver Compras', 'purchase', 'view', 'Ver requisiciones y OC', true, NOW()), ('00000000-0000-0000-0002-000000001101', 'purchase.requisitions', 'Requisiciones', 'purchase', 'create', 'Crear requisiciones', true, NOW()), ('00000000-0000-0000-0002-000000001102', 'purchase.orders', 'Órdenes de Compra', 'purchase', 'create', 'Crear OC', true, NOW()), ('00000000-0000-0000-0002-000000001103', 'purchase.approve', 'Aprobar Compras', 'purchase', 'approve', 'Aprobar requisiciones/OC', true, NOW()), -- Módulo: Activos (assets) ('00000000-0000-0000-0002-000000001110', 'assets.view', 'Ver Activos', 'assets', 'view', 'Ver equipos y maquinaria', true, NOW()), ('00000000-0000-0000-0002-000000001111', 'assets.manage', 'Gestionar Activos', 'assets', 'manage', 'Gestionar activos', true, NOW()), -- Módulo: Documentos (documents) ('00000000-0000-0000-0002-000000001120', 'documents.view', 'Ver Documentos', 'documents', 'view', 'Ver repositorio', true, NOW()), ('00000000-0000-0000-0002-000000001121', 'documents.manage', 'Gestionar Documentos', 'documents', 'manage', 'Subir y gestionar docs', true, NOW()), -- Módulo: Reportes (reports) ('00000000-0000-0000-0002-000000001130', 'reports.view', 'Ver Reportes', 'reports', 'view', 'Ver reportes', true, NOW()), ('00000000-0000-0000-0002-000000001131', 'reports.export', 'Exportar Reportes', 'reports', 'export', 'Exportar a PDF/Excel', true, NOW()), -- Módulo: Administración (admin) ('00000000-0000-0000-0002-000000001140', 'admin.users', 'Gestionar Usuarios', 'admin', 'manage', 'Gestionar usuarios', true, NOW()), ('00000000-0000-0000-0002-000000001141', 'admin.roles', 'Gestionar Roles', 'admin', 'manage', 'Gestionar roles', true, NOW()), ('00000000-0000-0000-0002-000000001142', 'admin.settings', 'Configuración', 'admin', 'manage', 'Configuración del sistema', true, NOW()) ON CONFLICT (id) DO NOTHING; -- ───────────────────────────────────────────────────────────────────────────────── -- 3. ASIGNACIÓN ROL-PERMISOS (Matriz de permisos por rol) -- ───────────────────────────────────────────────────────────────────────────────── -- Super Admin: Todos los permisos INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000001', id FROM auth.permissions ON CONFLICT DO NOTHING; -- Director: Vista general + aprobaciones INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000002', id FROM auth.permissions WHERE code LIKE '%.view' OR code LIKE '%.approve' OR code IN ('reports.export', 'documents.view') ON CONFLICT DO NOTHING; -- Gerente de Obra: Gestión de proyectos completa INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000003', id FROM auth.permissions WHERE module IN ('construction', 'budgets', 'progress', 'estimates', 'contracts', 'quality', 'hse', 'reports', 'documents') ON CONFLICT DO NOTHING; -- Residente: Operación diaria INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000004', id FROM auth.permissions WHERE code IN ( 'construction.view', 'budgets.view', 'progress.view', 'progress.capture', 'progress.review', 'estimates.view', 'estimates.create', 'estimates.edit', 'estimates.submit', 'quality.view', 'quality.inspect', 'hse.view', 'hse.incidents', 'documents.view', 'documents.manage', 'reports.view' ) ON CONFLICT DO NOTHING; -- Supervisor: Campo INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000005', id FROM auth.permissions WHERE code IN ( 'construction.view', 'progress.view', 'progress.capture', 'quality.view', 'quality.inspect', 'hse.view', 'hse.incidents', 'inventory.view', 'reports.view' ) ON CONFLICT DO NOTHING; -- Almacenista INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000006', id FROM auth.permissions WHERE code IN ( 'inventory.view', 'inventory.manage', 'purchase.view', 'assets.view', 'reports.view' ) ON CONFLICT DO NOTHING; -- Contador INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000007', id FROM auth.permissions WHERE code IN ( 'finance.view', 'finance.entries', 'finance.payments', 'finance.reconcile', 'estimates.view', 'contracts.view', 'purchase.view', 'reports.view', 'reports.export' ) ON CONFLICT DO NOTHING; -- RRHH INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000008', id FROM auth.permissions WHERE code IN ( 'hr.view', 'hr.manage', 'hse.view', 'hse.training', 'reports.view' ) ON CONFLICT DO NOTHING; -- HSE INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000009', id FROM auth.permissions WHERE code IN ( 'hse.view', 'hse.incidents', 'hse.training', 'hse.permits', 'hr.view', 'construction.view', 'reports.view', 'reports.export' ) ON CONFLICT DO NOTHING; -- Calidad INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000010', id FROM auth.permissions WHERE code IN ( 'quality.view', 'quality.inspect', 'quality.approve', 'construction.view', 'documents.view', 'documents.manage', 'reports.view' ) ON CONFLICT DO NOTHING; -- Comprador INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000011', id FROM auth.permissions WHERE code IN ( 'purchase.view', 'purchase.requisitions', 'purchase.orders', 'inventory.view', 'contracts.view', 'reports.view' ) ON CONFLICT DO NOTHING; -- Cliente Visor (solo lectura limitada) INSERT INTO auth.role_permissions (role_id, permission_id) SELECT '00000000-0000-0000-0002-000000000012', id FROM auth.permissions WHERE code IN ('construction.view', 'progress.view', 'documents.view') ON CONFLICT DO NOTHING; -- ───────────────────────────────────────────────────────────────────────────────── -- 4. USUARIOS DEMO -- ───────────────────────────────────────────────────────────────────────────────── -- Password: Demo2026! (hash bcrypt con salt 10) -- Hash generado: $2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB INSERT INTO auth.users ( id, email, password_hash, first_name, last_name, is_active, is_verified, is_system, created_at ) VALUES -- Super Admin ('00000000-0000-0000-0002-000000000101', 'admin@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Admin', 'Sistema', true, true, true, NOW()), -- Director ('00000000-0000-0000-0002-000000000102', 'director@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Juan Carlos', 'Director Méndez', true, true, false, NOW()), -- Gerente de Obra ('00000000-0000-0000-0002-000000000103', 'gerente1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'María Elena', 'Gerente Torres', true, true, false, NOW()), -- Residente ('00000000-0000-0000-0002-000000000104', 'residente1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Carlos Alberto', 'Residente López', true, true, false, NOW()), -- Supervisor ('00000000-0000-0000-0002-000000000105', 'supervisor1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Ana María', 'Supervisora García', true, true, false, NOW()), -- Almacenista ('00000000-0000-0000-0002-000000000106', 'almacen1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Luis Fernando', 'Almacén Ruiz', true, true, false, NOW()), -- Contador ('00000000-0000-0000-0002-000000000107', 'contador1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Rosa María', 'Contadora Hernández', true, true, false, NOW()), -- RRHH ('00000000-0000-0000-0002-000000000108', 'rrhh1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Pedro Pablo', 'Recursos Martínez', true, true, false, NOW()), -- HSE ('00000000-0000-0000-0002-000000000109', 'hse1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Elena Patricia', 'Seguridad Sánchez', true, true, false, NOW()), -- Calidad ('00000000-0000-0000-0002-000000000110', 'calidad1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Diego Armando', 'Calidad Rodríguez', true, true, false, NOW()), -- Comprador ('00000000-0000-0000-0002-000000000111', 'comprador1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Laura Patricia', 'Compras Jiménez', true, true, false, NOW()), -- Cliente Visor ('00000000-0000-0000-0002-000000000112', 'visor1@demo.com', '$2a$10$rQnP.xNj7Y8hVJYw5v5qYeKKq5PmBnvTYmNZz6KXy5vJYmH5XYZAB', 'Cliente', 'Demo Comprador', true, true, false, NOW()) ON CONFLICT (id) DO NOTHING; -- ───────────────────────────────────────────────────────────────────────────────── -- 5. ASIGNACIÓN USUARIO-ROL -- ───────────────────────────────────────────────────────────────────────────────── INSERT INTO auth.user_roles (user_id, role_id, is_primary, created_at) VALUES ('00000000-0000-0000-0002-000000000101', '00000000-0000-0000-0002-000000000001', true, NOW()), -- admin -> super_admin ('00000000-0000-0000-0002-000000000102', '00000000-0000-0000-0002-000000000002', true, NOW()), -- director -> director ('00000000-0000-0000-0002-000000000103', '00000000-0000-0000-0002-000000000003', true, NOW()), -- gerente1 -> gerente_obra ('00000000-0000-0000-0002-000000000104', '00000000-0000-0000-0002-000000000004', true, NOW()), -- residente1 -> residente ('00000000-0000-0000-0002-000000000105', '00000000-0000-0000-0002-000000000005', true, NOW()), -- supervisor1 -> supervisor ('00000000-0000-0000-0002-000000000106', '00000000-0000-0000-0002-000000000006', true, NOW()), -- almacen1 -> almacenista ('00000000-0000-0000-0002-000000000107', '00000000-0000-0000-0002-000000000007', true, NOW()), -- contador1 -> contabilidad ('00000000-0000-0000-0002-000000000108', '00000000-0000-0000-0002-000000000008', true, NOW()), -- rrhh1 -> rrhh ('00000000-0000-0000-0002-000000000109', '00000000-0000-0000-0002-000000000009', true, NOW()), -- hse1 -> hse ('00000000-0000-0000-0002-000000000110', '00000000-0000-0000-0002-000000000010', true, NOW()), -- calidad1 -> calidad ('00000000-0000-0000-0002-000000000111', '00000000-0000-0000-0002-000000000011', true, NOW()), -- comprador1 -> comprador ('00000000-0000-0000-0002-000000000112', '00000000-0000-0000-0002-000000000012', true, NOW()) -- visor1 -> cliente_visor ON CONFLICT DO NOTHING; -- ───────────────────────────────────────────────────────────────────────────────── -- VERIFICACIÓN -- ───────────────────────────────────────────────────────────────────────────────── DO $$ DECLARE v_roles INTEGER; v_permissions INTEGER; v_users INTEGER; v_role_perms INTEGER; BEGIN SELECT COUNT(*) INTO v_roles FROM auth.roles; SELECT COUNT(*) INTO v_permissions FROM auth.permissions; SELECT COUNT(*) INTO v_users FROM auth.users; SELECT COUNT(*) INTO v_role_perms FROM auth.role_permissions; RAISE NOTICE '══════════════════════════════════════════════════════════════'; RAISE NOTICE 'SEED 02 - USUARIOS Y PERFILES - COMPLETADO'; RAISE NOTICE '══════════════════════════════════════════════════════════════'; RAISE NOTICE 'Roles: %', v_roles; RAISE NOTICE 'Permisos: %', v_permissions; RAISE NOTICE 'Usuarios: %', v_users; RAISE NOTICE 'Asignaciones rol-permiso: %', v_role_perms; RAISE NOTICE '══════════════════════════════════════════════════════════════'; END $$; COMMIT; -- ═══════════════════════════════════════════════════════════════════════════════ -- FIN SEED 02 -- ═══════════════════════════════════════════════════════════════════════════════