hAPI_face2 / src /routes /flows.ts
deploy's picture
Deploy hAPI-face2 mediator 2025-10-07T05:24:34Z
5816640
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);
}
});
}