@@ -11,7 +11,7 @@ import type {
1111 LinearRegressionResults ,
1212 UploadInstrumentRecordsData
1313} from '@opendatacapture/schemas/instrument-records' ;
14- import type { InstrumentRecordModel , Prisma , SessionModel } from '@prisma/generated-client' ;
14+ import { type InstrumentRecordModel , Prisma , type SessionModel } from '@prisma/generated-client' ;
1515import { isNumber , pickBy } from 'lodash-es' ;
1616
1717import { accessibleQuery } from '@/ability/ability.utils' ;
@@ -274,91 +274,84 @@ export class InstrumentRecordsService {
274274 ) ;
275275 }
276276
277- const createdRecordsArray : InstrumentRecordModel [ ] = [ ] ;
278277 const createdSessionsArray : SessionModel [ ] = [ ] ;
279278
280279 try {
281- for ( let i = 0 ; i < records . length ; i ++ ) {
282- const { data : rawData , date , subjectId } = records [ i ] ! ;
283- await this . createSubjectIfNotFound ( subjectId ) ;
284-
285- const session = await this . sessionsService . create ( {
286- date : date ,
287- groupId : groupId ? groupId : null ,
288- subjectData : {
289- id : subjectId
290- } ,
291- type : 'RETROSPECTIVE'
292- } ) ;
280+ const preProcessedRecords = await Promise . all (
281+ records . map ( async ( record ) => {
282+ const { data : rawData , date , subjectId } = record ;
283+
284+ // Validate data
285+ const parseResult = instrument . validationSchema . safeParse ( this . parseJson ( rawData ) ) ;
286+ if ( ! parseResult . success ) {
287+ console . error ( parseResult . error . issues ) ;
288+ throw new UnprocessableEntityException (
289+ `Data received for record does not pass validation schema of instrument ' ${ instrument . id } '`
290+ ) ;
291+ }
293292
294- createdSessionsArray . push ( session ) ;
293+ // Ensure subject exists
294+ await this . createSubjectIfNotFound ( subjectId ) ;
295295
296- const sessionId = session . id ;
296+ const session = await this . sessionsService . create ( {
297+ date : date ,
298+ groupId : groupId ?? null ,
299+ subjectData : { id : subjectId } ,
300+ type : 'RETROSPECTIVE'
301+ } ) ;
297302
298- const parseResult = instrument . validationSchema . safeParse ( this . parseJson ( rawData ) ) ;
299- if ( ! parseResult . success ) {
300- console . error ( parseResult . error . issues ) ;
301- throw new UnprocessableEntityException (
302- `Data received for record at index '${ i } ' does not pass validation schema of instrument '${ instrument . id } '`
303- ) ;
304- }
303+ createdSessionsArray . push ( session ) ;
305304
306- const createdRecord = await this . instrumentRecordModel . create ( {
307- data : {
308- computedMeasures : instrument . measures
309- ? this . instrumentMeasuresService . computeMeasures ( instrument . measures , parseResult . data )
310- : null ,
305+ const computedMeasures = instrument . measures
306+ ? this . instrumentMeasuresService . computeMeasures ( instrument . measures , parseResult . data )
307+ : null ;
308+
309+ return {
310+ computedMeasures,
311311 data : this . serializeData ( parseResult . data ) ,
312312 date,
313- group : groupId
314- ? {
315- connect : { id : groupId }
316- }
317- : undefined ,
318- instrument : {
319- connect : {
320- id : instrumentId
321- }
322- } ,
323- session : {
324- connect : {
325- id : sessionId
326- }
327- } ,
328- subject : {
329- connect : {
330- id : subjectId
331- }
332- }
333- }
334- } ) ;
313+ groupId,
314+ instrumentId,
315+ sessionId : session . id ,
316+ subjectId
317+ } ;
318+ } )
319+ ) ;
335320
336- createdRecordsArray . push ( createdRecord ) ;
337- }
338- } catch ( err ) {
339- await this . instrumentRecordModel . deleteMany ( {
321+ await this . instrumentRecordModel . createMany ( {
322+ data : preProcessedRecords
323+ } ) ;
324+
325+ return this . instrumentRecordModel . findMany ( {
340326 where : {
341- id : {
342- in : createdRecordsArray . map ( ( record ) => record . id )
343- }
327+ groupId,
328+ instrumentId
344329 }
345330 } ) ;
331+ } catch ( err ) {
346332 await this . sessionsService . deleteByIds ( createdSessionsArray . map ( ( session ) => session . id ) ) ;
347333 throw err ;
348334 }
349-
350- return createdRecordsArray ;
351335 }
352336
353337 private async createSubjectIfNotFound ( subjectId : string ) {
354338 try {
355- await this . subjectsService . findById ( subjectId ) ;
339+ return await this . subjectsService . findById ( subjectId ) ;
356340 } catch ( exception ) {
357341 if ( exception instanceof NotFoundException ) {
358342 const addedSubject : CreateSubjectDto = {
359343 id : subjectId
360344 } ;
361- await this . subjectsService . create ( addedSubject ) ;
345+ try {
346+ return await this . subjectsService . create ( addedSubject ) ;
347+ } catch ( prismaError ) {
348+ if ( prismaError instanceof Prisma . PrismaClientKnownRequestError && prismaError . code === 'P2002' ) {
349+ console . error ( prismaError ) ;
350+ return await this . subjectsService . findById ( subjectId ) ;
351+ } else {
352+ throw prismaError ;
353+ }
354+ }
362355 } else {
363356 throw exception ;
364357 }
0 commit comments