@@ -6,7 +6,9 @@ import { and, eq, sql } from 'drizzle-orm'
66import { type NextRequest , NextResponse } from 'next/server'
77import { v1ListLogsContract } from '@/lib/api/contracts/v1/logs'
88import { getValidationErrorMessage , parseRequest } from '@/lib/api/server'
9+ import { MATERIALIZE_CONCURRENCY , mapWithConcurrency } from '@/lib/core/utils/concurrency'
910import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
11+ import { materializeExecutionData } from '@/lib/logs/execution/trace-store'
1012import { buildLogFilters , getOrderBy } from '@/app/api/v1/logs/filters'
1113import { createApiResponse , getUserLimits } from '@/app/api/v1/logs/meta'
1214import {
@@ -103,14 +105,15 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
103105 . select ( {
104106 id : workflowExecutionLogs . id ,
105107 workflowId : workflowExecutionLogs . workflowId ,
108+ workspaceId : workflowExecutionLogs . workspaceId ,
106109 executionId : workflowExecutionLogs . executionId ,
107110 deploymentVersionId : workflowExecutionLogs . deploymentVersionId ,
108111 level : workflowExecutionLogs . level ,
109112 trigger : workflowExecutionLogs . trigger ,
110113 startedAt : workflowExecutionLogs . startedAt ,
111114 endedAt : workflowExecutionLogs . endedAt ,
112115 totalDurationMs : workflowExecutionLogs . totalDurationMs ,
113- cost : workflowExecutionLogs . cost ,
116+ costTotal : workflowExecutionLogs . costTotal ,
114117 files : workflowExecutionLogs . files ,
115118 executionData : params . details === 'full' ? workflowExecutionLogs . executionData : sql `null` ,
116119 workflowName : workflow . name ,
@@ -144,7 +147,12 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
144147 } )
145148 }
146149
147- const formattedLogs = data . map ( ( log ) => {
150+ // Only materialize externalized execution data when the response actually
151+ // needs it (details=full + finalOutput/traceSpans requested).
152+ const needsMaterialize =
153+ params . details === 'full' && ( params . includeFinalOutput || params . includeTraceSpans )
154+
155+ const formattedLogs = await mapWithConcurrency ( data , MATERIALIZE_CONCURRENCY , async ( log ) => {
148156 const result : any = {
149157 id : log . id ,
150158 workflowId : log . workflowId ,
@@ -155,7 +163,7 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
155163 startedAt : log . startedAt . toISOString ( ) ,
156164 endedAt : log . endedAt ?. toISOString ( ) || null ,
157165 totalDurationMs : log . totalDurationMs ,
158- cost : log . cost ? { total : ( log . cost as any ) . total } : null ,
166+ cost : log . costTotal != null ? { total : Number ( log . costTotal ) } : null ,
159167 files : log . files || null ,
160168 }
161169
@@ -167,12 +175,15 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
167175 deleted : ! log . workflowName ,
168176 }
169177
170- if ( log . cost ) {
171- result . cost = log . cost
172- }
173-
174- if ( log . executionData ) {
175- const execData = log . executionData as any
178+ if ( needsMaterialize && log . executionData ) {
179+ const execData = ( await materializeExecutionData (
180+ log . executionData as Record < string , unknown > | null ,
181+ {
182+ workspaceId : log . workspaceId ,
183+ workflowId : log . workflowId ,
184+ executionId : log . executionId ,
185+ }
186+ ) ) as any
176187 if ( params . includeFinalOutput && execData . finalOutput ) {
177188 result . finalOutput = execData . finalOutput
178189 }
0 commit comments