Skip to content

Commit da91097

Browse files
authored
Merge pull request #235 from makeopensource/75-ncag-question-types
ncag question types
2 parents 50150bf + e254ab9 commit da91097

File tree

9 files changed

+107
-129
lines changed

9 files changed

+107
-129
lines changed

devU-api/README.md

Lines changed: 35 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -11,104 +11,37 @@ For now the only reason we're including docker is to more easily control the dev
1111

1212
## Running the Project Locally
1313

14-
### Getting Everything Started
15-
16-
Once you've got these installed, we can build our container and run it
17-
18-
#### Note to run the postgres container locally using the command below
19-
20-
You have to modify `devU-api/src/environment.ts`
21-
22-
change
23-
24-
`dbHost: (load('database.host') || 'localhost') as string`
25-
26-
to
27-
28-
`dbHost: 'localhost'`
29-
30-
This will probably be fixed in the future but for now the above steps are necessary
31-
32-
#### Using docker compose
33-
34-
We use [docker compose profiles](https://docs.docker.com/compose/profiles/) to selectively start services in the main docker-compose when developing.
35-
36-
Assuming you are in api dir `devU-api`, To start all api services except the api run
37-
38-
```
39-
npm run api-services
40-
```
41-
42-
To stop the services
43-
44-
```
45-
npm run api-services-stop
46-
```
47-
48-
Then install dependencies using
49-
50-
```
51-
npm install
52-
```
53-
54-
Once you've got all the dependencies installed you can run the project via
55-
56-
```
57-
npm start
58-
```
59-
60-
#### Manually:
61-
62-
```
63-
docker run \
64-
--name typeorm-postgres \
65-
-p 5432:5432 \
66-
-e POSTGRES_PASSWORD=password \
67-
-e POSTGRES_DB=typescript_api \
68-
-e POSTGRES_USER=typescript_user \
69-
-d postgres
70-
```
71-
72-
Install all node dependencies. All of the database environment variables can change, and can be set as environment variables on your machine if you want to overwrite the defaults
73-
74-
```
75-
docker run \
76-
--name minio \
77-
-p 9002:9000 \
78-
-p 9001:9001 \
79-
-v /tmp/data:/data \
80-
-e "MINIO_ROOT_USER=typescript_user" \
81-
-e "MINIO_ROOT_PASSWORD=changeMe" \
82-
-d minio/minio server /data --console-address ":9001"
83-
```
84-
85-
Install all node dependencies. All of the database environment variables can change, and can be set as environment variables on your machine if you want to overwrite the defaults
86-
87-
```
88-
npm install
89-
```
90-
91-
Run the setup script to create local development auth keys. These are used in local development for signing and authenticating JWTs.
92-
93-
```
94-
npm run generate-config
95-
```
96-
97-
Run the initial migrations to setup our DB schema
98-
99-
```
100-
npm run typeorm -- migration:run -d src/database.ts
101-
```
102-
103-
Once you've got all the dependencies installed you can run the project via
104-
105-
```
106-
npm start
107-
```
108-
109-
By default the project runs at `localhost:3001`, but you can change the port by setting an alternate port by setting the `PORT` environment variable.
110-
111-
If you're working in vscode, a configuration has been included to allow for debugging. Open up the VS Code Run and Debug section and click `Debug API`.
14+
### Quick Start
15+
16+
The instructions below assume you are in the api dir `/devU-api/`
17+
18+
You must have the following tools installed
19+
20+
* Docker
21+
* Node >= v20
22+
23+
Once you've got these installed,
24+
25+
1. We use [docker compose profiles](https://docs.docker.com/compose/profiles/)
26+
to selectively start services in the main docker-compose when developing.
27+
This starts all required services for the api depends (database, frontend etc.)
28+
```
29+
npm run api-services
30+
```
31+
32+
To remove all related containers
33+
```
34+
npm run api-services-stop
35+
```
36+
37+
2. Install dependencies using
38+
```
39+
npm install
40+
```
41+
3. Once you've got all the dependencies installed you can run the project via
42+
```
43+
npm run start
44+
```
11245
11346
### Convenient Devtools
11447
@@ -173,7 +106,7 @@ Here's what you need to know:
173106

174107
Here's the basic layout of the application
175108

176-
![control flow of the api](/docs/controlFlow.png 'Control Flow')
109+
![control flow of the api](./docs/controlFlow.png 'Control Flow')
177110

178111
Let's take this from the top
179112

@@ -218,9 +151,8 @@ When developing if you need to create a new type,
218151

219152
This will update the types in `devU-api` and `devU-client` folders.
220153

221-
**Note if the types are not being detected by your IDE**
222-
223-
**Go to the `devU-api/` and `devU-client/` and run `npm install` in each folder to update the shared modules.**
154+
if the types are not being detected, Go to the `devU-api/` and `devU-client/`
155+
and run `npm install` in each folder to update the shared modules.
224156

225157
### Testing
226158

@@ -257,7 +189,7 @@ I wouldn't recommend digging that far down as the of tests should be more human-
257189
If the schema needs to be updated, you can do so by updating the models and running
258190
259191
```
260-
npm run typeorm migration:generate -- -d src/database src/migration/<generatedMigrationName>
192+
npm run create-migration someMeaningfulMigrationName
261193
```
262194
263195
Doing so will attempt to create an auto migration from any changes within the `src/models` directory and add it to `src/migrations`. If an auto migration is generated for you (always check your auto migrations), you can run it with the above migration command

devU-api/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"create-migrate": "npx typeorm-ts-node-commonjs migration:generate -d src/database.ts",
1010
"update-shared": "cd ../devU-shared && npm run build-local && cd ../devU-api && npm i",
1111
"typeorm": "typeorm-ts-node-commonjs",
12+
"create-migration": "ts-node scripts/create-migration.ts",
1213
"test": "jest --passWithNoTests",
1314
"clean": "rimraf build/*",
1415
"lint": "tsc",
@@ -17,7 +18,7 @@
1718
"pre-commit": "lint-staged",
1819
"populate-db": "ts-node-dev ./scripts/populate-db.ts",
1920
"tango": "ts-node-dev ./src/tango/tests/tango.endpoint.test.ts",
20-
"api-services": "docker compose -f ../docker-compose.yml --profile dev-api up",
21+
"api-services": "docker compose -f ../docker-compose.yml --profile dev-api up --build",
2122
"api-services-stop": "docker compose -f ../docker-compose.yml --profile dev-api stop"
2223
},
2324
"lint-staged": {
@@ -67,6 +68,7 @@
6768
"cors": "^2.8.5",
6869
"devu-shared-modules": "./devu-shared-modules",
6970
"express": "^4.17.1",
71+
"express-list-endpoints": "^7.1.1",
7072
"express-validator": "^6.14.2",
7173
"helmet": "^4.6.0",
7274
"jsonwebtoken": "^9.0.2",
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { exec } from 'child_process'
2+
3+
// Get the migration name from command line arguments
4+
const migrationName = process.argv[2]
5+
6+
if (!migrationName) {
7+
console.error('Migration name is required!')
8+
console.error('Usage: npm run create-mig MigrationName')
9+
process.exit(1)
10+
}
11+
12+
const command = `npm run typeorm -- migration:generate -d src/database.ts src/migration/${migrationName}`
13+
console.log(`Executing: ${command}`)
14+
15+
// Execute the command
16+
exec(command, (error, stdout, stderr) => {
17+
if (stdout) console.log(stdout)
18+
if (stderr) console.error(stderr)
19+
20+
if (error) {
21+
console.error(`Error: ${error.message}`)
22+
process.exit(1)
23+
}
24+
25+
console.log('Migration file created successfully!')
26+
})

devU-api/src/entities/nonContainerAutoGrader/nonContainerAutoGrader.model.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ export default class NonContainerAutoGraderModel {
2727
* type: integer
2828
* question:
2929
* type: string
30+
* metadata:
31+
* type: any
32+
* description: this contains a valid json string tha contains info about any arbitrary question type (MCQ, Fill in the blanks etc.)
3033
* score:
3134
* type: number
3235
* correctString:
@@ -53,6 +56,9 @@ export default class NonContainerAutoGraderModel {
5356
@Column({ name: 'question', length: 128 })
5457
question: string
5558

59+
@Column({ name: 'metadata', type: 'jsonb', nullable: true, default: {} })
60+
metadata: any // use any since this can be any arbitrary structure
61+
5662
@Column({ name: 'score' })
5763
score: number
5864

devU-api/src/entities/nonContainerAutoGrader/nonContainerAutoGrader.serializer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export function serialize(nonContainerAutoGrader: NonContainerAutoGraderModel):
88
assignmentId: nonContainerAutoGrader.assignmentId,
99
question: nonContainerAutoGrader.question,
1010
score: nonContainerAutoGrader.score,
11+
metadata: JSON.stringify(nonContainerAutoGrader.metadata ?? ''),
1112
correctString: nonContainerAutoGrader.correctString,
1213
isRegex: nonContainerAutoGrader.isRegex,
1314
createdAt: nonContainerAutoGrader.createdAt.toISOString(),

devU-api/src/index.ts

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,11 @@ import { responseInterceptor } from './entities/webhooks/webhooks.middleware'
2323

2424
const app = express()
2525

26-
initializeMinio()
27-
.then(() =>
28-
dataSource.initialize()
29-
.then(() => {
30-
console.log('Data Source has been initialized!')
31-
})
32-
.catch(err => {
33-
console.error('Error during Data Source initialization', err)
34-
})
35-
)
36-
.then(_connection => {
26+
async function main() {
27+
try {
28+
await initializeMinio()
29+
await dataSource.initialize()
30+
3731
app.use(helmet())
3832
app.use(express.urlencoded({ extended: true }))
3933
app.use(express.json())
@@ -42,17 +36,19 @@ initializeMinio()
4236
app.use(morgan('combined'))
4337
app.use(passport.initialize())
4438

45-
console.log(`Api: ${environment.isDocker ? '' : 'not'} running in docker`)
46-
47-
app.use(responseInterceptor)
48-
49-
// Middleware;
39+
console.log(`API${environment.isDocker ? '' : ' not'} running in docker`)
40+
app.use(responseInterceptor) // webhooks
5041
app.use('/', router)
5142
app.use(errorHandler)
5243

5344
app.listen(environment.port, () =>
54-
console.log(`API listening at port - ${environment.port}\n
55-
If you are running the full app, the front end should be accessible at http://localhost:9000`)
45+
console.log(`API listening at port - ${environment.port}`),
5646
)
57-
})
58-
.catch(err => console.log('TypeORM connection error:', err))
47+
} catch (e: any) {
48+
console.error(`Error during initialization ${e.toString()}`)
49+
}
50+
}
51+
52+
main().catch((err: any) => {
53+
console.error(err)
54+
})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { MigrationInterface, QueryRunner } from "typeorm";
2+
3+
export class AddMetadataToNCAG1741738490302 implements MigrationInterface {
4+
name = 'AddMetadataToNCAG1741738490302'
5+
6+
public async up(queryRunner: QueryRunner): Promise<void> {
7+
await queryRunner.query(`ALTER TABLE "nonContainerAutoGrader" ADD "metadata" jsonb DEFAULT '{}'`);
8+
}
9+
10+
public async down(queryRunner: QueryRunner): Promise<void> {
11+
await queryRunner.query(`ALTER TABLE "nonContainerAutoGrader" DROP COLUMN "metadata"`);
12+
}
13+
14+
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { SubmissionProblemScore, SubmissionScore } from ".."
1+
import { SubmissionProblemScore } from './submissionProblemScore.types'
2+
import { SubmissionScore } from './submissionScore.types'
23

3-
export type GraderInfo = {
44

5+
export type GraderInfo = {
56
submissionScore: SubmissionScore
67
submissionProblemScores: SubmissionProblemScore[]
7-
88
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
export type NonContainerAutoGrader = {
22
id?: number
3+
createdAt?: string
4+
updatedAt?: string
35
assignmentId: number
46
question: string
7+
metadata: string,
58
score:number
69
correctString: string
710
isRegex: boolean
8-
createdAt?: string
9-
updatedAt?: string
1011
}

0 commit comments

Comments
 (0)