@@ -8,11 +8,9 @@ import type {
88 InstrumentRecordQueryParams ,
99 InstrumentRecordsExport ,
1010 LinearRegressionResults ,
11- UploadInstrumentRecordData
11+ UploadInstrumentRecordsData
1212} from '@opendatacapture/schemas/instrument-records' ;
13- import type { SessionType } from '@opendatacapture/schemas/session' ;
14- import type { CreateSubjectData } from '@opendatacapture/schemas/subject' ;
15- import type { InstrumentRecordModel , Prisma } from '@prisma/generated-client' ;
13+ import type { InstrumentRecordModel , Prisma , SessionModel } from '@prisma/generated-client' ;
1614import { isNumber , pickBy } from 'lodash-es' ;
1715
1816import { accessibleQuery } from '@/ability/ability.utils' ;
@@ -253,91 +251,106 @@ export class InstrumentRecordsService {
253251 }
254252
255253 async upload (
256- { groupId, instrumentId, records } : UploadInstrumentRecordData ,
254+ { groupId, instrumentId, records } : UploadInstrumentRecordsData ,
257255 options ?: EntityOperationOptions
258256 ) : Promise < InstrumentRecordModel [ ] > {
259257 if ( groupId ) {
260258 await this . groupsService . findById ( groupId , options ) ;
261259 }
262260
263261 const instrument = await this . instrumentsService . findById ( instrumentId ) ;
264-
265- const createdModelsArray : InstrumentRecordModel [ ] = [ ] ;
266262 if ( instrument . kind === 'SERIES' ) {
267263 throw new UnprocessableEntityException (
268264 `Cannot create instrument record for series instrument '${ instrument . id } '`
269265 ) ;
270266 }
271267
272- for ( const record of records ) {
273- const { data, date, subjectId } = record ;
274-
275- //create a new subject id in subjects service if they dont exist
276- try {
277- await this . subjectsService . findById ( subjectId ) ;
278- } catch ( exception ) {
279- if ( exception instanceof NotFoundException ) {
280- const addedSubject : CreateSubjectDto = {
281- id : subjectId
282- } ;
283- await this . subjectsService . create ( addedSubject ) ;
284- } else {
285- throw exception ;
286- }
287- }
288-
289- let subjectInfo : CreateSubjectData = {
290- dateOfBirth : null ,
291- firstName : null ,
292- id : subjectId ,
293- lastName : null ,
294- sex : null
295- } ;
268+ const createdRecordsArray : InstrumentRecordModel [ ] = [ ] ;
269+ const createdSessionsArray : SessionModel [ ] = [ ] ;
296270
297- let sessionType : SessionType = 'RETROSPECTIVE' ;
271+ try {
272+ for ( let i = 0 ; i < records . length ; i ++ ) {
273+ const { data, date, subjectId } = records [ i ] ! ;
274+ await this . createSubjectIfNotFound ( subjectId ) ;
298275
299- let sessionId = (
300- await this . sessionsService . create ( {
276+ const session = await this . sessionsService . create ( {
301277 date : date ,
302278 groupId : groupId ? groupId : null ,
303- subjectData : subjectInfo ,
304- type : sessionType
305- } )
306- ) . id ;
307-
308- const createdModel = await this . instrumentRecordModel . create ( {
309- data : {
310- computedMeasures : instrument . measures
311- ? this . instrumentMeasuresService . computeMeasures ( instrument . measures , data )
312- : null ,
313- data,
314- date,
315- group : groupId
316- ? {
317- connect : { id : groupId }
318- }
319- : undefined ,
320- instrument : {
321- connect : {
322- id : instrumentId
323- }
324- } ,
325- session : {
326- connect : {
327- id : sessionId
328- }
279+ subjectData : {
280+ id : subjectId
329281 } ,
330- subject : {
331- connect : {
332- id : subjectId
282+ type : 'RETROSPECTIVE'
283+ } ) ;
284+
285+ createdSessionsArray . push ( session ) ;
286+
287+ const sessionId = session . id ;
288+
289+ if ( ! instrument . validationSchema . safeParse ( data ) . success ) {
290+ throw new UnprocessableEntityException (
291+ `Data received for record at index '${ i } ' does not pass validation schema of instrument '${ instrument . id } '`
292+ ) ;
293+ }
294+
295+ const createdRecord = await this . instrumentRecordModel . create ( {
296+ data : {
297+ computedMeasures : instrument . measures
298+ ? this . instrumentMeasuresService . computeMeasures ( instrument . measures , data )
299+ : null ,
300+ data,
301+ date,
302+ group : groupId
303+ ? {
304+ connect : { id : groupId }
305+ }
306+ : undefined ,
307+ instrument : {
308+ connect : {
309+ id : instrumentId
310+ }
311+ } ,
312+ session : {
313+ connect : {
314+ id : sessionId
315+ }
316+ } ,
317+ subject : {
318+ connect : {
319+ id : subjectId
320+ }
333321 }
334322 }
323+ } ) ;
324+
325+ createdRecordsArray . push ( createdRecord ) ;
326+ }
327+ } catch ( err ) {
328+ await this . instrumentRecordModel . deleteMany ( {
329+ where : {
330+ id : {
331+ in : createdRecordsArray . map ( ( record ) => record . id )
332+ }
335333 }
336334 } ) ;
337-
338- createdModelsArray . push ( createdModel ) ;
335+ await this . sessionsService . deleteByIds ( createdSessionsArray . map ( ( session ) => session . id ) ) ;
336+ throw err ;
339337 }
340338
341- return createdModelsArray ;
339+ return createdRecordsArray ;
340+ }
341+
342+ private async createSubjectIfNotFound ( subjectId : string ) {
343+ try {
344+ await this . subjectsService . findById ( subjectId ) ;
345+ } catch ( exception ) {
346+ if ( exception instanceof NotFoundException ) {
347+ const addedSubject : CreateSubjectDto = {
348+ id : subjectId
349+ } ;
350+ await this . subjectsService . create ( addedSubject ) ;
351+ } else {
352+ throw exception ;
353+ }
354+ }
342355 }
343356}
0 commit comments