This commit is contained in:
2026-06-25 12:05:53 -05:00
commit b58e50e423
141 changed files with 28190 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
import { db, id, now, visibleClause } from '../db.js';
function camelChangeRequest(row) {
if (!row) return null;
return {
id: row.id,
deploymentId: row.deployment_id,
deploymentName: row.deployment_name || null,
connectionId: row.connection_id,
action: row.action,
status: row.status,
requestedBy: row.requested_by,
requesterEmail: row.requester_email || '',
approverUserId: row.approver_user_id,
approverEmail: row.approver_email || '',
reason: row.reason || '',
decidedAt: row.decided_at || '',
executedAt: row.executed_at || '',
createdAt: row.created_at,
updatedAt: row.updated_at
};
}
export function createChangeRequest({ deploymentId, connectionId, action, requestedBy, requesterEmail }) {
const requestId = id('chg');
db.prepare(`
INSERT INTO change_requests (id, deployment_id, connection_id, action, status, requested_by, requester_email, created_at, updated_at)
VALUES (?, ?, ?, ?, 'pending', ?, ?, ?, ?)
`).run(requestId, deploymentId, connectionId || null, action, requestedBy || null, requesterEmail || '', now(), now());
return camelChangeRequest(db.prepare('SELECT * FROM change_requests WHERE id = ?').get(requestId));
}
export function findApprovedRequest(deploymentId, action) {
const row = db.prepare(`
SELECT * FROM change_requests
WHERE deployment_id = ? AND action = ? AND status = 'approved'
ORDER BY decided_at DESC LIMIT 1
`).get(deploymentId, action);
return camelChangeRequest(row);
}
export function findPendingRequest(deploymentId, action) {
const row = db.prepare(`
SELECT * FROM change_requests
WHERE deployment_id = ? AND action = ? AND status = 'pending'
ORDER BY created_at DESC LIMIT 1
`).get(deploymentId, action);
return camelChangeRequest(row);
}
export function getChangeRequest(requestId) {
return camelChangeRequest(db.prepare('SELECT * FROM change_requests WHERE id = ?').get(requestId));
}
// Requests are scoped to deployments the user can see; admins see all.
export function listChangeRequests(userId, { status, isAdmin = false } = {}) {
const where = [];
const params = [];
if (!isAdmin) {
where.push(`d.id IS NOT NULL AND ${visibleClause('d')}`);
params.push(userId, userId);
}
if (status) { where.push('c.status = ?'); params.push(status); }
const clause = where.length ? `WHERE ${where.join(' AND ')}` : '';
return db.prepare(`
SELECT c.*, d.name AS deployment_name
FROM change_requests c
LEFT JOIN intune_deployments d ON d.id = c.deployment_id
${clause}
ORDER BY c.created_at DESC
LIMIT 200
`).all(...params).map(camelChangeRequest);
}
export function decideChangeRequest(requestId, { status, approverUserId, approverEmail, reason }) {
const existing = db.prepare('SELECT * FROM change_requests WHERE id = ?').get(requestId);
if (!existing || existing.status !== 'pending') return null;
db.prepare(`
UPDATE change_requests
SET status = ?, approver_user_id = ?, approver_email = ?, reason = ?, decided_at = ?, updated_at = ?
WHERE id = ?
`).run(status, approverUserId || null, approverEmail || '', reason || '', now(), now(), requestId);
return getChangeRequest(requestId);
}
export function markRequestExecuted(requestId) {
db.prepare(`UPDATE change_requests SET status = 'executed', executed_at = ?, updated_at = ? WHERE id = ?`)
.run(now(), now(), requestId);
}