@@ -11,7 +11,7 @@ import {
1111} from '@prisma/client' ;
1212import { nanoid } from 'nanoid' ;
1313import sharp from 'sharp' ;
14- import { omit } from 'lodash' ;
14+ import { omit , setWith } from 'lodash' ;
1515
1616import { PrismaService } from '../prisma.service' ;
1717import * as RGAA from '../rgaa.json' ;
@@ -21,7 +21,6 @@ import { CRITERIA_BY_AUDIT_TYPE } from './criteria';
2121import { FileStorageService } from './file-storage.service' ;
2222import { UpdateAuditDto } from './update-audit.dto' ;
2323import { UpdateResultsDto } from './update-results.dto' ;
24- import { writeFile } from 'fs/promises' ;
2524
2625const AUDIT_EDIT_INCLUDE : Prisma . AuditInclude = {
2726 recipients : true ,
@@ -893,7 +892,7 @@ export class AuditService {
893892 }
894893
895894 async duplicateAudit ( uniqueId : string , newAuditName : string ) {
896- const o = await this . prisma . audit . findUnique ( {
895+ const originalAudit = await this . prisma . audit . findUnique ( {
897896 where : { editUniqueId : uniqueId } ,
898897 include : {
899898 environments : true ,
@@ -909,23 +908,96 @@ export class AuditService {
909908 } ,
910909 } ) ;
911910
912- if ( ! o ) {
911+ if ( ! originalAudit ) {
913912 return ;
914913 }
915914
916- // console.dir(originalAudit, { depth: null });
917-
918- // await writeFile('audit.json', JSON.stringify(originalAudit, null, 2));
915+ const duplicateEditUniqueId = nanoid ( ) ;
916+ const duplicateConsultUniqueId = nanoid ( ) ;
917+
918+ /**
919+ Object storing duplicate exampleImage creation data mapped by
920+ - page id
921+ - result id
922+ - example id
923+
924+ This object is used within the call to prisma.audit.create() to duplicate the example images.
925+
926+ Example content:
927+ ```
928+ {
929+ 'page-id': {
930+ 'result-id': {
931+ 'example-id': {
932+ filename: 'foo',
933+ ...
934+ }
935+ }
936+ }
937+ }
938+ ```
939+ */
940+ const imagesCreateData : {
941+ [ pageId : string ] : {
942+ [ resultId : string ] : object ;
943+ } ;
944+ } = { } ;
945+
946+ /**
947+ * contains s3 file duplications which will be executed together by calling
948+ * `fileStorageService.duplicateMultipleFiles()`
949+ */
950+ const imageDuplications : { originalKey : string ; destinationKey : string } [ ] =
951+ [ ] ;
952+
953+ originalAudit . pages . forEach ( ( p ) => {
954+ p . results . forEach ( ( r ) => {
955+ r . exampleImages . forEach ( ( e , i ) => {
956+ const randomPrefix = nanoid ( ) ;
957+
958+ const key = `audits/${ duplicateEditUniqueId } /${ randomPrefix } /${ e . originalFilename } ` ;
959+ const thumbnailKey = `audits/${ duplicateEditUniqueId } /${ randomPrefix } /thumbnail_${ e . originalFilename } ` ;
960+
961+ const publicUrl = this . fileStorageService . getPublicUrl ( key ) ;
962+ const thumbnailUrl =
963+ this . fileStorageService . getPublicUrl ( thumbnailKey ) ;
964+
965+ imageDuplications . push (
966+ {
967+ originalKey : e . key ,
968+ destinationKey : key ,
969+ } ,
970+ {
971+ originalKey : e . thumbnailKey ,
972+ destinationKey : thumbnailKey ,
973+ } ,
974+ ) ;
975+
976+ setWith (
977+ imagesCreateData ,
978+ [ p . id , r . id , e . id ] ,
979+ {
980+ originalFilename : e . originalFilename ,
981+ url : publicUrl ,
982+ size : e . size ,
983+ key : key ,
984+ thumbnailUrl : thumbnailUrl ,
985+ thumbnailKey : thumbnailKey ,
986+ } ,
987+ Object ,
988+ ) ;
989+ } ) ;
990+ } ) ;
991+ } ) ;
919992
920- const editUniqueId = nanoid ( ) ;
921- const consultUniqueId = nanoid ( ) ;
993+ await this . fileStorageService . duplicateMultipleFiles ( imageDuplications ) ;
922994
923995 const newAudit = await this . prisma . audit . create ( {
924996 data : {
925- ...omit ( o , [ 'id' , 'auditTraceId' ] ) ,
997+ ...omit ( originalAudit , [ 'id' , 'auditTraceId' ] ) ,
926998
927- editUniqueId,
928- consultUniqueId,
999+ editUniqueId : duplicateEditUniqueId ,
1000+ consultUniqueId : duplicateConsultUniqueId ,
9291001
9301002 procedureName : newAuditName ,
9311003
@@ -935,29 +1007,23 @@ export class AuditService {
9351007
9361008 environments : {
9371009 createMany : {
938- data : o . environments . map ( ( e ) => omit ( e , [ 'id' , 'auditUniqueId' ] ) ) ,
1010+ data : originalAudit . environments . map ( ( e ) =>
1011+ omit ( e , [ 'id' , 'auditUniqueId' ] ) ,
1012+ ) ,
9391013 } ,
9401014 } ,
9411015
9421016 pages : {
943- create : o . pages . map ( ( p ) => ( {
1017+ create : originalAudit . pages . map ( ( p ) => ( {
9441018 name : p . name ,
9451019 url : p . url ,
9461020 results : {
9471021 create : p . results . map ( ( r ) => ( {
9481022 ...omit ( r , [ 'id' , 'pageId' ] ) ,
9491023 exampleImages : {
950- // TODO: duplicate images too
951- create : [
952- // {
953- // originalFilename: 'string',
954- // url: 'string',
955- // size: 123,
956- // key: 'string',
957- // thumbnailUrl: 'string',
958- // thumbnailKey: 'string',
959- // },
960- ] ,
1024+ create : r . exampleImages . map (
1025+ ( e ) => imagesCreateData [ p . id ] [ r . id ] [ e . id ] ,
1026+ ) ,
9611027 } ,
9621028 } ) ) ,
9631029 } ,
@@ -966,8 +1032,8 @@ export class AuditService {
9661032
9671033 auditTrace : {
9681034 create : {
969- auditConsultUniqueId : consultUniqueId ,
970- auditEditUniqueId : editUniqueId ,
1035+ auditConsultUniqueId : duplicateConsultUniqueId ,
1036+ auditEditUniqueId : duplicateEditUniqueId ,
9711037 } ,
9721038 } ,
9731039 } ,
0 commit comments