From 5f84a44d1f9f326d31b001c507a04f9f5b074e53 Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Tue, 25 Aug 2026 11:01:46 +0000 Subject: [PATCH] Add hotel_location and met_office integrations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two new schema-driven integrations for hvac's weather compensation feature: hotel_location (lat/lon, plaintext config) and met_office (encrypted api_key). Both surface automatically on the portal's Integrations tab via the existing generic integration UI/routes — no portal changes needed. Deliberately central here rather than hvac-local so other apps can reuse the hotel's location later. Added a met_office connection test (DataHub daily-forecast call) alongside the others. Co-Authored-By: Claude Sonnet 5 --- src/integrations/schema.js | 10 ++++++++++ src/routes/integrations.js | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/integrations/schema.js b/src/integrations/schema.js index f43c74a..4b9079a 100644 --- a/src/integrations/schema.js +++ b/src/integrations/schema.js @@ -52,6 +52,16 @@ export const INTEGRATIONS = { configFields: ['host', 'port'], secretFields: ['username', 'password'], }, + hotel_location: { + name: 'Hotel Location', + configFields: ['latitude', 'longitude'], + secretFields: [], + }, + met_office: { + name: 'Met Office DataHub', + configFields: [], + secretFields: ['api_key'], + }, } export const MASKED = '••••••••' diff --git a/src/routes/integrations.js b/src/routes/integrations.js index a8a2125..76ac858 100644 --- a/src/routes/integrations.js +++ b/src/routes/integrations.js @@ -166,6 +166,18 @@ export async function integrationRoutes(app) { if (res.status === 401 || res.status === 403) throw new Error('Invalid Azure API key') if (!res.ok) throw new Error(`Azure returned ${res.status}`) } + else if (req.params.slug === 'met_office') { + if (!creds.api_key) throw new Error('Met Office API key required') + const { rows: [loc] } = await pool.query(`SELECT config FROM integrations WHERE slug = 'hotel_location'`) + const lat = loc?.config?.latitude || '51.5072' + const lon = loc?.config?.longitude || '-0.1276' + const res = await fetch( + `https://data.hub.api.metoffice.gov.uk/sitespecific/v0/point/daily?latitude=${lat}&longitude=${lon}`, + { headers: { apikey: creds.api_key }, signal: AbortSignal.timeout(8000) } + ) + if (res.status === 401 || res.status === 403) throw new Error('Invalid Met Office API key') + if (!res.ok) throw new Error(`Met Office DataHub returned ${res.status}`) + } else if (req.params.slug === 'sambapos') { const errors = [] // SQL test — SambaPOS uses MSSQL; host may be "server\INSTANCE"