@@ -137,9 +137,10 @@ export async function copyForkResourceContainers(
137137 eq ( customTools . workspaceId , sourceWorkspaceId )
138138 )
139139 )
140+ const inserts : ( typeof customTools . $inferInsert ) [ ] = [ ]
140141 for ( const row of rows ) {
141142 const childId = generateId ( )
142- await tx . insert ( customTools ) . values ( {
143+ inserts . push ( {
143144 ...row ,
144145 id : childId ,
145146 workspaceId : childWorkspaceId ,
@@ -150,16 +151,18 @@ export async function copyForkResourceContainers(
150151 record ( 'custom_tool' , row . id , childId )
151152 names . customTools . push ( row . title )
152153 }
154+ if ( inserts . length > 0 ) await tx . insert ( customTools ) . values ( inserts )
153155 }
154156
155157 if ( selection . skills . length > 0 ) {
156158 const rows = await tx
157159 . select ( )
158160 . from ( skill )
159161 . where ( and ( inArray ( skill . id , selection . skills ) , eq ( skill . workspaceId , sourceWorkspaceId ) ) )
162+ const inserts : ( typeof skill . $inferInsert ) [ ] = [ ]
160163 for ( const row of rows ) {
161164 const childId = generateId ( )
162- await tx . insert ( skill ) . values ( {
165+ inserts . push ( {
163166 ...row ,
164167 id : childId ,
165168 workspaceId : childWorkspaceId ,
@@ -170,6 +173,7 @@ export async function copyForkResourceContainers(
170173 record ( 'skill' , row . id , childId )
171174 names . skills . push ( row . name )
172175 }
176+ if ( inserts . length > 0 ) await tx . insert ( skill ) . values ( inserts )
173177 }
174178
175179 if ( selection . mcpServers . length > 0 ) {
@@ -186,32 +190,34 @@ export async function copyForkResourceContainers(
186190 // `generateMcpServerId` is deterministic on (workspace, url), so two selected
187191 // servers with the same normalized URL derive the same child id. Insert once
188192 // and map both source ids to the surviving child rather than aborting the fork.
189- const insertedMcpIds = new Set < string > ( )
193+ const insertsByChildId = new Map < string , typeof mcpServers . $inferInsert > ( )
190194 for ( const row of rows ) {
191195 const childId = row . url ? generateMcpServerId ( childWorkspaceId , row . url ) : generateId ( )
192196 record ( 'mcp_server' , row . id , childId )
193- if ( insertedMcpIds . has ( childId ) ) continue
194- insertedMcpIds . add ( childId )
197+ if ( insertsByChildId . has ( childId ) ) continue
195198 names . mcpServers . push ( row . name )
199+ insertsByChildId . set ( childId , {
200+ ...row ,
201+ id : childId ,
202+ workspaceId : childWorkspaceId ,
203+ createdBy : userId ,
204+ // Secrets are never copied across workspaces: drop the registered OAuth
205+ // client + any auth headers so the child re-authenticates from scratch.
206+ oauthClientId : null ,
207+ oauthClientSecret : null ,
208+ headers : { } ,
209+ connectionStatus : 'disconnected' ,
210+ lastConnected : null ,
211+ lastError : null ,
212+ deletedAt : null ,
213+ createdAt : now ,
214+ updatedAt : now ,
215+ } )
216+ }
217+ if ( insertsByChildId . size > 0 ) {
196218 await tx
197219 . insert ( mcpServers )
198- . values ( {
199- ...row ,
200- id : childId ,
201- workspaceId : childWorkspaceId ,
202- createdBy : userId ,
203- // Secrets are never copied across workspaces: drop the registered OAuth
204- // client + any auth headers so the child re-authenticates from scratch.
205- oauthClientId : null ,
206- oauthClientSecret : null ,
207- headers : { } ,
208- connectionStatus : 'disconnected' ,
209- lastConnected : null ,
210- lastError : null ,
211- deletedAt : null ,
212- createdAt : now ,
213- updatedAt : now ,
214- } )
220+ . values ( [ ...insertsByChildId . values ( ) ] )
215221 . onConflictDoNothing ( )
216222 }
217223 }
@@ -227,13 +233,14 @@ export async function copyForkResourceContainers(
227233 isNull ( userTableDefinitions . archivedAt )
228234 )
229235 )
236+ const inserts : ( typeof userTableDefinitions . $inferInsert ) [ ] = [ ]
230237 for ( const definition of definitions ) {
231238 const childTableId = generateId ( )
232239 const remappedSchema = remapForkTableWorkflowGroups (
233240 definition . schema as TableSchema ,
234241 workflowIdMap
235242 )
236- await tx . insert ( userTableDefinitions ) . values ( {
243+ inserts . push ( {
237244 ...definition ,
238245 id : childTableId ,
239246 workspaceId : childWorkspaceId ,
@@ -251,6 +258,7 @@ export async function copyForkResourceContainers(
251258 contentPlan . tables . push ( { sourceId : definition . id , childId : childTableId } )
252259 names . tables . push ( definition . name )
253260 }
261+ if ( inserts . length > 0 ) await tx . insert ( userTableDefinitions ) . values ( inserts )
254262 }
255263
256264 if ( selection . knowledgeBases . length > 0 ) {
@@ -264,9 +272,10 @@ export async function copyForkResourceContainers(
264272 isNull ( knowledgeBase . deletedAt )
265273 )
266274 )
275+ const inserts : ( typeof knowledgeBase . $inferInsert ) [ ] = [ ]
267276 for ( const base of bases ) {
268277 const childKbId = generateId ( )
269- await tx . insert ( knowledgeBase ) . values ( {
278+ inserts . push ( {
270279 ...base ,
271280 id : childKbId ,
272281 workspaceId : childWorkspaceId ,
@@ -279,6 +288,7 @@ export async function copyForkResourceContainers(
279288 contentPlan . knowledgeBases . push ( { sourceId : base . id , childId : childKbId } )
280289 names . knowledgeBases . push ( base . name )
281290 }
291+ if ( inserts . length > 0 ) await tx . insert ( knowledgeBase ) . values ( inserts )
282292 }
283293
284294 return { idMap, mappingEntries, contentPlan, names }
0 commit comments