@programisto/edrm-exams 0.3.15 → 0.3.16
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.
|
@@ -20,6 +20,7 @@ export var ExperienceLevel;
|
|
|
20
20
|
})(ExperienceLevel || (ExperienceLevel = {}));
|
|
21
21
|
/* eslint-enable no-unused-vars */
|
|
22
22
|
let Candidate = class Candidate extends EnduranceSchema {
|
|
23
|
+
entityId;
|
|
23
24
|
contact;
|
|
24
25
|
experienceLevel;
|
|
25
26
|
yearsOfExperience;
|
|
@@ -32,6 +33,10 @@ let Candidate = class Candidate extends EnduranceSchema {
|
|
|
32
33
|
return CandidateModel;
|
|
33
34
|
}
|
|
34
35
|
};
|
|
36
|
+
__decorate([
|
|
37
|
+
EnduranceModelType.prop({ type: Types.ObjectId, ref: 'Entity', required: false }),
|
|
38
|
+
__metadata("design:type", Types.ObjectId)
|
|
39
|
+
], Candidate.prototype, "entityId", void 0);
|
|
35
40
|
__decorate([
|
|
36
41
|
EnduranceModelType.prop({ required: true, ref: 'Contact' }),
|
|
37
42
|
__metadata("design:type", Types.ObjectId)
|
|
@@ -8,6 +8,7 @@ import Candidate from '../models/candidate.model.js';
|
|
|
8
8
|
import ContactModel from '../models/contact.model.js';
|
|
9
9
|
import { generateLiveMessage } from '../lib/openai.js';
|
|
10
10
|
import { computeScoresByCategory } from '../lib/score-utils.js';
|
|
11
|
+
import { Types } from 'mongoose';
|
|
11
12
|
// Fonction utilitaire pour récupérer le nom du job
|
|
12
13
|
async function getJobName(targetJob) {
|
|
13
14
|
// Si c'est déjà une string (ancien format), on la retourne directement
|
|
@@ -1465,25 +1466,44 @@ class ExamsRouter extends EnduranceRouter {
|
|
|
1465
1466
|
if (!test) {
|
|
1466
1467
|
return res.status(404).json({ message: 'Test not found' });
|
|
1467
1468
|
}
|
|
1468
|
-
|
|
1469
|
-
const newResult = new TestResult({
|
|
1470
|
-
candidateId,
|
|
1471
|
-
testId,
|
|
1472
|
-
categories,
|
|
1473
|
-
state: 'pending',
|
|
1474
|
-
invitationDate: Date.now()
|
|
1475
|
-
});
|
|
1476
|
-
await newResult.save();
|
|
1477
|
-
// Récupérer l'email du candidat
|
|
1469
|
+
// Récupérer le candidat et le contact (avant de créer le TestResult pour pouvoir utiliser le candidat scopé entité)
|
|
1478
1470
|
const candidate = await Candidate.findById(candidateId);
|
|
1479
1471
|
if (!candidate) {
|
|
1480
1472
|
return res.status(404).json({ message: 'Candidate not found' });
|
|
1481
1473
|
}
|
|
1482
|
-
// Récupérer le contact pour obtenir l'email
|
|
1483
1474
|
const contact = await ContactModel.findById(candidate.contact);
|
|
1484
1475
|
if (!contact) {
|
|
1485
1476
|
return res.status(404).json({ message: 'Contact not found' });
|
|
1486
1477
|
}
|
|
1478
|
+
// Multi-entité : s'assurer qu'un Candidate existe pour l'entité courante (même contact).
|
|
1479
|
+
// Permet à un candidat déjà présent sur une autre entité de se connecter à l'espace candidat de cette entité.
|
|
1480
|
+
let entityCandidate = candidate;
|
|
1481
|
+
if (req.entity?._id) {
|
|
1482
|
+
const entityId = req.entity._id instanceof Types.ObjectId ? req.entity._id : new Types.ObjectId(String(req.entity._id));
|
|
1483
|
+
const existing = await Candidate.findOne({ contact: contact._id, entityId });
|
|
1484
|
+
if (!existing) {
|
|
1485
|
+
entityCandidate = new Candidate({
|
|
1486
|
+
contact: contact._id,
|
|
1487
|
+
entityId,
|
|
1488
|
+
skills: Array.isArray(candidate.skills) ? candidate.skills : [],
|
|
1489
|
+
experienceLevel: candidate.experienceLevel,
|
|
1490
|
+
yearsOfExperience: candidate.yearsOfExperience ?? 0
|
|
1491
|
+
});
|
|
1492
|
+
await entityCandidate.save();
|
|
1493
|
+
}
|
|
1494
|
+
else {
|
|
1495
|
+
entityCandidate = existing;
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
const categories = test.categories.map((cat) => ({ categoryId: cat.categoryId }));
|
|
1499
|
+
const newResult = new TestResult({
|
|
1500
|
+
candidateId: entityCandidate._id,
|
|
1501
|
+
testId,
|
|
1502
|
+
categories,
|
|
1503
|
+
state: 'pending',
|
|
1504
|
+
invitationDate: Date.now()
|
|
1505
|
+
});
|
|
1506
|
+
await newResult.save();
|
|
1487
1507
|
const email = contact.email;
|
|
1488
1508
|
// Construire le lien d'invitation
|
|
1489
1509
|
const testLink = (process.env.TEST_INVITATION_LINK || '') + email;
|