@programisto/edrm-exams 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +135 -0
  2. package/dist/bin/www.d.ts +2 -0
  3. package/dist/bin/www.js +9 -0
  4. package/dist/modules/edrm-exams/lib/openai/correctQuestion.txt +10 -0
  5. package/dist/modules/edrm-exams/lib/openai/createQuestion.txt +68 -0
  6. package/dist/modules/edrm-exams/lib/openai.d.ts +36 -0
  7. package/dist/modules/edrm-exams/lib/openai.js +82 -0
  8. package/dist/modules/edrm-exams/listeners/correct.listener.d.ts +2 -0
  9. package/dist/modules/edrm-exams/listeners/correct.listener.js +85 -0
  10. package/dist/modules/edrm-exams/models/candidate.models.d.ts +13 -0
  11. package/dist/modules/edrm-exams/models/candidate.models.js +59 -0
  12. package/dist/modules/edrm-exams/models/company.model.d.ts +8 -0
  13. package/dist/modules/edrm-exams/models/company.model.js +34 -0
  14. package/dist/modules/edrm-exams/models/test-category.models.d.ts +7 -0
  15. package/dist/modules/edrm-exams/models/test-category.models.js +29 -0
  16. package/dist/modules/edrm-exams/models/test-question.model.d.ts +25 -0
  17. package/dist/modules/edrm-exams/models/test-question.model.js +70 -0
  18. package/dist/modules/edrm-exams/models/test-result.model.d.ts +26 -0
  19. package/dist/modules/edrm-exams/models/test-result.model.js +70 -0
  20. package/dist/modules/edrm-exams/models/test.model.d.ts +52 -0
  21. package/dist/modules/edrm-exams/models/test.model.js +123 -0
  22. package/dist/modules/edrm-exams/models/user.model.d.ts +18 -0
  23. package/dist/modules/edrm-exams/models/user.model.js +64 -0
  24. package/dist/modules/edrm-exams/routes/company.router.d.ts +7 -0
  25. package/dist/modules/edrm-exams/routes/company.router.js +108 -0
  26. package/dist/modules/edrm-exams/routes/exams-candidate.router.d.ts +7 -0
  27. package/dist/modules/edrm-exams/routes/exams-candidate.router.js +299 -0
  28. package/dist/modules/edrm-exams/routes/exams.router.d.ts +7 -0
  29. package/dist/modules/edrm-exams/routes/exams.router.js +1012 -0
  30. package/dist/modules/edrm-exams/routes/result.router.d.ts +7 -0
  31. package/dist/modules/edrm-exams/routes/result.router.js +314 -0
  32. package/dist/modules/edrm-exams/routes/user.router.d.ts +7 -0
  33. package/dist/modules/edrm-exams/routes/user.router.js +96 -0
  34. package/package.json +73 -8
