diff --git a/app/models/integration.server.ts b/app/models/integration.server.ts index 75a6f83d..67bf2308 100644 --- a/app/models/integration.server.ts +++ b/app/models/integration.server.ts @@ -26,3 +26,61 @@ export async function isValidServiceKey(serviceKey: string | null): Promise = [] + + for (const intg of integrations) { + const serviceKey = process.env[intg.serviceKey] + + if (!serviceKey) { + results.push({ + slug: intg.slug, + ok: false, + error: `Service key '${intg.serviceKey}' not configured`, + }) + continue + } + + try { + const response = await fetch(`${intg.serviceUrl}/integrations/${deviceId}`, { + method: 'DELETE', + headers: { + 'x-service-key': serviceKey, + }, + }) + + // 404 is fine: no integration existed for this device + if (response.ok || response.status === 404) { + results.push({ + slug: intg.slug, + ok: true, + status: response.status, + }) + } else { + const text = await response.text() + results.push({ + slug: intg.slug, + ok: false, + status: response.status, + error: text, + }) + } + } catch (error) { + results.push({ + slug: intg.slug, + ok: false, + error: error instanceof Error ? error.message : String(error), + }) + } + } + + return results +} \ No newline at end of file diff --git a/app/routes/device.$deviceId.edit.general.tsx b/app/routes/device.$deviceId.edit.general.tsx index 56498ef7..520eda1c 100644 --- a/app/routes/device.$deviceId.edit.general.tsx +++ b/app/routes/device.$deviceId.edit.general.tsx @@ -16,6 +16,7 @@ import { MarkdownContent } from '~/components/markdown-content' import { Button } from '~/components/ui/button' import { updateDevice, deleteDevice } from '~/lib/devices-service.server' import { getDevice, getDeviceWithoutSensors } from '~/models/device.server' +import { deleteDeviceIntegrations } from '~/models/integration.server' import { verifyLogin } from '~/models/user.server' import { type Device } from '~/schema' import { @@ -241,6 +242,16 @@ export async function action({ request, params }: ActionFunctionArgs) { } } + const integrationDeletionResults = await deleteDeviceIntegrations(deviceID) + + const failedDeletions = integrationDeletionResults.filter((result) => !result.ok) + if (failedDeletions.length > 0) { + console.error('Failed to delete one or more integrations before device deletion', { + deviceID, + failedDeletions, + }) + } + await deleteDevice(user, device, passwordDelete) return redirect('/profile/me')