import { db } from '../db/index.js'; import { getHost } from '../hosts/index.js'; import { recordProgress } from './progress.js'; import type { ProvisioningDetail } from '../../provisioning-detail.js'; export const safetyOverrideCapability = 'instance.safety-override'; export function safetyOverride(id: string): ProvisioningDetail['safetyOverride'] { return db().prepare(`SELECT actor_id AS actorId, actor_name AS actorName, confirmed_at AS confirmedAt FROM provisioning_safety_overrides WHERE deployment_id=?`).get(id) as ProvisioningDetail['safetyOverride'] ?? null; } /** Approval belongs to one unsubmitted operation and its original live instance. */ export function safetyOverrideAvailability(id: string): { applicable: boolean; unavailableReason: string | null } { const target = db().prepare(`SELECT i.host_id FROM server_deployments d JOIN native_provisioning n ON n.deployment_id=d.id JOIN native_instances i ON i.id=n.instance_id AND i.server=d.server AND i.generation=n.generation AND i.retired_at IS NULL WHERE d.id=? AND d.server_deleted_at IS NULL AND d.action IN ('restart','stop','rebuild','destroy') AND d.state IN ('queued','waiting') AND d.submitted_at IS NULL AND n.operation_id IS NULL AND NOT EXISTS (SELECT 1 FROM ec_host_migrations m WHERE m.deployment_id=d.id) AND NOT EXISTS (SELECT 1 FROM native_creation_cancellations c WHERE c.cleanup_id=d.id) AND NOT EXISTS (SELECT 1 FROM autoscaling_decisions a WHERE a.operation_id=d.id) AND NOT EXISTS (SELECT 1 FROM provisioning_safety_overrides o WHERE o.deployment_id=d.id)`) .get(id) as { host_id: string } | undefined; if (!target) return { applicable: false, unavailableReason: null }; return { applicable: true, unavailableReason: getHost(target.host_id)?.inventory.capabilities?.includes(safetyOverrideCapability) ? null : 'Update this host’s agent before using admin override.' }; } export function enableSafetyOverride(id: string, actor: { id: string; username: string }): { ok: true } | { ok: false; error: string } { return db().transaction(() => { // A retried confirmation never sends or repeats a command. if (safetyOverride(id)) return { ok: true as const }; const availability = safetyOverrideAvailability(id); if (!availability.applicable) return { ok: false as const, error: 'This operation can no longer be overridden. Refresh to see its current state.' }; if (availability.unavailableReason) return { ok: false as const, error: availability.unavailableReason }; const confirmedAt = new Date().toISOString(); db().prepare('INSERT INTO provisioning_safety_overrides(deployment_id,actor_id,actor_name,confirmed_at) VALUES(?,?,?,?)') .run(id, actor.id, actor.username, confirmedAt); recordProgress(id, { event: { kind: 'safety-override', message: `Admin override confirmed by ${actor.username}: bypass player safety checks for this operation.`, details: { actorId: actor.id, actorName: actor.username, confirmedAt, checks: ['player-occupancy'] } } }); return { ok: true as const }; })(); }