import { db } from '../db.js'; import { camelJob, camelJobHost, camelJobLog } from './mappers.js'; // A job is visible to the operator who triggered it, to anyone who can see the // linked RunPlan, or to any admin. This prevents cross-user log/output leakage. function jobVisibilityClause() { return `( j.triggered_by = ? OR r.visibility = 'shared' OR r.owner_user_id = ? OR r.group_id IN (SELECT group_id FROM user_groups WHERE user_id = ?) )`; } export function listJobs(userId, isAdmin = false) { if (isAdmin) { return db.prepare(` SELECT j.*, r.name AS runplan_name, s.name AS script_name FROM jobs j LEFT JOIN runplans r ON r.id = j.runplan_id LEFT JOIN scripts s ON s.id = j.script_id ORDER BY j.created_at DESC LIMIT 100 `).all().map(camelJob); } return db.prepare(` SELECT j.*, r.name AS runplan_name, s.name AS script_name FROM jobs j LEFT JOIN runplans r ON r.id = j.runplan_id LEFT JOIN scripts s ON s.id = j.script_id WHERE ${jobVisibilityClause()} ORDER BY j.created_at DESC LIMIT 100 `).all(userId, userId, userId).map(camelJob); } export function getJob(jobId, userId, isAdmin = false) { const job = isAdmin ? db.prepare(` SELECT j.*, r.name AS runplan_name, s.name AS script_name FROM jobs j LEFT JOIN runplans r ON r.id = j.runplan_id LEFT JOIN scripts s ON s.id = j.script_id WHERE j.id = ? `).get(jobId) : db.prepare(` SELECT j.*, r.name AS runplan_name, s.name AS script_name FROM jobs j LEFT JOIN runplans r ON r.id = j.runplan_id LEFT JOIN scripts s ON s.id = j.script_id WHERE j.id = ? AND ${jobVisibilityClause()} `).get(jobId, userId, userId, userId); if (!job) return null; const hosts = db.prepare(` SELECT jh.*, h.name AS host_name, h.address AS host_address FROM job_hosts jh LEFT JOIN hosts h ON h.id = jh.host_id WHERE jh.job_id = ? ORDER BY h.name `).all(jobId); const logs = db.prepare(` SELECT jl.*, h.name AS host_name FROM job_logs jl LEFT JOIN hosts h ON h.id = jl.host_id WHERE jl.job_id = ? ORDER BY jl.created_at, jl.id `).all(jobId); return { ...camelJob(job), hosts: hosts.map(camelJobHost), logs: logs.map(camelJobLog) }; }