-- Panel Transmitiras: usuarios, permisos y sesiones (mismo modelo que -- ~/dev/a24c/backend/api/v1/modules/dashboard — tablas en inglés, esquema a24c). -- Ejecutar en PostgreSQL (misma base donde está el catálogo ControlDesk, p. ej. CONTROLDESK). CREATE SCHEMA IF NOT EXISTS a24c; CREATE TABLE IF NOT EXISTS a24c.dashboard_users ( id SERIAL PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, full_name VARCHAR(100), is_active BOOLEAN NOT NULL DEFAULT true, is_admin BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), last_access_at TIMESTAMPTZ, CONSTRAINT chk_dashboard_users_username_length CHECK (char_length(username) >= 3) ); CREATE TABLE IF NOT EXISTS a24c.dashboard_user_database_permissions ( id SERIAL PRIMARY KEY, dashboard_user_id INTEGER NOT NULL REFERENCES a24c.dashboard_users (id) ON DELETE CASCADE, database_name VARCHAR(255) NOT NULL, can_view BOOLEAN NOT NULL DEFAULT true, can_download_backup BOOLEAN NOT NULL DEFAULT false, can_restore BOOLEAN NOT NULL DEFAULT false, assigned_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE (dashboard_user_id, database_name) ); CREATE TABLE IF NOT EXISTS a24c.dashboard_sessions ( id SERIAL PRIMARY KEY, dashboard_user_id INTEGER NOT NULL REFERENCES a24c.dashboard_users (id) ON DELETE CASCADE, token VARCHAR(255) UNIQUE NOT NULL, ip_address VARCHAR(50), user_agent TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), expires_at TIMESTAMPTZ NOT NULL, is_active BOOLEAN NOT NULL DEFAULT true ); CREATE INDEX IF NOT EXISTS idx_a24c_dashboard_user_db_perm_user ON a24c.dashboard_user_database_permissions (dashboard_user_id); CREATE INDEX IF NOT EXISTS idx_a24c_dashboard_user_db_perm_dbname ON a24c.dashboard_user_database_permissions (database_name); CREATE INDEX IF NOT EXISTS idx_a24c_dashboard_users_active ON a24c.dashboard_users (is_active); CREATE INDEX IF NOT EXISTS idx_a24c_dashboard_sessions_token ON a24c.dashboard_sessions (token); CREATE INDEX IF NOT EXISTS idx_a24c_dashboard_sessions_user ON a24c.dashboard_sessions (dashboard_user_id); COMMENT ON TABLE a24c.dashboard_users IS 'Operadores del panel Transmitiras (JWT/bcrypt). Paridad api/v1/modules/dashboard/users.'; COMMENT ON TABLE a24c.dashboard_user_database_permissions IS 'Permisos por base de datos. Paridad dashboard/user_database_permissions.'; COMMENT ON TABLE a24c.dashboard_sessions IS 'Sesiones persistidas (opcional; el panel usa JWT en cookie). Paridad dashboard/sessions.'; -- Usuario admin por defecto (cambiar password_hash tras primer arranque; ver scripts/generate-password-hash.js) INSERT INTO a24c.dashboard_users (username, email, password_hash, full_name, is_admin, is_active) VALUES ( 'admin', 'admin@aduanasoft.com', '$2b$10$rKvvkYpNwF5J5K5J5J5J5uX5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X', 'Administrador del Sistema', true, true ) ON CONFLICT (username) DO NOTHING;