diff --git a/src/db.js b/src/db.js index e67fc0a..462d21f 100644 --- a/src/db.js +++ b/src/db.js @@ -138,6 +138,14 @@ export async function initDb() { internal_port = EXCLUDED.internal_port `) + // Seed restaurant_bookings app — inactive until settings configures the Hosted Tables URL. + // ON CONFLICT DO NOTHING so restarts never reset base_path/active managed by settings. + await pool.query(` + INSERT INTO apps (slug, name, description, base_path, icon, theme_color, category, active) + VALUES ('restaurant_bookings', 'Table Bookings', 'Hosted table reservation system', '/bookings', 'UtensilsCrossed', '#1a1a2e', 'Restaurant', FALSE) + ON CONFLICT (slug) DO NOTHING + `) + // Seed default Staff role await pool.query(` INSERT INTO roles (name, slug, description, is_default) diff --git a/src/routes/internal.js b/src/routes/internal.js index 0f49183..8138363 100644 --- a/src/routes/internal.js +++ b/src/routes/internal.js @@ -45,4 +45,23 @@ export async function internalRoutes(app) { invalidateSmtpCache() return { ok: true } }) + + // Called by settings after saving the hosted_tables integration + app.patch('/apps/:slug', async (request, reply) => { + if (!isSettingsAuthorised(request)) return reply.status(401).send({ error: 'Unauthorized' }) + const { slug } = request.params + const { base_path, active } = request.body || {} + if (base_path === undefined && active === undefined) return reply.status(400).send({ error: 'Nothing to update' }) + const sets = [] + const vals = [] + if (base_path !== undefined) { sets.push(`base_path = $${vals.push(base_path)}`); } + if (active !== undefined) { sets.push(`active = $${vals.push(Boolean(active))}`); } + vals.push(slug) + const { rowCount } = await pool.query( + `UPDATE apps SET ${sets.join(', ')} WHERE slug = $${vals.length}`, + vals + ) + if (rowCount === 0) return reply.status(404).send({ error: 'App not found' }) + return { ok: true } + }) }