/** * Routes Catalog - Single source of truth for all API endpoints * Used by provider/consumer tests to validate route parity */ import { RoutesV2 } from '../routes/routesV2'; export const RoutesCatalog = [ // IG Adapter endpoints (Infra) { method: 'GET', path: RoutesV2.InfraHealth }, { method: 'GET', path: RoutesV2.IgAccounts }, { method: 'GET', path: RoutesV2.IgPositions }, { method: 'GET', path: RoutesV2.IgPortfolio }, // ML Service endpoints (ML) { method: 'GET', path: RoutesV2.MlHealth }, { method: 'GET', path: RoutesV2.MlModels }, { method: 'POST', path: RoutesV2.MlPredict }, { method: 'GET', path: RoutesV2.MlSignals }, { method: 'POST', path: RoutesV2.MlBacktest }, // System endpoints { method: 'GET', path: RoutesV2.Health }, // Portfolio endpoints { method: 'GET', path: RoutesV2.PortfolioSummary }, // Trading endpoints { method: 'GET', path: RoutesV2.TradesOpen }, { method: 'GET', path: RoutesV2.TradesClosed }, // Signal Query Routes { method: 'GET', path: RoutesV2.SignalsQuery }, // Wealth Routes { method: 'GET', path: RoutesV2.WealthHl }, // Data Access Routes (FE reads from Supabase views) { method: 'GET', path: RoutesV2.TradingAccounts }, ] as const; export type RouteEntry = typeof RoutesCatalog[number]; export type RouteMethod = RouteEntry['method']; export type RoutePath = RouteEntry['path']; /** * Helper to find routes by method or path */ export const findRoutes = { byMethod: (method: RouteMethod) => RoutesCatalog.filter(r => r.method === method), byPath: (path: RoutePath) => RoutesCatalog.filter(r => r.path === path), byPattern: (pattern: string) => RoutesCatalog.filter(r => r.path.includes(pattern)), }; /** * Validate if a given path/method combination is allowed */ export const isAllowedRoute = (method: string, path: string): boolean => { return RoutesCatalog.some(r => r.method === method && r.path === path); };