package/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # Endurance Template
2
+
3
+ ## Overview
4
+
5
+ The Endurance Framework is a highly modular and scalable Node.js project template built on Express.js. It is designed to dynamically load and manage independent modules, making it extremely easy to develop, extend, and maintain web applications. The goal is to create a library of ready-made modules (e.g., login, user management, etc.) that can be easily integrated into any project.
6
+
7
+ ## Features
8
+
9
+ - **Dynamic Module Loading**: Easily add new modules with their own models and routes, and they will be automatically loaded and exposed by the application.
10
+ - **Express.js**: Fast, unopinionated, minimalist web framework for Node.js.
11
+ - **Modular Structure**: Each module is independent, promoting separation of concerns and better maintainability.
12
+ - **Modules marketplace**: Uses npm packages starting with "EDRM-" to quickly add features to your API.
13
+ - **Lib assets**: Include everything your need to start creating a robust API : events management, CRON, swagger, API versioning, webhooks etc.
14
+
15
+ ## Getting Started
16
+
17
+ ### Prerequisites
18
+
19
+ - Node.js (v20.x)
20
+ - MongoDB (optional for session management and data management)
21
+
22
+ ### Installation
23
+
24
+ 1. Install our CLI:
25
+
26
+ ```sh
27
+ npm install -g endurance
28
+ ```
29
+
30
+ 2. Create a project folder and create a new project:
31
+
32
+ ```sh
33
+ mkdir newproject
34
+ cd newproject
35
+
36
+ endurance new
37
+ ```
38
+
39
+ ### Usage
40
+
41
+ 1. **Start the application**:
42
+
43
+ For development:
44
+
45
+ ```sh
46
+ npm start
47
+ ```
48
+
49
+ For production:
50
+
51
+ ```sh
52
+ npm run prod
53
+ ```
54
+
55
+ 2. **Add a new module**:
56
+
57
+ To add a new module, create a new folder under the `modules` directory. Each module should contain its own models and routes.
58
+
59
+ Example structure for a new module:
60
+
61
+ ```
62
+ modules/
63
+ your-module/
64
+ models/
65
+ YourModel.js
66
+ routes/
67
+ yourModule.router.js
68
+ ```
69
+
70
+ 3. **Dynamic Module Loading**:
71
+
72
+ The application will automatically load and expose the routes and models from any new module added to the `modules` directory. There is no need for additional configuration.
73
+
74
+ ### Example
75
+
76
+ Here is an example of how to add a simple "login" module:
77
+
78
+ 1. **Create the module structure**:
79
+
80
+ ```
81
+ modules/
82
+ login/
83
+ models/
84
+ User.js
85
+ routes/
86
+ login.router.js
87
+ ```
88
+
89
+ 2. **Define the model (`User.js`)**:
90
+
91
+ ```javascript
92
+ const mongoose = require('mongoose');
93
+
94
+ const UserSchema = new mongoose.Schema({
95
+ username: { type: String, required: true },
96
+ password: { type: String, required: true }
97
+ });
98
+
99
+ module.exports = mongoose.model('User', UserSchema);
100
+ ```
101
+
102
+ 3. **Define the route (`login.router.js`)**:
103
+
104
+ ```javascript
105
+ const router = require('endurance-core/lib/router')();
106
+
107
+ router.post('/login', (req, res) => {
108
+ // Your login logic here
109
+ res.send('Login route');
110
+ });
111
+
112
+ module.exports = router;
113
+ ```
114
+
115
+ ### Testing
116
+
117
+ Run tests using Mocha and Supertest:
118
+
119
+ ```sh
120
+ npm test
121
+ ```
122
+
123
+ ### Roadmap
124
+
125
+ - **Library of Modules**: Develop a library of ready-made modules (e.g., login, user management) for easy integration.
126
+ - **Enhanced Documentation**: Provide detailed documentation and examples for each module.
127
+ - **Community Contributions**: Encourage community contributions to expand the module library.
128
+
129
+ ## Contributing
130
+
131
+ We welcome contributions! Please read our [Contributing Guidelines](CONTRIBUTING.md) for more details.
132
+
133
+ ## License
134
+
135
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import { fileURLToPath } from 'url';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+ const localAppPath = path.join(__dirname, '../lib/app.js');
8
+ const coreAppPath = 'endurance-core/dist/lib/app.js';
9
+ fs.existsSync(localAppPath) ? await import(localAppPath) : await import(coreAppPath);
@@ -0,0 +1,10 @@
1
+ Tu est un correcteur de question de concours.
2
+ Tu doit donner un score à cette question : ${instruction} dont la réponse donnée par le candidat est : ${response}.
3
+ Il s'agissait d'une question de type ${questionType} (et si la question est de type MCQ alors les réponses possibles étaient les suivantes : ${possibleResponses})
4
+ le score maximum pour cette question est ${maxScore}
5
+ Tu doit donner un score entre 0 et ${maxScore} et un commentaire de correction.
6
+ Tu dois répondre au format JSON : la reponse envoyer doit correspondre exactement à ce model json :
7
+ {
8
+ "score": score,
9
+ "comment": commentaire
10
+ }
@@ -0,0 +1,68 @@
1
+ Tu es un assistant qui crée des questions pour un test.
2
+ créer une question en fonction de du métier : ${job}, du niveau de seniorité : ${seniority}, de la categorie de question : ${category} et le niveau d'expertise de cette categorie : ${expertiseLevel} (allant de 1 à 10, de 1 à 3 = 'beginner', de 3 à 6 = 'intermediate', de 6 à 10 = 'advanced').
3
+ - la question doit être de type : ${questionType}.
4
+ - la question doit être dans la langue suivante : Français
5
+ - voici le model pour une question :
6
+ const questionModel = new mongoose.Schema(
7
+ {
8
+ instruction:
9
+ {
10
+ type: String,
11
+ required: true
12
+ },
13
+ questionType:
14
+ {
15
+ type: String,
16
+ enum:
17
+ ["MCQ", "free question", "exercice"],
18
+ required: true,
19
+ },
20
+ maxScore:
21
+ {
22
+ type: Number,
23
+ required: true,
24
+ },
25
+ possibleResponses: // only on MCQ (multiple choice responses)
26
+ {
27
+ type:
28
+ [{
29
+ possibleResponse:
30
+ {
31
+ type: String,
32
+ required: true,
33
+ },
34
+ valid:
35
+ {
36
+ type: Boolean,
37
+ required: true
38
+ }
39
+ }],
40
+ },
41
+ time: // in secondes
42
+ {
43
+ type: Number,
44
+ required: true,
45
+ },
46
+ textType: //type d'input demandé à l'utilisateur
47
+ {
48
+ type: String,
49
+ enum:
50
+ ["text", "code"],
51
+ required: false
52
+ }
53
+ });
54
+ - toutes les instruction et les réponses doivent toujours être compatible avec LaTeX pour être afficher dans des balises <MathJax>
55
+ voici un exemple : Voici une formule mathématique : \\( \\frac{a}{b} = c \\)
56
+ - voici des containtes pour chaque type de question :
57
+ - MCQ
58
+ (il ne peut y avoir qu'une seule réponse juste sur quatre au total) le temps pour ces questions vont de 30 secondes à 1 minute
59
+ - free question ( ne rien mettre dans possibleResponses)
60
+ le temps pour ces questions vont de 30 secondes à 5 minutes en fonction de la complexité de la réponse attendue (à toi de juger)
61
+ - exercice ( ne rien mettre dans possibleResponses )
62
+ le temps pour ces questions vont de 3 à 20 minutes en fonction de la complexité de la réponse attendue (à toi de juger)
63
+ - les instruction et la difficulté doivent être en rapport avec targetJob et seniorityLevel de ${test}
64
+ - le temps pour répondre à la question dans time doit laisser le temps aux utilisateur d'y répondre, sans non plus lui laisser trop de temps pour qu'il triche (surtout sur les QCM).
65
+ - le format de la réponses doit être en json avec seulement les elements présent dans le model ci dessus et pas besoin d'ajouter d"_id".
66
+ - si la réponse attendue à une question de type free question ou exercice est un bout de code, alors remplit textType en "code", sinon laisse "text"
67
+
68
+ Pour ne pas faire de doublon, voici la liste des questions déjà présentes dans le test : ${otherQuestions}
@@ -0,0 +1,36 @@
1
+ interface CreateQuestionParams {
2
+ job: string;
3
+ seniority: string;
4
+ questionType: string;
5
+ category: string;
6
+ expertiseLevel: string;
7
+ otherQuestions: string;
8
+ }
9
+ interface CorrectQuestionParams {
10
+ question: {
11
+ _id: string;
12
+ instruction: string;
13
+ maxScore: number;
14
+ possibleResponses: Array<{
15
+ possibleResponse: string;
16
+ valid: boolean;
17
+ }>;
18
+ questionType: string;
19
+ };
20
+ result: {
21
+ responses: Array<{
22
+ questionId: string;
23
+ response: string;
24
+ }>;
25
+ };
26
+ }
27
+ interface ContextBuilder {
28
+ createQuestion: (params: CreateQuestionParams) => Promise<Record<string, string>>;
29
+ correctQuestion: (params: CorrectQuestionParams) => Promise<{
30
+ instruction: string;
31
+ response: string;
32
+ maxScore: number;
33
+ }>;
34
+ }
35
+ export declare function generateLiveMessage(messageType: keyof ContextBuilder, params: CreateQuestionParams | CorrectQuestionParams, json?: boolean): Promise<string>;
36
+ export {};
@@ -0,0 +1,82 @@
1
+ import OpenAI from 'openai';
2
+ import { fileURLToPath } from 'url';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+ const openai = new OpenAI({
8
+ apiKey: process.env.OPENAI_API_KEY
9
+ });
10
+ const contextBuilder = {
11
+ async createQuestion({ job, seniority, questionType, category, expertiseLevel, otherQuestions }) {
12
+ const context = {
13
+ job,
14
+ seniority,
15
+ questionType,
16
+ category,
17
+ expertiseLevel,
18
+ otherQuestions
19
+ };
20
+ return context;
21
+ },
22
+ async correctQuestion({ question, result }) {
23
+ let response = '';
24
+ for (let i = 0; i < result.responses.length; i++) {
25
+ if (result.responses[i].questionId === question._id) {
26
+ response = result.responses[i].response;
27
+ break;
28
+ }
29
+ }
30
+ const instruction = question.instruction;
31
+ const maxScore = question.maxScore;
32
+ const questionType = question.questionType;
33
+ const possibleResponses = question.possibleResponses.map((response, index) => `réponse ${index + 1} = ${response}`).join('\n');
34
+ const context = {
35
+ instruction,
36
+ response,
37
+ maxScore,
38
+ questionType,
39
+ possibleResponses
40
+ };
41
+ return context;
42
+ }
43
+ };
44
+ export async function generateLiveMessage(messageType, params, json) {
45
+ const MAX_RETRY = 2;
46
+ let retryCount = 0;
47
+ const context = await contextBuilder[messageType](params);
48
+ const text = fs.readFileSync(path.join(__dirname, 'openai', `${messageType}.txt`), 'utf8');
49
+ const message = text.replace(/\${(.*?)}/g, (_, v) => context[v]);
50
+ while (retryCount <= MAX_RETRY) {
51
+ try {
52
+ const openAIParams = {
53
+ model: 'gpt-4-1106-preview',
54
+ temperature: 0.7,
55
+ messages: [{ role: 'system', content: message }]
56
+ };
57
+ if (json) {
58
+ openAIParams.response_format = { type: 'json_object' };
59
+ }
60
+ const result = await openai.chat.completions.create(openAIParams);
61
+ const content = result.choices[0].message.content;
62
+ if (!content) {
63
+ throw new Error('No content in response');
64
+ }
65
+ return removeQuotes(content);
66
+ }
67
+ catch (error) {
68
+ retryCount++;
69
+ console.log(error);
70
+ if (retryCount > MAX_RETRY) {
71
+ return 'Brain freezed, I cannot generate a live message right now.';
72
+ }
73
+ }
74
+ }
75
+ return 'Brain freezed, I cannot generate a live message right now.';
76
+ }
77
+ function removeQuotes(str) {
78
+ if (str.startsWith('"') && str.endsWith('"')) {
79
+ return str.substring(1, str.length - 1);
80
+ }
81
+ return str;
82
+ }
@@ -0,0 +1,2 @@
1
+ import { enduranceListener } from 'endurance-core';
2
+ export default enduranceListener;
@@ -0,0 +1,85 @@
1
+ import { enduranceListener, enduranceEventTypes } from 'endurance-core';
2
+ import TestQuestion from '../models/test-question.model.js';
3
+ import { generateLiveMessage } from '../lib/openai.js';
4
+ import TestResult, { TestState } from '../models/test-result.model.js';
5
+ async function correctTest(options) {
6
+ console.log('Correcting test', { options });
7
+ if (!options.testId)
8
+ throw new Error('TestId is required');
9
+ if (!options.responses)
10
+ throw new Error('Responses are required');
11
+ if (!options.state)
12
+ throw new Error('State is required');
13
+ try {
14
+ // Récupérer le résultat de test
15
+ const result = await TestResult.findById(options._id);
16
+ if (!result) {
17
+ throw new Error('Test result not found');
18
+ }
19
+ let finalscore = 0;
20
+ // Pour chaque réponse enregistrée en base, on cherche la correction correspondante
21
+ for (const dbResponse of result.responses) {
22
+ const correction = options.responses.find(r => r.questionId.toString() === dbResponse.questionId.toString());
23
+ if (!correction)
24
+ continue;
25
+ const question = await TestQuestion.findById(dbResponse.questionId);
26
+ if (!question) {
27
+ console.error('Question not found', { questionId: dbResponse.questionId });
28
+ continue;
29
+ }
30
+ const scoreResponse = await generateLiveMessage('correctQuestion', {
31
+ question: {
32
+ _id: question._id.toString(),
33
+ instruction: question.instruction,
34
+ possibleResponses: question.possibleResponses,
35
+ questionType: question.questionType,
36
+ maxScore: question.maxScore
37
+ },
38
+ result: {
39
+ responses: [{
40
+ questionId: dbResponse.questionId.toString(),
41
+ response: dbResponse.response
42
+ }]
43
+ }
44
+ }, true);
45
+ console.log('Correction result:', { scoreResponse });
46
+ const parsedResult = JSON.parse(scoreResponse);
47
+ finalscore += parsedResult.score;
48
+ dbResponse.score = parsedResult.score;
49
+ dbResponse.comment = parsedResult.comment || '';
50
+ }
51
+ // Mettre à jour le score final et l'état
52
+ result.score = finalscore;
53
+ result.state = TestState.Finish;
54
+ // Forcer la sauvegarde des sous-documents responses
55
+ result.markModified('responses');
56
+ // Sauvegarder les modifications avec findByIdAndUpdate pour éviter les conflits de version
57
+ await TestResult.findByIdAndUpdate(result._id, {
58
+ $set: {
59
+ responses: result.responses,
60
+ score: result.score,
61
+ state: result.state
62
+ }
63
+ });
64
+ console.log('Test correction completed and saved', { finalScore: finalscore });
65
+ }
66
+ catch (err) {
67
+ if (err instanceof Error) {
68
+ console.error(`Error correcting test: ${err.message}`, { err });
69
+ }
70
+ else {
71
+ console.error('Unknown error occurred during test correction', { err });
72
+ }
73
+ throw err; // Propager l'erreur pour la gestion en amont
74
+ }
75
+ }
76
+ enduranceListener.createListener(enduranceEventTypes.CORRECT_TEST, (args) => {
77
+ if (typeof args === 'object' && args !== null) {
78
+ const options = args;
79
+ correctTest(options);
80
+ }
81
+ else {
82
+ console.error('Invalid data type received in correct listener', { args });
83
+ }
84
+ });
85
+ export default enduranceListener;
@@ -0,0 +1,13 @@
1
+ import { EnduranceSchema } from 'endurance-core';
2
+ declare class Candidate extends EnduranceSchema {
3
+ firstName: string;
4
+ lastName: string;
5
+ email: string;
6
+ magicLinkToken?: string;
7
+ magicLinkExpiresAt?: Date;
8
+ authToken?: string;
9
+ authTokenExpiresAt?: Date;
10
+ static getModel(): import("@typegoose/typegoose").ReturnModelType<typeof Candidate, import("@typegoose/typegoose/lib/types").BeAnObject>;
11
+ }
12
+ declare const CandidateModel: import("@typegoose/typegoose").ReturnModelType<typeof Candidate, import("@typegoose/typegoose/lib/types").BeAnObject>;
13
+ export default CandidateModel;
@@ -0,0 +1,59 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { EnduranceSchema, EnduranceModelType } from 'endurance-core';
11
+ let Candidate = class Candidate extends EnduranceSchema {
12
+ firstName;
13
+ lastName;
14
+ email;
15
+ magicLinkToken;
16
+ magicLinkExpiresAt;
17
+ authToken;
18
+ authTokenExpiresAt;
19
+ static getModel() {
20
+ return CandidateModel;
21
+ }
22
+ };
23
+ __decorate([
24
+ EnduranceModelType.prop({ required: true }),
25
+ __metadata("design:type", String)
26
+ ], Candidate.prototype, "firstName", void 0);
27
+ __decorate([
28
+ EnduranceModelType.prop({ required: true }),
29
+ __metadata("design:type", String)
30
+ ], Candidate.prototype, "lastName", void 0);
31
+ __decorate([
32
+ EnduranceModelType.prop({ required: true, unique: true }),
33
+ __metadata("design:type", String)
34
+ ], Candidate.prototype, "email", void 0);
35
+ __decorate([
36
+ EnduranceModelType.prop({ required: false, type: String }),
37
+ __metadata("design:type", String)
38
+ ], Candidate.prototype, "magicLinkToken", void 0);
39
+ __decorate([
40
+ EnduranceModelType.prop({ required: false, type: Date }),
41
+ __metadata("design:type", Date)
42
+ ], Candidate.prototype, "magicLinkExpiresAt", void 0);
43
+ __decorate([
44
+ EnduranceModelType.prop({ required: false, type: String }),
45
+ __metadata("design:type", String)
46
+ ], Candidate.prototype, "authToken", void 0);
47
+ __decorate([
48
+ EnduranceModelType.prop({ required: false, type: Date }),
49
+ __metadata("design:type", Date)
50
+ ], Candidate.prototype, "authTokenExpiresAt", void 0);
51
+ Candidate = __decorate([
52
+ EnduranceModelType.modelOptions({
53
+ options: {
54
+ allowMixed: EnduranceModelType.Severity.ALLOW
55
+ }
56
+ })
57
+ ], Candidate);
58
+ const CandidateModel = EnduranceModelType.getModelForClass(Candidate);
59
+ export default CandidateModel;
@@ -0,0 +1,8 @@
1
+ import { EnduranceSchema } from 'endurance-core';
2
+ declare class Company extends EnduranceSchema {
3
+ name: string;
4
+ logo: string;
5
+ static getModel(): import("@typegoose/typegoose").ReturnModelType<typeof Company, import("@typegoose/typegoose/lib/types").BeAnObject>;
6
+ }
7
+ declare const CompanyModel: import("@typegoose/typegoose").ReturnModelType<typeof Company, import("@typegoose/typegoose/lib/types").BeAnObject>;
8
+ export default CompanyModel;
@@ -0,0 +1,34 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { EnduranceSchema, EnduranceModelType } from 'endurance-core';
11
+ let Company = class Company extends EnduranceSchema {
12
+ name;
13
+ logo;
14
+ static getModel() {
15
+ return CompanyModel;
16
+ }
17
+ };
18
+ __decorate([
19
+ EnduranceModelType.prop({ required: true }),
20
+ __metadata("design:type", String)
21
+ ], Company.prototype, "name", void 0);
22
+ __decorate([
23
+ EnduranceModelType.prop({ required: true }),
24
+ __metadata("design:type", String)
25
+ ], Company.prototype, "logo", void 0);
26
+ Company = __decorate([
27
+ EnduranceModelType.modelOptions({
28
+ options: {
29
+ allowMixed: EnduranceModelType.Severity.ALLOW
30
+ }
31
+ })
32
+ ], Company);
33
+ const CompanyModel = EnduranceModelType.getModelForClass(Company);
34
+ export default CompanyModel;
@@ -0,0 +1,7 @@
1
+ import { EnduranceSchema } from 'endurance-core';
2
+ declare class TestCategory extends EnduranceSchema {
3
+ name: string;
4
+ static getModel(): import("@typegoose/typegoose").ReturnModelType<typeof TestCategory, import("@typegoose/typegoose/lib/types").BeAnObject>;
5
+ }
6
+ declare const TestCategoryModel: import("@typegoose/typegoose").ReturnModelType<typeof TestCategory, import("@typegoose/typegoose/lib/types").BeAnObject>;
7
+ export default TestCategoryModel;
@@ -0,0 +1,29 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { EnduranceSchema, EnduranceModelType } from 'endurance-core';
11
+ let TestCategory = class TestCategory extends EnduranceSchema {
12
+ name;
13
+ static getModel() {
14
+ return TestCategoryModel;
15
+ }
16
+ };
17
+ __decorate([
18
+ EnduranceModelType.prop({ required: true }),
19
+ __metadata("design:type", String)
20
+ ], TestCategory.prototype, "name", void 0);
21
+ TestCategory = __decorate([
22
+ EnduranceModelType.modelOptions({
23
+ options: {
24
+ allowMixed: EnduranceModelType.Severity.ALLOW
25
+ }
26
+ })
27
+ ], TestCategory);
28
+ const TestCategoryModel = EnduranceModelType.getModelForClass(TestCategory);
29
+ export default TestCategoryModel;
@@ -0,0 +1,25 @@
1
+ import { EnduranceSchema } from 'endurance-core';
2
+ declare enum QuestionType {
3
+ MCQ = "MCQ",
4
+ FreeQuestion = "free question",
5
+ Exercise = "exercice"
6
+ }
7
+ interface PossibleResponse {
8
+ possibleResponse: string;
9
+ valid: boolean;
10
+ }
11
+ declare enum TextType {
12
+ Text = "text",
13
+ Code = "code"
14
+ }
15
+ declare class TestQuestion extends EnduranceSchema {
16
+ questionType: QuestionType;
17
+ instruction: string;
18
+ maxScore: number;
19
+ possibleResponses: PossibleResponse[];
20
+ time: number;
21
+ textType: TextType;
22
+ static getModel(): import("@typegoose/typegoose").ReturnModelType<typeof TestQuestion, import("@typegoose/typegoose/lib/types").BeAnObject>;
23
+ }
24
+ declare const TestQuestionModel: import("@typegoose/typegoose").ReturnModelType<typeof TestQuestion, import("@typegoose/typegoose/lib/types").BeAnObject>;
25
+ export default TestQuestionModel;