( requestId: string, tableId: string, validated: BatchInsertTableRowsBodyInput, userId: string, authType: AuthTypeValue | undefined )
| 37 | } |
| 38 | |
| 39 | async function handleBatchInsert( |
| 40 | requestId: string, |
| 41 | tableId: string, |
| 42 | validated: BatchInsertTableRowsBodyInput, |
| 43 | userId: string, |
| 44 | authType: AuthTypeValue | undefined |
| 45 | ): Promise<NextResponse> { |
| 46 | const accessResult = await checkAccess(tableId, userId, 'write') |
| 47 | if (!accessResult.ok) return accessError(accessResult, requestId, tableId) |
| 48 | |
| 49 | const { table } = accessResult |
| 50 | |
| 51 | if (validated.workspaceId !== table.workspaceId) { |
| 52 | logger.warn( |
| 53 | `[${requestId}] Workspace ID mismatch for table ${tableId}. Provided: ${validated.workspaceId}, Actual: ${table.workspaceId}` |
| 54 | ) |
| 55 | return NextResponse.json({ error: 'Invalid workspace ID' }, { status: 400 }) |
| 56 | } |
| 57 | |
| 58 | const wire = rowWireTranslators(authType, table.schema as TableSchema) |
| 59 | const rows = (validated.rows as RowData[]).map((row) => wire.dataIn(row)) |
| 60 | |
| 61 | // Validate rows before calling service (service also validates, but route-level |
| 62 | // validation returns structured HTTP responses) |
| 63 | const validation = await validateBatchRows({ |
| 64 | rows, |
| 65 | schema: table.schema as TableSchema, |
| 66 | tableId, |
| 67 | }) |
| 68 | if (!validation.valid) return validation.response |
| 69 | |
| 70 | try { |
| 71 | const insertedRows = await batchInsertRows( |
| 72 | { |
| 73 | tableId, |
| 74 | rows, |
| 75 | workspaceId: validated.workspaceId, |
| 76 | userId, |
| 77 | positions: validated.positions, |
| 78 | orderKeys: validated.orderKeys, |
| 79 | }, |
| 80 | table, |
| 81 | requestId |
| 82 | ) |
| 83 | |
| 84 | return NextResponse.json({ |
| 85 | success: true, |
| 86 | data: { |
| 87 | rows: insertedRows.map((r) => ({ |
| 88 | id: r.id, |
| 89 | data: wire.dataOut(r.data), |
| 90 | position: r.position, |
| 91 | orderKey: r.orderKey ?? undefined, |
| 92 | createdAt: r.createdAt instanceof Date ? r.createdAt.toISOString() : r.createdAt, |
| 93 | updatedAt: r.updatedAt instanceof Date ? r.updatedAt.toISOString() : r.updatedAt, |
| 94 | })), |
| 95 | insertedCount: insertedRows.length, |
| 96 | message: `Successfully inserted ${insertedRows.length} rows`, |
no test coverage detected