@@ -26,7 +26,47 @@ import { MemberPrismaService } from 'src/shared/modules/global/member-prisma.ser
2626import { ResourceApiService } from 'src/shared/modules/global/resource.service' ;
2727import { UserRole } from 'src/shared/enums/userRole.enum' ;
2828import { Prisma } from '@prisma/client' ;
29- import { buildSafeReviewSummationMetadata } from 'src/shared/utils/review-summation-metadata.util' ;
29+
30+ const REVIEW_SUMMATION_RESPONSE_SELECT = {
31+ id : true ,
32+ submissionId : true ,
33+ legacySubmissionId : true ,
34+ aggregateScore : true ,
35+ scorecardId : true ,
36+ scorecardLegacyId : true ,
37+ isPassing : true ,
38+ isFinal : true ,
39+ isProvisional : true ,
40+ isExample : true ,
41+ reviewedDate : true ,
42+ createdAt : true ,
43+ createdBy : true ,
44+ updatedAt : true ,
45+ updatedBy : true ,
46+ } satisfies Prisma . reviewSummationSelect ;
47+
48+ const REVIEW_SUMMATION_RESPONSE_WITH_METADATA_SELECT = {
49+ ...REVIEW_SUMMATION_RESPONSE_SELECT ,
50+ metadata : true ,
51+ } satisfies Prisma . reviewSummationSelect ;
52+
53+ const REVIEW_SUMMATION_WITH_SUBMITTER_SELECT = {
54+ ...REVIEW_SUMMATION_RESPONSE_SELECT ,
55+ submission : {
56+ select : {
57+ memberId : true ,
58+ } ,
59+ } ,
60+ } satisfies Prisma . reviewSummationSelect ;
61+
62+ const REVIEW_SUMMATION_WITH_SUBMITTER_AND_METADATA_SELECT = {
63+ ...REVIEW_SUMMATION_RESPONSE_WITH_METADATA_SELECT ,
64+ submission : {
65+ select : {
66+ memberId : true ,
67+ } ,
68+ } ,
69+ } satisfies Prisma . reviewSummationSelect ;
3070
3171@Injectable ( )
3272export class ReviewSummationService {
@@ -562,9 +602,10 @@ export class ReviewSummationService {
562602
563603 const data = await this . prisma . reviewSummation . create ( {
564604 data : createData ,
605+ select : REVIEW_SUMMATION_RESPONSE_SELECT ,
565606 } ) ;
566607 this . logger . log ( `Review summation created with ID: ${ data . id } ` ) ;
567- return data as ReviewSummationResponseDto ;
608+ return this . buildResponse ( data ) ;
568609 } catch ( error ) {
569610 // Re-throw NotFoundException and BadRequestException as-is
570611 if (
@@ -671,8 +712,6 @@ export class ReviewSummationService {
671712 : undefined ;
672713 const challengeIdFilter =
673714 rawChallengeId && rawChallengeId . length ? rawChallengeId : undefined ;
674- const includeMetadata =
675- ( queryDto . metadata ?? '' ) . toLowerCase ( ) === 'true' ;
676715
677716 if ( isSubmitterOnly ) {
678717 const userId =
@@ -839,23 +878,23 @@ export class ReviewSummationService {
839878 } ;
840879
841880 const shouldEnrichSubmitterMetadata = Boolean ( challengeIdFilter ) ;
881+ const includeMetadata =
882+ ( authUser ?. isMachine ?? false ) &&
883+ parseBooleanString ( queryDto . metadata ) === true ;
884+ const summationSelect = shouldEnrichSubmitterMetadata
885+ ? includeMetadata
886+ ? REVIEW_SUMMATION_WITH_SUBMITTER_AND_METADATA_SELECT
887+ : REVIEW_SUMMATION_WITH_SUBMITTER_SELECT
888+ : includeMetadata
889+ ? REVIEW_SUMMATION_RESPONSE_WITH_METADATA_SELECT
890+ : REVIEW_SUMMATION_RESPONSE_SELECT ;
842891
843892 const summations = await this . prisma . reviewSummation . findMany ( {
844893 where : whereClause ,
845894 skip,
846895 take : perPage ,
847896 orderBy,
848- ...( shouldEnrichSubmitterMetadata
849- ? {
850- include : {
851- submission : {
852- select : {
853- memberId : true ,
854- } ,
855- } ,
856- } ,
857- }
858- : { } ) ,
897+ select : summationSelect ,
859898 } ) ;
860899
861900 const submitterInfoByMemberId = new Map <
@@ -929,11 +968,10 @@ export class ReviewSummationService {
929968 } ) ;
930969
931970 const data : ReviewSummationResponseDto [ ] = summations . map ( ( summation ) => {
932- const { submission, metadata, ...rest } =
933- summation as typeof summation & {
934- submission ?: { memberId : string | null } ;
935- metadata ?: Prisma . JsonValue | null ;
936- } ;
971+ const summationRecord = summation as typeof summation & {
972+ submission ?: { memberId : string | null } ;
973+ } ;
974+ const { submission } = summationRecord ;
937975
938976 let submitterId : number | null = null ;
939977 let submitterHandle : string | null = null ;
@@ -958,20 +996,17 @@ export class ReviewSummationService {
958996 }
959997 }
960998
961- const base : ReviewSummationResponseDto = {
962- ...rest ,
963- submitterId,
964- submitterHandle,
965- submitterMaxRating,
966- } as ReviewSummationResponseDto ;
967-
968- if ( includeMetadata ) {
969- base . metadata = isSubmitterOnly
970- ? buildSafeReviewSummationMetadata ( metadata )
971- : ( metadata ?? null ) ;
972- }
973-
974- return base ;
999+ return this . buildResponse (
1000+ summationRecord ,
1001+ {
1002+ submitterId,
1003+ submitterHandle,
1004+ submitterMaxRating,
1005+ } ,
1006+ {
1007+ includeMetadata,
1008+ } ,
1009+ ) ;
9751010 } ) ;
9761011
9771012 this . logger . log (
@@ -1081,9 +1116,10 @@ export class ReviewSummationService {
10811116 const data = await this . prisma . reviewSummation . update ( {
10821117 where : { id } ,
10831118 data : updateData ,
1119+ select : REVIEW_SUMMATION_RESPONSE_SELECT ,
10841120 } ) ;
10851121 this . logger . log ( `Review summation updated successfully: ${ id } ` ) ;
1086- return data as ReviewSummationResponseDto ;
1122+ return this . buildResponse ( data ) ;
10871123 } catch ( error ) {
10881124 // Re-throw NotFoundException and BadRequestException from checkSummation and validation as-is
10891125 if (
@@ -1165,13 +1201,14 @@ export class ReviewSummationService {
11651201 try {
11661202 const data = await this . prisma . reviewSummation . findUnique ( {
11671203 where : { id } ,
1204+ select : REVIEW_SUMMATION_RESPONSE_SELECT ,
11681205 } ) ;
11691206 if ( ! data || ! data . id ) {
11701207 throw new NotFoundException (
11711208 `Review summation with ID ${ id } not found. Please verify the summation ID is correct.` ,
11721209 ) ;
11731210 }
1174- return data ;
1211+ return this . buildResponse ( data ) ;
11751212 } catch ( error ) {
11761213 // Re-throw NotFoundException as-is
11771214 if ( error instanceof NotFoundException ) {
@@ -1189,4 +1226,29 @@ export class ReviewSummationService {
11891226 } ) ;
11901227 }
11911228 }
1229+
1230+ /**
1231+ * Builds a review summation response object.
1232+ * @param data Review summation row or row-like object to serialize.
1233+ * @param extras Optional computed submitter fields to append.
1234+ * @param options Response serialization options, including internal metadata access.
1235+ * @returns Review summation response DTO with internal relations removed.
1236+ * @throws This method does not throw.
1237+ * Used by all review summation response paths as a final guard against exposing per-seed metadata by default.
1238+ */
1239+ private buildResponse (
1240+ data : Record < string , unknown > ,
1241+ extras : Partial < ReviewSummationResponseDto > = { } ,
1242+ options : { includeMetadata ?: boolean } = { } ,
1243+ ) : ReviewSummationResponseDto {
1244+ const response : Record < string , unknown > = {
1245+ ...data ,
1246+ ...extras ,
1247+ } ;
1248+ if ( ! options . includeMetadata ) {
1249+ delete response . metadata ;
1250+ }
1251+ delete response . submission ;
1252+ return response as unknown as ReviewSummationResponseDto ;
1253+ }
11921254}
0 commit comments