Skip to content

Commit c14d879

Browse files
authored
Feat/detailed-settings-disable-answers (#145)
* verbosity update * final touch * adjusting schema.prisma back * changes and adjustments * formatting
1 parent 74d3bd9 commit c14d879

File tree

49 files changed

+1143
-1043
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1143
-1043
lines changed

.secrets.baseline

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"files": null,
44
"lines": null
55
},
6-
"generated_at": "2025-10-09T10:36:06Z",
6+
"generated_at": "2025-10-09T13:24:14Z",
77
"plugins_used": [
88
{
99
"name": "AWSKeyDetector"
@@ -283,21 +283,21 @@
283283
{
284284
"hashed_secret": "e1166e6dd837019ab04f130ab34c425e04161645",
285285
"is_verified": false,
286-
"line_number": 382,
286+
"line_number": 384,
287287
"type": "Secret Keyword",
288288
"verified_result": null
289289
},
290290
{
291291
"hashed_secret": "f0c5bc5473fd2f959bdac630e625aa33346fd12a",
292292
"is_verified": false,
293-
"line_number": 429,
293+
"line_number": 431,
294294
"type": "Secret Keyword",
295295
"verified_result": null
296296
},
297297
{
298298
"hashed_secret": "29080f1c58f9859ddaa6aeda7d2c410c12e222dc",
299299
"is_verified": false,
300-
"line_number": 461,
300+
"line_number": 463,
301301
"type": "Secret Keyword",
302302
"verified_result": null
303303
}

apps/api-gateway/src/auth/jwt/cookie-based/mock.jwt.cookie.auth.guard.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,14 @@ export class MockJwtCookieAuthGuard extends AuthGuard("cookie-strategy") {
2222
const request: RequestWithUserSession = context.switchToHttp().getRequest();
2323

2424
request.user = {
25-
userId: "dev-user",
26-
role: UserRole.LEARNER,
27-
groupId: "string",
28-
assignmentId: 1888,
25+
userId: "magdy.hafez@ibm.com1",
26+
role: UserRole.AUTHOR,
27+
groupId: "autogen-faculty-v1-course-v1-IND-AI0103EN-v1",
28+
assignmentId: 1,
2929
gradingCallbackRequired: false,
3030
returnUrl: "https://skills.network",
3131
launch_presentation_locale: "en",
3232
};
33-
3433
return true;
3534
}
3635
}

apps/api-gateway/src/main.ts

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,51 @@ import { AppModule } from "./app.module";
99
import { winstonOptions } from "./logger/config";
1010

1111
async function bootstrap() {
12-
const app = await NestFactory.create(AppModule, {
13-
cors: false,
14-
logger: WinstonModule.createLogger(winstonOptions),
15-
});
16-
app.use(json({ limit: "1000mb" }));
17-
app.use(urlencoded({ limit: "1000mb", extended: true }));
18-
app.setGlobalPrefix("api", {
19-
exclude: ["health", "health/liveness", "health/readiness"],
20-
});
21-
22-
app.enableVersioning({
23-
type: VersioningType.URI,
24-
});
25-
26-
app.use(helmet());
27-
28-
app.use(cookieParser());
29-
30-
const config = new DocumentBuilder()
31-
.setTitle("API")
32-
.setDescription("API Description")
33-
.build();
34-
const document = SwaggerModule.createDocument(app, config);
35-
SwaggerModule.setup("api", app, document, {
36-
customSiteTitle: "API Docs",
37-
customCss: ".swagger-ui .topbar .topbar-wrapper { display: none; }",
38-
});
39-
40-
app.enableShutdownHooks();
41-
42-
await app.listen(process.env.API_GATEWAY_PORT ?? 3000);
12+
const logger = WinstonModule.createLogger(winstonOptions);
13+
14+
try {
15+
const app = await NestFactory.create(AppModule, {
16+
cors: false,
17+
logger,
18+
});
19+
app.use(json({ limit: "1000mb" }));
20+
app.use(urlencoded({ limit: "1000mb", extended: true }));
21+
app.setGlobalPrefix("api", {
22+
exclude: ["health", "health/liveness", "health/readiness"],
23+
});
24+
25+
app.enableVersioning({
26+
type: VersioningType.URI,
27+
});
28+
29+
app.use(helmet());
30+
31+
app.use(cookieParser());
32+
33+
const config = new DocumentBuilder()
34+
.setTitle("API")
35+
.setDescription("API Description")
36+
.build();
37+
const document = SwaggerModule.createDocument(app, config);
38+
SwaggerModule.setup("api", app, document, {
39+
customSiteTitle: "API Docs",
40+
customCss: ".swagger-ui .topbar .topbar-wrapper { display: none; }",
41+
});
42+
43+
app.enableShutdownHooks();
44+
45+
const port = process.env.API_GATEWAY_PORT ?? 3000;
46+
await app.listen(port, "0.0.0.0");
47+
48+
logger.log(`🚀 API Gateway is running on port ${port}`);
49+
logger.log(
50+
`📚 API Documentation available at http://localhost:${port}/api`,
51+
);
52+
} catch (error) {
53+
logger.error("❌ Failed to start API Gateway:", error);
54+
// eslint-disable-next-line unicorn/no-process-exit
55+
process.exit(1);
56+
}
4357
}
58+
4459
void bootstrap();

apps/api/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"test:staged": "jest --bail --findRelatedTests --passWithNoTests --collectCoverage=false",
2525
"test:watch": "jest --watch",
2626
"create-initial-versions": "dotenv -e ./dev.env -- ts-node src/scripts/create-initial-versions.ts",
27-
"translation-audit": "node dist/src/scripts/translation-audit.js"
27+
"translation-audit": "node dist/src/scripts/translation-audit.js",
28+
"verify-migration": "dotenv -e ./dev.env -- ts-node scripts/verify-migration.ts"
2829
},
2930
"prisma": {
3031
"seed": "ts-node prisma/seed.ts"
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
-- CreateEnum for CorrectAnswerVisibility
2+
CREATE TYPE "CorrectAnswerVisibility" AS ENUM ('NEVER', 'ALWAYS', 'ON_PASS');
3+
4+
-- Add the new column with ALWAYS as default
5+
ALTER TABLE "Assignment" ADD COLUMN "correctAnswerVisibility" "CorrectAnswerVisibility" DEFAULT 'ALWAYS';
6+
7+
-- Convert existing data: if showCorrectAnswer was true, set to ON_PASS, otherwise set to NEVER
8+
UPDATE "Assignment"
9+
SET "correctAnswerVisibility" = CASE
10+
WHEN "showCorrectAnswer" = true THEN 'ON_PASS'::"CorrectAnswerVisibility"
11+
ELSE 'NEVER'::"CorrectAnswerVisibility"
12+
END;
13+
14+
-- Make the new column NOT NULL after data conversion
15+
ALTER TABLE "Assignment" ALTER COLUMN "correctAnswerVisibility" SET NOT NULL;
16+
17+
-- Drop the old column
18+
ALTER TABLE "Assignment" DROP COLUMN "showCorrectAnswer";
19+
20+
-- Add the new column to AssignmentVersion table
21+
ALTER TABLE "AssignmentVersion" ADD COLUMN "correctAnswerVisibility" "CorrectAnswerVisibility" DEFAULT 'ALWAYS';
22+
23+
-- Update existing AssignmentVersion data: copy from parent Assignment
24+
UPDATE "AssignmentVersion" av
25+
SET "correctAnswerVisibility" = a."correctAnswerVisibility"
26+
FROM "Assignment" a
27+
WHERE av."assignmentId" = a.id;
28+
29+
-- Make the new column NOT NULL after data conversion
30+
ALTER TABLE "AssignmentVersion" ALTER COLUMN "correctAnswerVisibility" SET NOT NULL;

apps/api/prisma/schema.prisma

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ generator client {
55
provider = "prisma-client-js"
66
}
77

8-
// prisma/schema.prisma
98
datasource db {
109
provider = "postgresql"
1110
url = env("DATABASE_URL")
@@ -23,6 +22,13 @@ enum AssignmentQuestionDisplayOrder {
2322
DEFINED /// The assignments are displayed in a predefined order
2423
RANDOM /// The assignments are displayed in a random order
2524
}
25+
26+
/// This enum defines when correct answers should be visible to learners
27+
enum CorrectAnswerVisibility {
28+
NEVER /// Correct answers are never shown to learners
29+
ALWAYS /// Correct answers are always shown after submission
30+
ON_PASS /// Correct answers are only shown when learners pass the assignment
31+
}
2632
model GradingAudit {
2733
id Int @id @default(autoincrement())
2834
questionId Int
@@ -82,7 +88,7 @@ model Job {
8288
progress String?
8389
createdAt DateTime @default(now())
8490
updatedAt DateTime @updatedAt
85-
result Json? // Add this field to store generated questions
91+
result Json?
8692
}
8793
model GradingJob {
8894
id Int @id @default(autoincrement())
@@ -114,7 +120,7 @@ model publishJob {
114120
percentage Int?
115121
createdAt DateTime @default(now())
116122
updatedAt DateTime @updatedAt
117-
result Json? // Add this field to store generated questions
123+
result Json?
118124
}
119125
/// This model tracks the AI usage for each assignment and usage type
120126
model AIUsage {
@@ -188,7 +194,6 @@ enum ChatRole {
188194
SYSTEM
189195
}
190196

191-
/// The Group model represents a particular group of assignments (having the same groupID)
192197
model Group {
193198
id String @unique /// Unique ID of the course
194199
assignments AssignmentGroup[] /// The list of assignments associated with this group
@@ -204,7 +209,6 @@ model AssignmentGroup {
204209
@@id([assignmentId, groupId]) /// Unique identifier for the relationship
205210
}
206211

207-
/// The Assignment model represents a particular assignment
208212
model Assignment {
209213
id Int @id @default(autoincrement()) /// Unique identifier for the assignment
210214
name String /// Name of the assignment
@@ -231,8 +235,8 @@ model Assignment {
231235
showAssignmentScore Boolean @default(true) /// Should the assignment score be shown to the learner after its submission
232236
showQuestionScore Boolean @default(true) /// Should the question score be shown to the learner after its submission
233237
showSubmissionFeedback Boolean @default(true) /// Should the AI provide feedback when the learner submits a question
234-
showQuestions Boolean @default(true) /// Should the questions be shown to the learner
235-
showCorrectAnswer Boolean @default(true) /// Should the correct answer be shown to the learner after its submission
238+
showQuestions Boolean @default(true) /// Should the questions be shown to the learner
239+
correctAnswerVisibility CorrectAnswerVisibility @default(ALWAYS) /// When should correct answers be shown to learners
236240
updatedAt DateTime @default(now()) @updatedAt /// The DateTime at which the assignment was last updated
237241
languageCode String? /// The language code for the assignment
238242
currentVersionId Int? /// The ID of the current active version
@@ -282,6 +286,7 @@ model AssignmentVersion {
282286
showQuestionScore Boolean @default(true) /// Show question score
283287
showSubmissionFeedback Boolean @default(true) /// Show submission feedback
284288
showQuestions Boolean @default(true) /// Show questions
289+
correctAnswerVisibility CorrectAnswerVisibility @default(ALWAYS) /// When to show correct answers to learners
285290
languageCode String? /// Language code
286291
createdBy String /// User who created this version
287292
createdAt DateTime @default(now()) /// When version was created
@@ -523,7 +528,6 @@ model Report {
523528
524529
similarityScore Float? // Similarity score (0-1) with the parent report
525530
}
526-
// Add to schema.prisma
527531
model UserNotification {
528532
id Int @id @default(autoincrement())
529533
userId String

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
UserSessionRequest,
2828
} from "../../../auth/interfaces/user.session.interface";
2929
import { Roles } from "../../../auth/role/roles.global.guard";
30+
import { SuccessPageDataDto } from "../../attempt/dto/success-page-data.dto";
3031
import {
3132
GRADE_SUBMISSION_EXCEPTION,
3233
IN_COOLDOWN_PERIOD,

0 commit comments

Comments
 (0)