Skip to content

Commit 7bd7076

Browse files
authored
fix: data transformer (#185)
* update data transformer * feat: encode/decode choices and improve code structure * fix: data transformer should handle more edge cases with more tests
1 parent 6602575 commit 7bd7076

23 files changed

+3421
-2141
lines changed

.secrets.baseline

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,161 @@
335335
"verified_result": null
336336
}
337337
],
338+
"apps/web/app/Helpers/__tests__/actual-api-format.test.ts": [
339+
{
340+
"hashed_secret": "1eb9369bcdb20f6c88138c9427f009b6afe19c7c",
341+
"is_verified": false,
342+
"line_number": 22,
343+
"type": "Base64 High Entropy String",
344+
"verified_result": null
345+
},
346+
{
347+
"hashed_secret": "655dc5abb6b0ee511e4676b0739bb2077937014a",
348+
"is_verified": false,
349+
"line_number": 22,
350+
"type": "Base64 High Entropy String",
351+
"verified_result": null
352+
},
353+
{
354+
"hashed_secret": "6eff76dbb551ea7769517f3a7188862f85a7354e",
355+
"is_verified": false,
356+
"line_number": 79,
357+
"type": "Base64 High Entropy String",
358+
"verified_result": null
359+
},
360+
{
361+
"hashed_secret": "4f043b03a11e8b760986f07490ee76f48c6c7342",
362+
"is_verified": false,
363+
"line_number": 81,
364+
"type": "Base64 High Entropy String",
365+
"verified_result": null
366+
},
367+
{
368+
"hashed_secret": "618eb19f52dfe817f292f54554346cad3e3a88b3",
369+
"is_verified": false,
370+
"line_number": 81,
371+
"type": "Base64 High Entropy String",
372+
"verified_result": null
373+
}
374+
],
375+
"apps/web/app/Helpers/__tests__/choice-feedback-decoding.test.ts": [
376+
{
377+
"hashed_secret": "6eff76dbb551ea7769517f3a7188862f85a7354e",
378+
"is_verified": false,
379+
"line_number": 234,
380+
"type": "Base64 High Entropy String",
381+
"verified_result": null
382+
}
383+
],
384+
"apps/web/app/Helpers/data-transformer.edge-cases.test.ts": [
385+
{
386+
"hashed_secret": "9716c4510d038dc8f853fc40dc96f8a2a87bb51c",
387+
"is_verified": false,
388+
"line_number": 162,
389+
"type": "Base64 High Entropy String",
390+
"verified_result": null
391+
},
392+
{
393+
"hashed_secret": "4f043b03a11e8b760986f07490ee76f48c6c7342",
394+
"is_verified": false,
395+
"line_number": 165,
396+
"type": "Base64 High Entropy String",
397+
"verified_result": null
398+
},
399+
{
400+
"hashed_secret": "9aa7cde469abc42954177388692fa3c14663338d",
401+
"is_verified": false,
402+
"line_number": 166,
403+
"type": "Base64 High Entropy String",
404+
"verified_result": null
405+
}
406+
],
407+
"apps/web/app/Helpers/data-transformer.realworld.test.ts": [
408+
{
409+
"hashed_secret": "c5b49f145071d1dfaa7b852fbac2cc2d452c033d",
410+
"is_verified": false,
411+
"line_number": 15,
412+
"type": "Base64 High Entropy String",
413+
"verified_result": null
414+
},
415+
{
416+
"hashed_secret": "565d3a24396607e26491162b13a69050b37c7be7",
417+
"is_verified": false,
418+
"line_number": 17,
419+
"type": "Base64 High Entropy String",
420+
"verified_result": null
421+
},
422+
{
423+
"hashed_secret": "9690ab4554c9150bb66f9019049b7ed18998d6ab",
424+
"is_verified": false,
425+
"line_number": 22,
426+
"type": "Base64 High Entropy String",
427+
"verified_result": null
428+
},
429+
{
430+
"hashed_secret": "4f043b03a11e8b760986f07490ee76f48c6c7342",
431+
"is_verified": false,
432+
"line_number": 25,
433+
"type": "Base64 High Entropy String",
434+
"verified_result": null
435+
},
436+
{
437+
"hashed_secret": "9aa7cde469abc42954177388692fa3c14663338d",
438+
"is_verified": false,
439+
"line_number": 26,
440+
"type": "Base64 High Entropy String",
441+
"verified_result": null
442+
},
443+
{
444+
"hashed_secret": "b7e41a1408b0de53b6a18b0383983df52151bffd",
445+
"is_verified": false,
446+
"line_number": 60,
447+
"type": "Base64 High Entropy String",
448+
"verified_result": null
449+
},
450+
{
451+
"hashed_secret": "7f8a4c8efb7a9d741a4131e6382406d04920a55c",
452+
"is_verified": false,
453+
"line_number": 75,
454+
"type": "Base64 High Entropy String",
455+
"verified_result": null
456+
},
457+
{
458+
"hashed_secret": "ef584f952dbcdb807b1f2a5b688a6b2ac7beaf76",
459+
"is_verified": false,
460+
"line_number": 158,
461+
"type": "Base64 High Entropy String",
462+
"verified_result": null
463+
},
464+
{
465+
"hashed_secret": "fca9f0a000cc0d99a6b89eff22b280d43b3dc23a",
466+
"is_verified": false,
467+
"line_number": 168,
468+
"type": "Base64 High Entropy String",
469+
"verified_result": null
470+
},
471+
{
472+
"hashed_secret": "ad5a4eb98aace66b683002aa7038bb800f8b0a65",
473+
"is_verified": false,
474+
"line_number": 174,
475+
"type": "Base64 High Entropy String",
476+
"verified_result": null
477+
},
478+
{
479+
"hashed_secret": "28681ff8a70bc722645c0ebe5c21fbd8a2ee904a",
480+
"is_verified": false,
481+
"line_number": 183,
482+
"type": "Base64 High Entropy String",
483+
"verified_result": null
484+
},
485+
{
486+
"hashed_secret": "dd65cdacb216bbeca512abfb1ecd15d1c53ac7bd",
487+
"is_verified": false,
488+
"line_number": 431,
489+
"type": "Base64 High Entropy String",
490+
"verified_result": null
491+
}
492+
],
338493
"apps/web/app/api/markChat/route.ts": [
339494
{
340495
"hashed_secret": "3f70a0183ead614880b70bff64fd39c0d9155d62",

apps/api/src/api/assignment/attempt/attempt.service.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,15 +2342,25 @@ export class AttemptServiceV1 {
23422342
learnerResponse: string;
23432343
} {
23442344
const choices = this.parseChoices(question.choices);
2345+
console.log(
2346+
`Handling single correct question response for question ID: ${question.id}`,
2347+
);
23452348
const learnerChoice =
23462349
createQuestionResponseAttemptRequestDto.learnerChoices[0];
2347-
2350+
console.log(
2351+
`Learner choice: ${learnerChoice}, Choices: ${JSON.stringify(choices)}`,
2352+
);
23482353
const normalizedLearnerChoice = this.normalizeText(learnerChoice);
23492354
const correctChoice = choices.find((choice) => choice.isCorrect);
2350-
2355+
console.log(
2356+
`Correct choice: ${correctChoice ? correctChoice.choice : "None"}`,
2357+
);
23512358
const selectedChoice = choices.find(
23522359
(choice) => this.normalizeText(choice.choice) === normalizedLearnerChoice,
23532360
);
2361+
console.log(
2362+
`Selected choice: ${selectedChoice ? selectedChoice.choice : "None"}`,
2363+
);
23542364

23552365
const data = {
23562366
learnerChoice,

apps/api/src/api/attempt/common/strategies/choice-grading.strategy.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ export class ChoiceGradingStrategy extends AbstractGradingStrategy<string[]> {
154154
}> {
155155
await this.validateResponse(question, requestDto);
156156

157+
console.log("request dto:", requestDto);
158+
157159
const learnerResponse = await this.extractLearnerResponse(requestDto);
158160

159161
return this.gradeSingleChoice(question, learnerResponse, context);
@@ -170,6 +172,7 @@ export class ChoiceGradingStrategy extends AbstractGradingStrategy<string[]> {
170172
responseDto: CreateQuestionResponseAttemptResponseDto;
171173
learnerResponse: string[];
172174
}> {
175+
console.log("learner response:", learnerResponse);
173176
const choices = this.parseChoices(question.choices);
174177

175178
if (!learnerResponse || learnerResponse.length === 0) {
@@ -187,12 +190,25 @@ export class ChoiceGradingStrategy extends AbstractGradingStrategy<string[]> {
187190
}
188191

189192
const learnerChoice = learnerResponse[0];
193+
console.log("learner response:", learnerResponse);
190194
const normalizedLearnerChoice = this.normalizeText(learnerChoice);
191195
const correctChoice = choices.find((choice) => choice.isCorrect);
192196

197+
console.log("learner choice:", normalizedLearnerChoice);
198+
console.log(
199+
"all choices:",
200+
choices.map((c) => c.choice),
201+
);
202+
203+
console.log(
204+
"correct answer:",
205+
correctChoice ? correctChoice.choice : "none",
206+
);
207+
193208
const selectedChoice = choices.find(
194209
(choice) => this.normalizeText(choice.choice) === normalizedLearnerChoice,
195210
);
211+
console.log("selected choice:", selectedChoice);
196212

197213
const data = {
198214
learnerChoice,

apps/api/src/app.module.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@ import { AppService } from "./app.service";
1313
import { AdminAuthModule } from "./auth/admin-auth.module";
1414
import { AuthModule } from "./auth/auth.module";
1515
import { UserSessionMiddleware } from "./auth/middleware/user.session.middleware";
16+
import { CommonModule } from "./common/common.module";
1617
import { DatabaseModule } from "./database/database.module";
1718
import { HealthModule } from "./health/health.module";
1819
import { winstonOptions } from "./logger/config";
1920
import { LoggerMiddleware } from "./logger/logger.middleware";
2021
import { MessagingModule } from "./messaging/messaging.module";
21-
import { DataTransformMiddleware } from "./middleware/data-transform.middleware";
2222
import { routes } from "./routes";
2323

2424
@Module({
2525
imports: [
2626
ConfigModule.forRoot(),
2727
WinstonModule.forRoot(winstonOptions),
2828
HealthModule,
29+
CommonModule,
2930
ApiModule,
3031
ScheduledTasksModule,
3132
RouterModule.register(routes),
@@ -39,7 +40,7 @@ import { routes } from "./routes";
3940
export class AppModule implements NestModule {
4041
configure(consumer: MiddlewareConsumer) {
4142
consumer
42-
.apply(DataTransformMiddleware, LoggerMiddleware)
43+
.apply(LoggerMiddleware)
4344
.forRoutes({ path: "*", method: RequestMethod.ALL })
4445
.apply(UserSessionMiddleware)
4546
.forRoutes(

apps/api/src/common/common.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Module, Global } from "@nestjs/common";
2-
import { APP_INTERCEPTOR } from "@nestjs/core";
2+
import { APP_INTERCEPTOR, Reflector } from "@nestjs/core";
33
import { DataTransformInterceptor } from "./interceptors/data-transform.interceptor";
44

55
/**
@@ -8,6 +8,8 @@ import { DataTransformInterceptor } from "./interceptors/data-transform.intercep
88
@Global()
99
@Module({
1010
providers: [
11+
Reflector,
12+
DataTransformInterceptor,
1113
{
1214
provide: APP_INTERCEPTOR,
1315
useClass: DataTransformInterceptor,

0 commit comments

Comments
 (0)