From 1fde9f8613ca5c9dd63339a2df704d9416796462 Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Wed, 15 Jul 2026 15:41:51 +0000 Subject: [PATCH] =?UTF-8?q?Add=20Hosted=20Tables=20integration=20=E2=80=94?= =?UTF-8?q?=20configurable=20site=20URL=20syncs=20to=20auth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registers hosted_tables in the integration schema with a single site_url config field. On save, syncHostedTables() PATCHes auth to update restaurant_bookings base_path and active state, so the portal app appears only when a URL is set. Co-Authored-By: Claude Sonnet 4.6 --- src/integrations/schema.js | 5 +++++ src/routes/integrations.js | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/integrations/schema.js b/src/integrations/schema.js index f7a5486..d1ff77c 100644 --- a/src/integrations/schema.js +++ b/src/integrations/schema.js @@ -37,6 +37,11 @@ export const INTEGRATIONS = { configFields: ['host', 'port', 'from', 'reply_to'], secretFields: ['user', 'pass'], }, + hosted_tables: { + name: 'Hosted Tables', + configFields: ['site_url'], + secretFields: [], + }, } export const MASKED = '••••••••' diff --git a/src/routes/integrations.js b/src/routes/integrations.js index 056a45e..63964ad 100644 --- a/src/routes/integrations.js +++ b/src/routes/integrations.js @@ -16,6 +16,17 @@ function bustAuthCache() { }).catch(() => {}) } +function syncHostedTables(siteUrl, enabled) { + const secret = process.env.SETTINGS_SECRET || '' + const active = enabled && siteUrl.trim().length > 0 + fetch(`${AUTH_URL}/api/auth/internal/apps/restaurant_bookings`, { + method: 'PATCH', + headers: { Authorization: `Bearer ${secret}`, 'Content-Type': 'application/json' }, + body: JSON.stringify({ base_path: siteUrl.trim() || '/bookings', active }), + signal: AbortSignal.timeout(5000), + }).catch(() => {}) +} + function decryptSecrets(row) { if (!row.secrets) return {} try { return JSON.parse(decrypt(row.secrets)) } catch { return {} } @@ -89,6 +100,7 @@ export async function integrationRoutes(app) { const { rows: [updated] } = await pool.query('SELECT * FROM integrations WHERE slug = $1', [slug]) if (slug === 'workforce' || slug === 'smtp') bustAuthCache() + if (slug === 'hosted_tables') syncHostedTables(config.site_url ?? '', enabled) return maskRow(updated) })