Spaces:
Build error
Build error
| import type { Router } from 'express'; | |
| import { supabase, tableMissing } from '../supabase.js'; | |
| interface RevenueStreamRecord { | |
| amount: number; | |
| status: string; | |
| metadata: Record<string, any> | null; | |
| } | |
| export function registerRiverRoutes(router: Router) { | |
| router.get('/river/tools', async (_req, res, next) => { | |
| try { | |
| const { data, error } = await supabase | |
| .from('river_tools') | |
| .select('*') | |
| .order('created_at', { ascending: false }); | |
| if (error && !tableMissing(error)) throw error; | |
| res.json({ tools: data ?? [] }); | |
| } catch (error) { | |
| next(error); | |
| } | |
| }); | |
| router.get('/river/analytics/:toolId', async (req, res, next) => { | |
| const { toolId } = req.params; | |
| try { | |
| const { data, error } = await supabase | |
| .from('river_tool_metrics') | |
| .select('*') | |
| .eq('tool_id', toolId) | |
| .order('recorded_at', { ascending: false }) | |
| .limit(1) | |
| .single(); | |
| if (!error && data) { | |
| return res.json({ toolId, ...data }); | |
| } | |
| if (error && !tableMissing(error)) { | |
| throw error; | |
| } | |
| // Fallback to aggregate revenue streams | |
| const { data: revenueData, error: revenueError } = await supabase | |
| .from('revenue_streams') | |
| .select('amount,status,metadata'); | |
| if (revenueError && !tableMissing(revenueError)) throw revenueError; | |
| const streams = (revenueData ?? []) as RevenueStreamRecord[]; | |
| const relevant = streams.filter(stream => { | |
| const meta = stream.metadata || {}; | |
| return meta.tool_id === toolId || meta.toolId === toolId; | |
| }); | |
| const revenue = relevant.reduce((sum, stream) => sum + (stream.status === 'confirmed' ? stream.amount : 0), 0); | |
| const conversions = relevant.length; | |
| res.json({ | |
| toolId, | |
| revenue, | |
| conversions, | |
| subscribers: conversions, // placeholder until distinct subscribers tracked | |
| mrr: revenue, | |
| timestamp: new Date().toISOString(), | |
| }); | |
| } catch (error) { | |
| next(error); | |
| } | |
| }); | |
| } | |