@@ -197,6 +197,35 @@ const countStagedReferences = async (table, snakeFkField, recordId, matchPredica
197197 return count ;
198198} ;
199199
200+ const countStagedReferencesForIds = async ( table , snakeFkField , recordIds ) => {
201+ const recordIdSet = new Set ( recordIds ) ;
202+ const stagedRows = await StagingV2 . findAll ( {
203+ where : {
204+ table,
205+ action : { [ Op . in ] : [ 'INSERT' , 'UPDATE' ] } ,
206+ committed : false ,
207+ failed_commit : false ,
208+ } ,
209+ raw : true ,
210+ } ) ;
211+
212+ let count = 0 ;
213+ for ( const stagedRow of stagedRows ) {
214+ try {
215+ const parsedData = JSON . parse ( stagedRow . data ) ;
216+ const records = Array . isArray ( parsedData ) ? parsedData : [ parsedData ] ;
217+ for ( const record of records ) {
218+ if ( recordIdSet . has ( record ?. [ snakeFkField ] ) ) {
219+ count += 1 ;
220+ }
221+ }
222+ } catch {
223+ continue ;
224+ }
225+ }
226+ return count ;
227+ } ;
228+
200229const findPendingStagedDeleteIds = async ( table , primaryKeyField ) => {
201230 const stagedRows = await StagingV2 . findAll ( {
202231 where : {
@@ -270,6 +299,42 @@ export const checkReferences = async (table, recordId) => {
270299 } ;
271300} ;
272301
302+ export const checkUnitReferencesForIds = async ( unitIds ) => {
303+ const recordIds = unitIds . filter ( Boolean ) ;
304+ if ( recordIds . length === 0 ) {
305+ return { hasReferences : false , references : [ ] } ;
306+ }
307+
308+ const definitions = REFERENCE_MAP . unit ;
309+ const references = [ ] ;
310+
311+ for ( const def of definitions ) {
312+ const { model, fkField, table : refTable , label } = def ;
313+ const primaryKeyAttr = model . primaryKeyAttribute ;
314+ const primaryKeyField = getV2PrimaryKeyField ( refTable ) || toSnakeCase ( primaryKeyAttr ) ;
315+ const pendingDeleteIds = await findPendingStagedDeleteIds ( refTable , primaryKeyField ) ;
316+ const mainRecords = await model . findAll ( {
317+ where : { [ fkField ] : { [ Op . in ] : recordIds } } ,
318+ raw : true ,
319+ } ) ;
320+ const mainCount = mainRecords . filter ( ( row ) => {
321+ const rowId = row ?. [ primaryKeyAttr ] ?? row ?. [ primaryKeyField ] ;
322+ return ! pendingDeleteIds . has ( rowId ) ;
323+ } ) . length ;
324+
325+ const stagedCount = await countStagedReferencesForIds ( refTable , toSnakeCase ( fkField ) , recordIds ) ;
326+ const totalCount = mainCount + stagedCount ;
327+ if ( totalCount > 0 ) {
328+ references . push ( { table : refTable , count : totalCount , label } ) ;
329+ }
330+ }
331+
332+ return {
333+ hasReferences : references . length > 0 ,
334+ references,
335+ } ;
336+ } ;
337+
273338/**
274339 * Build a 409 response body from a reference check result.
275340 *
0 commit comments