diff --git a/data/survey_mappings.db-shm b/data/survey_mappings.db-shm index 28f666b..fe9ac28 100644 Binary files a/data/survey_mappings.db-shm and b/data/survey_mappings.db-shm differ diff --git a/data/survey_mappings.db-wal b/data/survey_mappings.db-wal index 981b147..e69de29 100644 Binary files a/data/survey_mappings.db-wal and b/data/survey_mappings.db-wal differ diff --git a/src/routes/admin.js b/src/routes/admin.js index 84a471a..636e83e 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -6,10 +6,20 @@ const { updateEnvironmentAlias, getSurveysByEnvironment, updateSurveySlug, + refreshSurveyCache, } = require("../services/formbricks"); router.use(ensureAdminToken); +router.post("/sync", async (req, res) => { + try { + await refreshSurveyCache(); + res.json({ status: "ok", message: "Surveys synced successfully" }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + router.get("/environments", (req, res) => { try { const environments = getAllEnvironments(); diff --git a/src/server.js b/src/server.js index 1412f2e..748fa16 100644 --- a/src/server.js +++ b/src/server.js @@ -1,55 +1,55 @@ -require('dotenv').config(); -const express = require('express'); -const path = require('path'); -const surveyRoutes = require('./routes/surveys'); -const adminRoutes = require('./routes/admin'); -const { refreshSurveyCache } = require('./services/formbricks'); +require("dotenv").config(); +const express = require("express"); +const path = require("path"); +const surveyRoutes = require("./routes/surveys"); +const adminRoutes = require("./routes/admin"); +const { refreshSurveyCache } = require("./services/formbricks"); const app = express(); const PORT = process.env.PORT || 3011; // Template Engine Setup -app.set('view engine', 'ejs'); -app.set('views', path.join(__dirname, 'views')); +app.set("view engine", "ejs"); +app.set("views", path.join(__dirname, "views")); // Middleware app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Health check endpoint -app.get('/health', (req, res) => { - res.status(200).json({ status: 'ok' }); +app.get("/health", (req, res) => { + res.status(200).json({ status: "ok" }); }); // Root landing page -app.get('/', (req, res) => { - res.render('index', { - title: 'Formbricks Survey Portal' +app.get("/", (req, res) => { + res.render("index", { + title: "Formbricks Survey Portal", }); }); // Admin UI -app.get('/admin', (req, res) => { - res.render('admin', { - title: 'Admin - Formbricks Vanity' +app.get("/admin", (req, res) => { + res.render("admin", { + title: "Admin - Formbricks Vanity", }); }); // Admin API routes -app.use('/api/mappings', adminRoutes); +app.use("/api/mappings", adminRoutes); // Main survey routes (catch-all for vanity URLs) -app.use('/', surveyRoutes); +app.use("/", surveyRoutes); // Handle 404 for any other route app.use((req, res, next) => { - res.status(404).send('Sorry, that page does not exist.'); + res.status(404).send("Sorry, that page does not exist."); }); // Global error handler app.use((err, req, res, next) => { console.error(err.stack); - res.status(500).send('Something broke!'); + res.status(500).send("Something broke!"); }); // Initialize the survey cache at startup @@ -59,7 +59,15 @@ refreshSurveyCache() console.log(`Server is running at http://localhost:${PORT}`); }); }) - .catch(error => { - console.error('Failed to initialize Formbricks survey cache. Please check API key and connection.', error); - process.exit(1); // Exit if we can't load the initial surveys + .catch((error) => { + console.error( + "Failed to initialize Formbricks survey cache. Please check API key and connection.", + error.message + ); + // process.exit(1); // Don't exit, allow the server to start even if sync fails + app.listen(PORT, () => { + console.log( + `Server is running at http://localhost:${PORT} (Survey sync failed)` + ); + }); }); diff --git a/src/services/formbricks.js b/src/services/formbricks.js index cea439b..2dbafe0 100644 --- a/src/services/formbricks.js +++ b/src/services/formbricks.js @@ -64,6 +64,7 @@ async function fetchSurveysFromAPI() { headers: { "x-api-key": process.env.FORMBRICKS_API_KEY, }, + timeout: 15000, // 15 seconds timeout } ); @@ -108,6 +109,7 @@ async function refreshSurveyCache() { console.log(`Successfully synced ${synced} surveys into the database.`); } catch (error) { console.error("Failed to refresh survey cache:", error.message); + throw error; // Re-throw so server.js knows initialization failed } } diff --git a/src/views/admin.ejs b/src/views/admin.ejs index 8f3e7af..75e9403 100644 --- a/src/views/admin.ejs +++ b/src/views/admin.ejs @@ -1,365 +1,386 @@ - - - + + + <%= title %> - - - + + + - - + +
-

Admin Authentication

-

Enter your Admin Token to manage surveys.

-
- -
- +

Admin Authentication

+

+ Enter your Admin Token to manage surveys. +

+
+ +
+