From fde35234133652abc31c93b737008b71899f8621 Mon Sep 17 00:00:00 2001 From: sirpiglr <49359077-sirpiglr@users.noreply.replit.com> Date: Mon, 15 Dec 2025 22:03:00 +0000 Subject: [PATCH] Add endpoints to explore database schema and retrieve table data Initialize Supabase client with environment variables and register new API routes for schema exploration, table testing, and sample data retrieval. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 279f1558-c0e3-40e4-8217-be7e9f4c6eca Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 6cc03e4b-31f5-4d57-a340-17091c2752be Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/b984cb14-1d19-4944-922b-bc79e821ed35/279f1558-c0e3-40e4-8217-be7e9f4c6eca/2riq6Ir Replit-Helium-Checkpoint-Created: true --- server/routes.ts | 86 +++++++++++++++++++++++++++++++++++++++++++--- server/supabase.ts | 10 ++++++ 2 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 server/supabase.ts diff --git a/server/routes.ts b/server/routes.ts index ae68e01..5839775 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -1,16 +1,94 @@ import type { Express } from "express"; import { createServer, type Server } from "http"; import { storage } from "./storage"; +import { supabase } from "./supabase"; export async function registerRoutes( httpServer: Server, app: Express ): Promise { - // put application routes here - // prefix all routes with /api + + // API: Explore database schema (temporary - for development) + app.get("/api/schema", async (req, res) => { + try { + // Query information_schema to get all tables + const { data, error } = await supabase + .from('information_schema.tables') + .select('table_name') + .eq('table_schema', 'public'); + + if (error) { + // Alternative: try querying a known table or use RPC + // Let's try to get tables via a different approach + const tablesQuery = await supabase.rpc('get_tables'); + if (tablesQuery.error) { + return res.json({ + error: error.message, + hint: "Could not query schema. Tables may need to be accessed directly.", + supabaseConnected: true + }); + } + return res.json({ tables: tablesQuery.data }); + } + + res.json({ tables: data }); + } catch (err: any) { + res.status(500).json({ error: err.message }); + } + }); - // use storage to perform CRUD operations on the storage interface - // e.g. storage.insertUser(user) or storage.getUserByUsername(username) + // API: Test specific tables that might exist + app.get("/api/explore", async (req, res) => { + const potentialTables = [ + 'users', 'architects', 'profiles', 'credentials', 'certificates', + 'skills', 'curriculum', 'courses', 'modules', 'lessons', + 'threats', 'events', 'logs', 'projects', 'teams', + 'organizations', 'members', 'enrollments', 'progress' + ]; + + const results: Record = {}; + + for (const table of potentialTables) { + try { + const { data, error, count } = await supabase + .from(table) + .select('*', { count: 'exact', head: true }); + + if (!error) { + results[table] = { exists: true, count }; + } + } catch (e) { + // Table doesn't exist, skip + } + } + + res.json({ + foundTables: Object.keys(results), + details: results, + supabaseUrl: process.env.SUPABASE_URL ? 'configured' : 'missing' + }); + }); + + // API: Get sample data from a specific table + app.get("/api/table/:name", async (req, res) => { + const { name } = req.params; + const limit = parseInt(req.query.limit as string) || 10; + + try { + const { data, error, count } = await supabase + .from(name) + .select('*', { count: 'exact' }) + .limit(limit); + + if (error) { + return res.status(400).json({ error: error.message }); + } + + res.json({ table: name, count, sample: data }); + } catch (err: any) { + res.status(500).json({ error: err.message }); + } + }); return httpServer; } diff --git a/server/supabase.ts b/server/supabase.ts new file mode 100644 index 0000000..54d423c --- /dev/null +++ b/server/supabase.ts @@ -0,0 +1,10 @@ +import { createClient } from '@supabase/supabase-js'; + +const supabaseUrl = process.env.SUPABASE_URL; +const supabaseKey = process.env.SUPABASE_ANON_KEY; + +if (!supabaseUrl || !supabaseKey) { + throw new Error('Missing SUPABASE_URL or SUPABASE_ANON_KEY environment variables'); +} + +export const supabase = createClient(supabaseUrl, supabaseKey);