1- import { db } from '@sim/db'
2- import { tableRowExecutions , userTableRows } from '@sim/db/schema'
31import { createLogger } from '@sim/logger'
42import { toError } from '@sim/utils/errors'
5- import { and , eq , inArray , sql } from 'drizzle-orm'
63import { type NextRequest , NextResponse } from 'next/server'
74import {
85 type BatchInsertTableRowsBodyInput ,
@@ -17,27 +14,20 @@ import { isZodError, validationErrorResponse } from '@/lib/api/server/validation
1714import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
1815import { generateRequestId } from '@/lib/core/utils/request'
1916import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
20- import type {
21- Filter ,
22- RowData ,
23- RowExecutionMetadata ,
24- RowExecutions ,
25- Sort ,
26- TableSchema ,
27- } from '@/lib/table'
17+ import type { Filter , RowData , Sort , TableSchema } from '@/lib/table'
2818import {
2919 batchInsertRows ,
3020 batchUpdateRows ,
3121 deleteRowsByFilter ,
3222 deleteRowsByIds ,
3323 insertRow ,
34- USER_TABLE_ROWS_SQL_NAME ,
3524 updateRowsByFilter ,
3625 validateBatchRows ,
3726 validateRowData ,
3827 validateRowSize ,
3928} from '@/lib/table'
40- import { buildFilterClause , buildSortClause , TableQueryValidationError } from '@/lib/table/sql'
29+ import { TableQueryValidationError } from '@/lib/table/sql'
30+ import { queryRows } from '@/lib/table/table-wrapper'
4131import { accessError , checkAccess } from '@/app/api/table/utils'
4232
4333const logger = createLogger ( 'TableRowsAPI' )
@@ -268,113 +258,35 @@ export const GET = withRouteHandler(
268258 return NextResponse . json ( { error : 'Invalid workspace ID' } , { status : 400 } )
269259 }
270260
271- const baseConditions = [
272- eq ( userTableRows . tableId , tableId ) ,
273- eq ( userTableRows . workspaceId , validated . workspaceId ) ,
274- ]
275-
276- const schema = table . schema as TableSchema
277-
278- if ( validated . filter ) {
279- const filterClause = buildFilterClause (
280- validated . filter as Filter ,
281- USER_TABLE_ROWS_SQL_NAME ,
282- schema . columns
283- )
284- if ( filterClause ) {
285- baseConditions . push ( filterClause )
286- }
287- }
288-
289- let query = db
290- . select ( {
291- id : userTableRows . id ,
292- data : userTableRows . data ,
293- position : userTableRows . position ,
294- createdAt : userTableRows . createdAt ,
295- updatedAt : userTableRows . updatedAt ,
296- } )
297- . from ( userTableRows )
298- . where ( and ( ...baseConditions ) )
299-
300- if ( validated . sort ) {
301- const sortClause = buildSortClause ( validated . sort , USER_TABLE_ROWS_SQL_NAME , schema . columns )
302- if ( sortClause ) {
303- query = query . orderBy ( sortClause ) as typeof query
304- } else {
305- query = query . orderBy ( userTableRows . position ) as typeof query
306- }
307- } else {
308- query = query . orderBy ( userTableRows . position ) as typeof query
309- }
310-
311- let totalCount : number | null = null
312- if ( validated . includeTotal ) {
313- const [ { count } ] = await db
314- . select ( { count : sql < number > `count(*)` } )
315- . from ( userTableRows )
316- . where ( and ( ...baseConditions ) )
317- totalCount = Number ( count )
318- }
319-
320- const rows = await query . limit ( validated . limit ) . offset ( validated . offset )
321-
322- // Sidecar: fetch per-(row, group) execution state and group into a map
323- // so the response preserves the legacy `row.executions[groupId]` wire
324- // shape. One indexed-IN scan against table_row_executions.
325- const executionsByRow = new Map < string , RowExecutions > ( )
326- if ( rows . length > 0 ) {
327- const execRows = await db
328- . select ( )
329- . from ( tableRowExecutions )
330- . where (
331- inArray (
332- tableRowExecutions . rowId ,
333- rows . map ( ( r ) => r . id )
334- )
335- )
336- for ( const e of execRows ) {
337- const existing = executionsByRow . get ( e . rowId ) ?? { }
338- const meta : RowExecutionMetadata = {
339- status : e . status as RowExecutionMetadata [ 'status' ] ,
340- executionId : e . executionId ?? null ,
341- jobId : e . jobId ?? null ,
342- workflowId : e . workflowId ,
343- error : e . error ?? null ,
344- ...( e . runningBlockIds && e . runningBlockIds . length > 0
345- ? { runningBlockIds : e . runningBlockIds }
346- : { } ) ,
347- ...( e . blockErrors && Object . keys ( e . blockErrors as Record < string , string > ) . length > 0
348- ? { blockErrors : e . blockErrors as Record < string , string > }
349- : { } ) ,
350- ...( e . cancelledAt ? { cancelledAt : e . cancelledAt . toISOString ( ) } : { } ) ,
351- }
352- existing [ e . groupId ] = meta
353- executionsByRow . set ( e . rowId , existing )
354- }
355- }
261+ const result = await queryRows ( table , {
262+ filter : validated . filter as Filter | undefined ,
263+ sort : validated . sort ,
264+ limit : validated . limit ,
265+ offset : validated . offset ,
266+ includeTotal : validated . includeTotal ,
267+ } )
356268
357269 logger . info (
358- `[${ requestId } ] Queried ${ rows . length } rows from table ${ tableId } (total: ${ totalCount ?? 'n/a' } )`
270+ `[${ requestId } ] Queried ${ result . rowCount } rows from table ${ tableId } (total: ${ result . totalCount ?? 'n/a' } )`
359271 )
360272
361273 return NextResponse . json ( {
362274 success : true ,
363275 data : {
364- rows : rows . map ( ( r ) => ( {
276+ rows : result . rows . map ( ( r ) => ( {
365277 id : r . id ,
366278 data : r . data ,
367- executions : executionsByRow . get ( r . id ) ?? { } ,
279+ executions : r . executions ,
368280 position : r . position ,
369281 createdAt :
370282 r . createdAt instanceof Date ? r . createdAt . toISOString ( ) : String ( r . createdAt ) ,
371283 updatedAt :
372284 r . updatedAt instanceof Date ? r . updatedAt . toISOString ( ) : String ( r . updatedAt ) ,
373285 } ) ) ,
374- rowCount : rows . length ,
375- totalCount,
376- limit : validated . limit ,
377- offset : validated . offset ,
286+ rowCount : result . rowCount ,
287+ totalCount : result . totalCount ,
288+ limit : result . limit ,
289+ offset : result . offset ,
378290 } ,
379291 } )
380292 } catch ( error ) {
0 commit comments