import { FilterState, TraceDomain } from "@langfuse/shared"; import { tracesTableUiColumnDefinitions } from "@langfuse/shared/src/server"; // Uses the uiTableId for mapping fields later. const evalTraceFilterColumns = [ "id", "bookmarked", "name", "environment", "timestamp", "userId", "sessionId", "metadata", "release", "version", "tags", ] as const; function getColumnDefinition(column: string) { const columnDef = tracesTableUiColumnDefinitions.find( (col) => col.uiTableId === column || col.uiTableName === column || col.clickhouseSelect === column, ); if (!columnDef) { throw new Error(`Unhandled column for trace filter: ${column}`); } return columnDef; } /** * Maps trace filter column names to trace object field values. * Uses the centralized table mapping to ensure consistency with UI column definitions. */ export function mapTraceFilterColumn( trace: TraceDomain, column: string, ): unknown { const columnDef = getColumnDefinition(column); switch (columnDef.uiTableId) { case "id": return trace.id; case "name": return trace.name; case "timestamp": return trace.timestamp; case "environment": return trace.environment; case "tags": return trace.tags; case "bookmarked": return trace.bookmarked; case "release": return trace.release; case "version": return trace.version; case "userId": return trace.userId; case "sessionId": return trace.sessionId; case "metadata": return trace.metadata; default: throw new Error(`Unhandled column in trace filter mapping: ${column}`); } } /** * Determines if a filter requires a database lookup. * We make the decision based on whether the filter only selects for allow-listed columns */ export function requiresDatabaseLookup(filter: FilterState): boolean { if (!filter || filter.length === 0) { return false; } for (const condition of filter) { if ( !evalTraceFilterColumns.some( (c) => c === getColumnDefinition(condition.column).uiTableId, ) ) { return true; } } return false; }