Spaces:
Build error
Build error
| import type { Router } from 'express'; | |
| import { supabase, tableMissing } from '../supabase.js'; | |
| const FLOW_EXECUTOR = process.env.SUPABASE_FLOW_EXECUTOR || 'flow-executor'; | |
| export function registerFlowRoutes(router: Router) { | |
| router.get('/flows', async (req, res, next) => { | |
| const { status, type } = req.query; | |
| try { | |
| let query = supabase.from('flows').select('*').order('created_at', { ascending: false }); | |
| if (status && typeof status === 'string') { | |
| query = query.eq('status', status); | |
| } | |
| if (type && typeof type === 'string') { | |
| query = query.eq('type', type); | |
| } | |
| const { data, error } = await query; | |
| if (error && !tableMissing(error)) throw error; | |
| res.json({ flows: data ?? [] }); | |
| } catch (error) { | |
| next(error); | |
| } | |
| }); | |
| router.post('/flows/:id/execute', async (req, res, next) => { | |
| const { id } = req.params; | |
| try { | |
| const { data, error } = await supabase.functions.invoke(FLOW_EXECUTOR, { | |
| body: { flowId: id, parameters: req.body?.parameters ?? {} }, | |
| }); | |
| if (error) { | |
| // bubble up but mark accepted so caller can inspect details | |
| return res.status(502).json({ success: false, error: error.message }); | |
| } | |
| res.status(202).json({ success: true, response: data }); | |
| } catch (error) { | |
| next(error); | |
| } | |
| }); | |
| router.post('/flows/:id/publish', async (req, res, next) => { | |
| const { id } = req.params; | |
| try { | |
| const { data, error } = await supabase | |
| .from('flows') | |
| .update({ status: 'live', published_at: new Date().toISOString() }) | |
| .eq('id', id) | |
| .select() | |
| .single(); | |
| if (error) throw error; | |
| res.json({ success: true, flow: data }); | |
| } catch (error) { | |
| next(error); | |
| } | |
| }); | |
| router.post('/flows/:id/duplicate', async (req, res, next) => { | |
| const { id } = req.params; | |
| try { | |
| const { data: original, error: fetchError } = await supabase | |
| .from('flows') | |
| .select('*') | |
| .eq('id', id) | |
| .single(); | |
| if (fetchError) throw fetchError; | |
| const payload = { | |
| ...original, | |
| id: undefined, | |
| name: `${original.name} Copy`, | |
| status: 'draft', | |
| created_at: undefined, | |
| updated_at: undefined, | |
| published_at: null, | |
| last_run_at: null, | |
| }; | |
| const { data: inserted, error: insertError } = await supabase | |
| .from('flows') | |
| .insert(payload) | |
| .select() | |
| .single(); | |
| if (insertError) throw insertError; | |
| res.json({ success: true, flow: inserted }); | |
| } catch (error) { | |
| next(error); | |
| } | |
| }); | |
| router.post('/flows/:id/archive', async (req, res, next) => { | |
| const { id } = req.params; | |
| try { | |
| const { data, error } = await supabase | |
| .from('flows') | |
| .update({ status: 'archived', archived_at: new Date().toISOString() }) | |
| .eq('id', id) | |
| .select() | |
| .single(); | |
| if (error) throw error; | |
| res.json({ success: true, flow: data }); | |
| } catch (error) { | |
| next(error); | |
| } | |
| }); | |
| } | |