@platform-modules/foreign-ministry 1.3.286 → 1.3.290

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 (27) hide show
  1. package/dist/data-source.js +2 -0
  2. package/dist/helpers/employee-evaluation-request.utils.d.ts +30 -0
  3. package/dist/helpers/employee-evaluation-request.utils.js +139 -0
  4. package/dist/index.d.ts +3 -0
  5. package/dist/index.js +8 -1
  6. package/dist/models/EmployeeEvaluationAnswerModel.d.ts +5 -8
  7. package/dist/models/EmployeeEvaluationAnswerModel.js +18 -16
  8. package/dist/models/EmployeeEvaluationApprovalModel.d.ts +1 -1
  9. package/dist/models/EmployeeEvaluationApprovalModel.js +2 -2
  10. package/dist/models/EmployeeEvaluationPersonScoreModel.d.ts +9 -0
  11. package/dist/models/EmployeeEvaluationPersonScoreModel.js +45 -0
  12. package/dist/models/EmployeeEvaluationRequestModel.d.ts +6 -1
  13. package/dist/models/EmployeeEvaluationRequestModel.js +18 -2
  14. package/dist/models/EvaluationEligibilitySettingModel.d.ts +2 -0
  15. package/dist/models/EvaluationEligibilitySettingModel.js +4 -0
  16. package/package.json +24 -24
  17. package/scripts/migration-employee-evaluation-approval-role-null.sql +11 -0
  18. package/scripts/migration-employee-evaluation-request-v2.sql +63 -0
  19. package/scripts/migration-evaluation-max-employees-per-request.sql +2 -0
  20. package/src/data-source.ts +614 -612
  21. package/src/helpers/employee-evaluation-request.utils.ts +181 -0
  22. package/src/index.ts +479 -467
  23. package/src/models/EmployeeEvaluationAnswerModel.ts +26 -28
  24. package/src/models/EmployeeEvaluationApprovalModel.ts +2 -2
  25. package/src/models/EmployeeEvaluationPersonScoreModel.ts +25 -0
  26. package/src/models/EmployeeEvaluationRequestModel.ts +90 -77
  27. package/src/models/EvaluationEligibilitySettingModel.ts +51 -47
@@ -291,6 +291,7 @@ const EvaluationFormQuestionModel_1 = require("./models/EvaluationFormQuestionMo
291
291
  const EmployeeEvaluationRequestModel_1 = require("./models/EmployeeEvaluationRequestModel");
292
292
  const EmployeeEvaluationModel_1 = require("./models/EmployeeEvaluationModel");
293
293
  const EmployeeEvaluationAnswerModel_1 = require("./models/EmployeeEvaluationAnswerModel");
294
+ const EmployeeEvaluationPersonScoreModel_1 = require("./models/EmployeeEvaluationPersonScoreModel");
294
295
  const EmployeeEvaluationApprovalModel_1 = require("./models/EmployeeEvaluationApprovalModel");
295
296
  const EmployeeEvaluationWorkflowModel_1 = require("./models/EmployeeEvaluationWorkflowModel");
296
297
  const EmployeeEvaluationChatModel_1 = require("./models/EmployeeEvaluationChatModel");
@@ -592,6 +593,7 @@ exports.AppDataSource = new typeorm_1.DataSource({
592
593
  EmployeeEvaluationRequestModel_1.EmployeeEvaluationRequests,
593
594
  EmployeeEvaluationModel_1.EmployeeEvaluation,
594
595
  EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers,
596
+ EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore,
595
597
  EmployeeEvaluationApprovalModel_1.EmployeeEvaluationApprovalDetails,
596
598
  EmployeeEvaluationWorkflowModel_1.EmployeeEvaluationWorkFlow,
597
599
  EmployeeEvaluationChatModel_1.EmployeeEvaluationRequestChat,
@@ -0,0 +1,30 @@
1
+ import type { EntityManager } from 'typeorm';
2
+ export declare const DEFAULT_MAX_EMPLOYEES_PER_REQUEST = 50;
3
+ export type EmployeeEvaluationSubmitAnswer = {
4
+ section_id: number;
5
+ question_id: number;
6
+ score: number;
7
+ remarks?: string | null;
8
+ };
9
+ export type EmployeeEvaluationSubmitEmployee = {
10
+ user_id: number;
11
+ is_rca?: boolean;
12
+ answers: EmployeeEvaluationSubmitAnswer[];
13
+ };
14
+ export type NormalizedEmployeeSubmission = EmployeeEvaluationSubmitEmployee;
15
+ export declare function normalizeEmployeeSubmissions(raw: unknown): {
16
+ employees: NormalizedEmployeeSubmission[];
17
+ error?: string;
18
+ };
19
+ /** Resolve max employees from active eligibility setting for dept/section/month. */
20
+ export declare function resolveMaxEmployeesPerRequest(manager: EntityManager, department_id: number, section_id: number, month: number): Promise<number>;
21
+ export declare function persistEmployeeEvaluationScores(manager: EntityManager, opts: {
22
+ requestId: number;
23
+ formId: number;
24
+ createdBy: string;
25
+ employees: NormalizedEmployeeSubmission[];
26
+ }): Promise<{
27
+ totalScore: number;
28
+ averageScore: number;
29
+ employeeCount: number;
30
+ }>;
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_MAX_EMPLOYEES_PER_REQUEST = void 0;
4
+ exports.normalizeEmployeeSubmissions = normalizeEmployeeSubmissions;
5
+ exports.resolveMaxEmployeesPerRequest = resolveMaxEmployeesPerRequest;
6
+ exports.persistEmployeeEvaluationScores = persistEmployeeEvaluationScores;
7
+ const EmployeeEvaluationAnswerModel_1 = require("../models/EmployeeEvaluationAnswerModel");
8
+ const EmployeeEvaluationPersonScoreModel_1 = require("../models/EmployeeEvaluationPersonScoreModel");
9
+ const EmployeeEvaluationRequestModel_1 = require("../models/EmployeeEvaluationRequestModel");
10
+ const EvaluationEligibilitySettingModel_1 = require("../models/EvaluationEligibilitySettingModel");
11
+ const EvaluationFormQuestionModel_1 = require("../models/EvaluationFormQuestionModel");
12
+ exports.DEFAULT_MAX_EMPLOYEES_PER_REQUEST = 50;
13
+ function normalizeEmployeeSubmissions(raw) {
14
+ if (!Array.isArray(raw) || raw.length === 0) {
15
+ return { employees: [], error: 'employees must be a non-empty array' };
16
+ }
17
+ const seen = new Set();
18
+ const employees = [];
19
+ for (const item of raw) {
20
+ if (item == null || typeof item !== 'object') {
21
+ return { employees: [], error: 'Each employee entry must be an object' };
22
+ }
23
+ const o = item;
24
+ const user_id = Number(o.user_id ?? o.employee_id);
25
+ if (!Number.isFinite(user_id) || user_id <= 0) {
26
+ return { employees: [], error: 'Each employee must have a valid user_id' };
27
+ }
28
+ if (seen.has(user_id)) {
29
+ return { employees: [], error: `Duplicate user_id ${user_id} in employees list` };
30
+ }
31
+ seen.add(user_id);
32
+ const answersRaw = o.answers;
33
+ if (!Array.isArray(answersRaw) || answersRaw.length === 0) {
34
+ return { employees: [], error: `Employee ${user_id} must include a non-empty answers array` };
35
+ }
36
+ const answers = [];
37
+ const qSeen = new Set();
38
+ for (const a of answersRaw) {
39
+ if (a == null || typeof a !== 'object') {
40
+ return { employees: [], error: `Invalid answer for employee ${user_id}` };
41
+ }
42
+ const ar = a;
43
+ const section_id = Number(ar.section_id);
44
+ const question_id = Number(ar.question_id);
45
+ const score = Number(ar.score);
46
+ if (!Number.isFinite(section_id) || !Number.isFinite(question_id)) {
47
+ return { employees: [], error: `section_id and question_id required for employee ${user_id}` };
48
+ }
49
+ if (!Number.isFinite(score) || score < 0) {
50
+ return { employees: [], error: `score must be a non-negative number for employee ${user_id}, question ${question_id}` };
51
+ }
52
+ if (qSeen.has(question_id)) {
53
+ return { employees: [], error: `Duplicate question_id ${question_id} for employee ${user_id}` };
54
+ }
55
+ qSeen.add(question_id);
56
+ answers.push({
57
+ section_id,
58
+ question_id,
59
+ score,
60
+ remarks: ar.remarks != null ? String(ar.remarks) : null,
61
+ });
62
+ }
63
+ employees.push({
64
+ user_id,
65
+ is_rca: o.is_rca !== undefined ? Boolean(o.is_rca) : false,
66
+ answers,
67
+ });
68
+ }
69
+ return { employees };
70
+ }
71
+ /** Resolve max employees from active eligibility setting for dept/section/month. */
72
+ async function resolveMaxEmployeesPerRequest(manager, department_id, section_id, month) {
73
+ const setting = await manager
74
+ .getRepository(EvaluationEligibilitySettingModel_1.EvaluationEligibilitySetting)
75
+ .createQueryBuilder('s')
76
+ .where('s.is_deleted = false')
77
+ .andWhere('s.is_active = true')
78
+ .andWhere('s.department_id = :department_id', { department_id })
79
+ .andWhere('s.section_id = :section_id', { section_id })
80
+ .andWhere('s.from_month <= :month', { month })
81
+ .andWhere('s.to_month >= :month', { month })
82
+ .orderBy('s.id', 'DESC')
83
+ .getOne();
84
+ const max = setting?.max_employees_per_request;
85
+ if (max != null && Number.isFinite(Number(max)) && Number(max) > 0) {
86
+ return Math.floor(Number(max));
87
+ }
88
+ return exports.DEFAULT_MAX_EMPLOYEES_PER_REQUEST;
89
+ }
90
+ async function persistEmployeeEvaluationScores(manager, opts) {
91
+ const { requestId, formId, createdBy, employees } = opts;
92
+ let requestTotal = 0;
93
+ for (const emp of employees) {
94
+ let personTotal = 0;
95
+ for (const ans of emp.answers) {
96
+ const qMeta = await manager.findOne(EvaluationFormQuestionModel_1.EvaluationFormQuestion, {
97
+ where: { id: ans.question_id, is_deleted: false },
98
+ });
99
+ const questionSectionId = qMeta?.form_section_id;
100
+ if (!qMeta || questionSectionId == null || questionSectionId !== ans.section_id) {
101
+ throw new Error(`Invalid question ${ans.question_id} for section ${ans.section_id}`);
102
+ }
103
+ if (qMeta.max_score != null && ans.score > qMeta.max_score) {
104
+ throw new Error(`score ${ans.score} exceeds max_score ${qMeta.max_score} for question ${ans.question_id}`);
105
+ }
106
+ personTotal += ans.score;
107
+ await manager.save(EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers, manager.create(EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers, {
108
+ request_id: requestId,
109
+ user_id: emp.user_id,
110
+ form_id: formId,
111
+ section_id: ans.section_id,
112
+ question_id: ans.question_id,
113
+ score: ans.score,
114
+ remarks: ans.remarks ?? null,
115
+ created_by: createdBy,
116
+ is_deleted: false,
117
+ }));
118
+ }
119
+ await manager.save(EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore, manager.create(EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore, {
120
+ request_id: requestId,
121
+ user_id: emp.user_id,
122
+ is_rca: Boolean(emp.is_rca),
123
+ us_feedback: null,
124
+ total_score: personTotal,
125
+ created_by: createdBy,
126
+ is_deleted: false,
127
+ }));
128
+ requestTotal += personTotal;
129
+ }
130
+ const employeeCount = employees.length;
131
+ const averageScore = employeeCount ? requestTotal / employeeCount : 0;
132
+ await manager.update(EmployeeEvaluationRequestModel_1.EmployeeEvaluationRequests, { id: requestId }, {
133
+ total_score: requestTotal,
134
+ average_score: averageScore,
135
+ employee_count: employeeCount,
136
+ updated_by: createdBy,
137
+ });
138
+ return { totalScore: requestTotal, averageScore, employeeCount };
139
+ }
package/dist/index.d.ts CHANGED
@@ -407,9 +407,12 @@ export { ServicesNotificationTriggerType } from './models/ServicesNotificationCo
407
407
  export * from './models/MoodleUsersModel';
408
408
  export { EvaluationEligibilitySetting, EvaluationEligibilitySettingEmployee, } from './models/EvaluationEligibilitySettingModel';
409
409
  export { isEvaluationEligibilityWindowOpen, parseEvaluationEndDay, parseMonthRange, } from './helpers/evaluation-eligibility.utils';
410
+ export { DEFAULT_MAX_EMPLOYEES_PER_REQUEST, normalizeEmployeeSubmissions, resolveMaxEmployeesPerRequest, persistEmployeeEvaluationScores, } from './helpers/employee-evaluation-request.utils';
411
+ export type { EmployeeEvaluationSubmitAnswer, EmployeeEvaluationSubmitEmployee, NormalizedEmployeeSubmission, } from './helpers/employee-evaluation-request.utils';
410
412
  export { EmployeeEvaluationRequests, EmployeeEvaluationRequestStatus, EmployeeEvaluationRoutingBucket, } from './models/EmployeeEvaluationRequestModel';
411
413
  export { EmployeeEvaluation, EmployeeEvaluationUsFeedback } from './models/EmployeeEvaluationModel';
412
414
  export { EmployeeEvaluationAnswers } from './models/EmployeeEvaluationAnswerModel';
415
+ export { EmployeeEvaluationPersonScore } from './models/EmployeeEvaluationPersonScoreModel';
413
416
  export { EmployeeEvaluationApprovalDetails, EmployeeEvaluationApprovalStatus, } from './models/EmployeeEvaluationApprovalModel';
414
417
  export { EmployeeEvaluationWorkFlow, EmployeeEvaluationWorkFlowStatus, } from './models/EmployeeEvaluationWorkflowModel';
415
418
  export { EmployeeEvaluationRequestChat, EmployeeEvaluationMessageType, } from './models/EmployeeEvaluationChatModel';
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.EvaluationEligibilitySetting = exports.ServicesNotificationTriggerType = exports.AppointmentWorkFlowStatus = exports.AppointmentMessageType = exports.AppointmentAttendeeStatus = exports.AppointmentApprovalStatus = exports.AppointmentAttendees = exports.AppointmentWorkFlow = exports.AppointmentRequestChat = exports.AppointmentRequestAttachment = exports.AppointmentApprovalDetails = exports.AppointmentRequestStatus = exports.AppointmentRequests = exports.TravelClass = exports.MissionTravelWorkFlowStatus = exports.MissionTravelApprovalStatus = exports.AllowanceRatio = exports.DecisionType = exports.MissionType = exports.MissionTravelStatus = exports.GatePassMessageType = exports.GatePassWorkFlowStatus = exports.GatePassApprovalStatus = exports.GatePassType = exports.GatePassRequestStatus = exports.SecurityDeptMessageType = exports.SecurityDeptAccessType = exports.SecurityDeptRequestStatus = exports.RetiredCardMessageType = exports.RetiredCardWorkFlowStatus = exports.RetiredCardApprovalStatus = exports.RetiredCardAccessType = exports.RetiredCardRequestStatus = exports.TitleCategory = exports.ProfileUpdateRequestStatus = exports.StayAfterHoursTransactionStatus = exports.StayAfterHoursTransaction = exports.StayAfterHoursBalance = exports.EarlyCheckoutTransactionStatus = exports.EarlyCheckoutTransaction = exports.EarlyCheckoutFrequency = exports.EarlyCheckoutConfiguration = exports.EarlyCheckoutBalance = exports.LeaveTransactionStatus = exports.LeaveTransaction = exports.LeaveConfigurationGrades = exports.enumFrequency = exports.LeaveConfiguration = exports.ParcelDepartmentCategory = exports.RegisterCandidateExperienceActivity = void 0;
18
- exports.EvaluationFormQuestionType = exports.EvaluationFormQuestion = exports.EvaluationFormSection = exports.EvaluationFormType = exports.EvaluationForm = exports.EmployeeEvaluationRequestAttachment = exports.EmployeeEvaluationMessageType = exports.EmployeeEvaluationRequestChat = exports.EmployeeEvaluationWorkFlowStatus = exports.EmployeeEvaluationWorkFlow = exports.EmployeeEvaluationApprovalStatus = exports.EmployeeEvaluationApprovalDetails = exports.EmployeeEvaluationAnswers = exports.EmployeeEvaluationUsFeedback = exports.EmployeeEvaluation = exports.EmployeeEvaluationRoutingBucket = exports.EmployeeEvaluationRequestStatus = exports.EmployeeEvaluationRequests = exports.parseMonthRange = exports.parseEvaluationEndDay = exports.isEvaluationEligibilityWindowOpen = exports.EvaluationEligibilitySettingEmployee = void 0;
18
+ exports.EvaluationFormQuestionType = exports.EvaluationFormQuestion = exports.EvaluationFormSection = exports.EvaluationFormType = exports.EvaluationForm = exports.EmployeeEvaluationRequestAttachment = exports.EmployeeEvaluationMessageType = exports.EmployeeEvaluationRequestChat = exports.EmployeeEvaluationWorkFlowStatus = exports.EmployeeEvaluationWorkFlow = exports.EmployeeEvaluationApprovalStatus = exports.EmployeeEvaluationApprovalDetails = exports.EmployeeEvaluationPersonScore = exports.EmployeeEvaluationAnswers = exports.EmployeeEvaluationUsFeedback = exports.EmployeeEvaluation = exports.EmployeeEvaluationRoutingBucket = exports.EmployeeEvaluationRequestStatus = exports.EmployeeEvaluationRequests = exports.persistEmployeeEvaluationScores = exports.resolveMaxEmployeesPerRequest = exports.normalizeEmployeeSubmissions = exports.DEFAULT_MAX_EMPLOYEES_PER_REQUEST = exports.parseMonthRange = exports.parseEvaluationEndDay = exports.isEvaluationEligibilityWindowOpen = exports.EvaluationEligibilitySettingEmployee = void 0;
19
19
  __exportStar(require("./models/user"), exports);
20
20
  __exportStar(require("./models/role"), exports);
21
21
  __exportStar(require("./models/user-sessions"), exports);
@@ -499,6 +499,11 @@ var evaluation_eligibility_utils_1 = require("./helpers/evaluation-eligibility.u
499
499
  Object.defineProperty(exports, "isEvaluationEligibilityWindowOpen", { enumerable: true, get: function () { return evaluation_eligibility_utils_1.isEvaluationEligibilityWindowOpen; } });
500
500
  Object.defineProperty(exports, "parseEvaluationEndDay", { enumerable: true, get: function () { return evaluation_eligibility_utils_1.parseEvaluationEndDay; } });
501
501
  Object.defineProperty(exports, "parseMonthRange", { enumerable: true, get: function () { return evaluation_eligibility_utils_1.parseMonthRange; } });
502
+ var employee_evaluation_request_utils_1 = require("./helpers/employee-evaluation-request.utils");
503
+ Object.defineProperty(exports, "DEFAULT_MAX_EMPLOYEES_PER_REQUEST", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.DEFAULT_MAX_EMPLOYEES_PER_REQUEST; } });
504
+ Object.defineProperty(exports, "normalizeEmployeeSubmissions", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.normalizeEmployeeSubmissions; } });
505
+ Object.defineProperty(exports, "resolveMaxEmployeesPerRequest", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.resolveMaxEmployeesPerRequest; } });
506
+ Object.defineProperty(exports, "persistEmployeeEvaluationScores", { enumerable: true, get: function () { return employee_evaluation_request_utils_1.persistEmployeeEvaluationScores; } });
502
507
  var EmployeeEvaluationRequestModel_1 = require("./models/EmployeeEvaluationRequestModel");
503
508
  Object.defineProperty(exports, "EmployeeEvaluationRequests", { enumerable: true, get: function () { return EmployeeEvaluationRequestModel_1.EmployeeEvaluationRequests; } });
504
509
  Object.defineProperty(exports, "EmployeeEvaluationRequestStatus", { enumerable: true, get: function () { return EmployeeEvaluationRequestModel_1.EmployeeEvaluationRequestStatus; } });
@@ -508,6 +513,8 @@ Object.defineProperty(exports, "EmployeeEvaluation", { enumerable: true, get: fu
508
513
  Object.defineProperty(exports, "EmployeeEvaluationUsFeedback", { enumerable: true, get: function () { return EmployeeEvaluationModel_1.EmployeeEvaluationUsFeedback; } });
509
514
  var EmployeeEvaluationAnswerModel_1 = require("./models/EmployeeEvaluationAnswerModel");
510
515
  Object.defineProperty(exports, "EmployeeEvaluationAnswers", { enumerable: true, get: function () { return EmployeeEvaluationAnswerModel_1.EmployeeEvaluationAnswers; } });
516
+ var EmployeeEvaluationPersonScoreModel_1 = require("./models/EmployeeEvaluationPersonScoreModel");
517
+ Object.defineProperty(exports, "EmployeeEvaluationPersonScore", { enumerable: true, get: function () { return EmployeeEvaluationPersonScoreModel_1.EmployeeEvaluationPersonScore; } });
511
518
  var EmployeeEvaluationApprovalModel_1 = require("./models/EmployeeEvaluationApprovalModel");
512
519
  Object.defineProperty(exports, "EmployeeEvaluationApprovalDetails", { enumerable: true, get: function () { return EmployeeEvaluationApprovalModel_1.EmployeeEvaluationApprovalDetails; } });
513
520
  Object.defineProperty(exports, "EmployeeEvaluationApprovalStatus", { enumerable: true, get: function () { return EmployeeEvaluationApprovalModel_1.EmployeeEvaluationApprovalStatus; } });
@@ -1,13 +1,10 @@
1
1
  import { BaseModel } from './BaseModel';
2
- import { EvaluationFormSection } from './EvaluationFormSectionModel';
3
- import { EvaluationFormQuestion } from './EvaluationFormQuestionModel';
4
- import { EmployeeEvaluation } from './EmployeeEvaluationModel';
5
2
  export declare class EmployeeEvaluationAnswers extends BaseModel {
6
- employee_evaluation: EmployeeEvaluation;
7
- /** Form section (replaces legacy evaluation_section_master). */
8
- evaluation_section: EvaluationFormSection;
9
- /** Form question (replaces legacy evaluation_question_master). */
10
- evaluation_question: EvaluationFormQuestion;
3
+ request_id: number;
4
+ user_id: number;
5
+ form_id: number;
6
+ section_id: number;
7
+ question_id: number;
11
8
  score: number;
12
9
  remarks: string | null;
13
10
  }
@@ -12,29 +12,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.EmployeeEvaluationAnswers = void 0;
13
13
  const typeorm_1 = require("typeorm");
14
14
  const BaseModel_1 = require("./BaseModel");
15
- const EvaluationFormSectionModel_1 = require("./EvaluationFormSectionModel");
16
- const EvaluationFormQuestionModel_1 = require("./EvaluationFormQuestionModel");
17
- const EmployeeEvaluationModel_1 = require("./EmployeeEvaluationModel");
18
15
  let EmployeeEvaluationAnswers = class EmployeeEvaluationAnswers extends BaseModel_1.BaseModel {
19
16
  };
20
17
  exports.EmployeeEvaluationAnswers = EmployeeEvaluationAnswers;
21
18
  __decorate([
22
- (0, typeorm_1.ManyToOne)(() => EmployeeEvaluationModel_1.EmployeeEvaluation, { onDelete: 'CASCADE' }),
23
- (0, typeorm_1.JoinColumn)({ name: 'employee_evaluation_id' }),
24
- __metadata("design:type", EmployeeEvaluationModel_1.EmployeeEvaluation)
25
- ], EmployeeEvaluationAnswers.prototype, "employee_evaluation", void 0);
19
+ (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
20
+ __metadata("design:type", Number)
21
+ ], EmployeeEvaluationAnswers.prototype, "request_id", void 0);
22
+ __decorate([
23
+ (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
24
+ __metadata("design:type", Number)
25
+ ], EmployeeEvaluationAnswers.prototype, "user_id", void 0);
26
26
  __decorate([
27
- (0, typeorm_1.ManyToOne)(() => EvaluationFormSectionModel_1.EvaluationFormSection, { onDelete: 'RESTRICT' }),
28
- (0, typeorm_1.JoinColumn)({ name: 'evaluation_section_id' }),
29
- __metadata("design:type", EvaluationFormSectionModel_1.EvaluationFormSection)
30
- ], EmployeeEvaluationAnswers.prototype, "evaluation_section", void 0);
27
+ (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
28
+ __metadata("design:type", Number)
29
+ ], EmployeeEvaluationAnswers.prototype, "form_id", void 0);
31
30
  __decorate([
32
- (0, typeorm_1.ManyToOne)(() => EvaluationFormQuestionModel_1.EvaluationFormQuestion, { onDelete: 'RESTRICT' }),
33
- (0, typeorm_1.JoinColumn)({ name: 'evaluation_question_id' }),
34
- __metadata("design:type", EvaluationFormQuestionModel_1.EvaluationFormQuestion)
35
- ], EmployeeEvaluationAnswers.prototype, "evaluation_question", void 0);
31
+ (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
32
+ __metadata("design:type", Number)
33
+ ], EmployeeEvaluationAnswers.prototype, "section_id", void 0);
34
+ __decorate([
35
+ (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
36
+ __metadata("design:type", Number)
37
+ ], EmployeeEvaluationAnswers.prototype, "question_id", void 0);
36
38
  __decorate([
37
- (0, typeorm_1.Column)({ type: 'int', nullable: false }),
39
+ (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
38
40
  __metadata("design:type", Number)
39
41
  ], EmployeeEvaluationAnswers.prototype, "score", void 0);
40
42
  __decorate([
@@ -10,7 +10,7 @@ export declare class EmployeeEvaluationApprovalDetails extends BaseModel {
10
10
  service_id: number | null;
11
11
  sub_service_id: number | null;
12
12
  level: number;
13
- approver_role_id: number;
13
+ approver_role_id: number | null;
14
14
  department_id: number | null;
15
15
  section_id: number | null;
16
16
  approver_user_id: number | null;
@@ -39,8 +39,8 @@ __decorate([
39
39
  __metadata("design:type", Number)
40
40
  ], EmployeeEvaluationApprovalDetails.prototype, "level", void 0);
41
41
  __decorate([
42
- (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
43
- __metadata("design:type", Number)
42
+ (0, typeorm_1.Column)({ type: 'integer', nullable: true }),
43
+ __metadata("design:type", Object)
44
44
  ], EmployeeEvaluationApprovalDetails.prototype, "approver_role_id", void 0);
45
45
  __decorate([
46
46
  (0, typeorm_1.Column)({ type: 'integer', nullable: true }),
@@ -0,0 +1,9 @@
1
+ import { BaseModel } from './BaseModel';
2
+ import { EmployeeEvaluationUsFeedback } from './EmployeeEvaluationModel';
3
+ export declare class EmployeeEvaluationPersonScore extends BaseModel {
4
+ request_id: number;
5
+ user_id: number;
6
+ us_feedback: EmployeeEvaluationUsFeedback | null;
7
+ is_rca: boolean;
8
+ total_score: number | null;
9
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.EmployeeEvaluationPersonScore = void 0;
13
+ const typeorm_1 = require("typeorm");
14
+ const BaseModel_1 = require("./BaseModel");
15
+ const EmployeeEvaluationModel_1 = require("./EmployeeEvaluationModel");
16
+ let EmployeeEvaluationPersonScore = class EmployeeEvaluationPersonScore extends BaseModel_1.BaseModel {
17
+ };
18
+ exports.EmployeeEvaluationPersonScore = EmployeeEvaluationPersonScore;
19
+ __decorate([
20
+ (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
21
+ __metadata("design:type", Number)
22
+ ], EmployeeEvaluationPersonScore.prototype, "request_id", void 0);
23
+ __decorate([
24
+ (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
25
+ __metadata("design:type", Number)
26
+ ], EmployeeEvaluationPersonScore.prototype, "user_id", void 0);
27
+ __decorate([
28
+ (0, typeorm_1.Column)({
29
+ type: 'enum',
30
+ enum: EmployeeEvaluationModel_1.EmployeeEvaluationUsFeedback,
31
+ nullable: true,
32
+ }),
33
+ __metadata("design:type", Object)
34
+ ], EmployeeEvaluationPersonScore.prototype, "us_feedback", void 0);
35
+ __decorate([
36
+ (0, typeorm_1.Column)({ type: 'boolean', default: false, nullable: false }),
37
+ __metadata("design:type", Boolean)
38
+ ], EmployeeEvaluationPersonScore.prototype, "is_rca", void 0);
39
+ __decorate([
40
+ (0, typeorm_1.Column)({ type: 'float', nullable: true }),
41
+ __metadata("design:type", Object)
42
+ ], EmployeeEvaluationPersonScore.prototype, "total_score", void 0);
43
+ exports.EmployeeEvaluationPersonScore = EmployeeEvaluationPersonScore = __decorate([
44
+ (0, typeorm_1.Entity)({ name: 'employee_evaluation_person_scores' })
45
+ ], EmployeeEvaluationPersonScore);
@@ -19,7 +19,7 @@ export declare class EmployeeEvaluationRequests extends BaseModel {
19
19
  sub_service_id: number | null;
20
20
  /** User who raised the request (e.g. HOD). */
21
21
  user_id: number;
22
- evaluation_year: number;
22
+ evaluation_year: string;
23
23
  evaluation_period: string;
24
24
  evaluation_month: number;
25
25
  /** Scope: employees must belong to this department. */
@@ -31,4 +31,9 @@ export declare class EmployeeEvaluationRequests extends BaseModel {
31
31
  status: EmployeeEvaluationRequestStatus;
32
32
  workflow_execution_id: string | null;
33
33
  comments: string | null;
34
+ total_score: number | null;
35
+ average_score: number | null;
36
+ employee_count: number;
37
+ /** Form structure snapshot at request creation (sections/questions). */
38
+ dynamic_evaluation_form: Record<string, unknown> | null;
34
39
  }
@@ -51,8 +51,8 @@ __decorate([
51
51
  __metadata("design:type", Number)
52
52
  ], EmployeeEvaluationRequests.prototype, "user_id", void 0);
53
53
  __decorate([
54
- (0, typeorm_1.Column)({ type: 'int', nullable: false }),
55
- __metadata("design:type", Number)
54
+ (0, typeorm_1.Column)({ type: 'varchar', length: 10, nullable: false }),
55
+ __metadata("design:type", String)
56
56
  ], EmployeeEvaluationRequests.prototype, "evaluation_year", void 0);
57
57
  __decorate([
58
58
  (0, typeorm_1.Column)({ type: 'varchar', length: 120, nullable: false }),
@@ -99,6 +99,22 @@ __decorate([
99
99
  (0, typeorm_1.Column)({ type: 'text', nullable: true }),
100
100
  __metadata("design:type", Object)
101
101
  ], EmployeeEvaluationRequests.prototype, "comments", void 0);
102
+ __decorate([
103
+ (0, typeorm_1.Column)({ type: 'float', nullable: true }),
104
+ __metadata("design:type", Object)
105
+ ], EmployeeEvaluationRequests.prototype, "total_score", void 0);
106
+ __decorate([
107
+ (0, typeorm_1.Column)({ type: 'float', nullable: true }),
108
+ __metadata("design:type", Object)
109
+ ], EmployeeEvaluationRequests.prototype, "average_score", void 0);
110
+ __decorate([
111
+ (0, typeorm_1.Column)({ type: 'int', default: 0, nullable: false }),
112
+ __metadata("design:type", Number)
113
+ ], EmployeeEvaluationRequests.prototype, "employee_count", void 0);
114
+ __decorate([
115
+ (0, typeorm_1.Column)({ type: 'jsonb', nullable: true }),
116
+ __metadata("design:type", Object)
117
+ ], EmployeeEvaluationRequests.prototype, "dynamic_evaluation_form", void 0);
102
118
  exports.EmployeeEvaluationRequests = EmployeeEvaluationRequests = __decorate([
103
119
  (0, typeorm_1.Entity)({ name: 'employee_evaluation_requests' })
104
120
  ], EmployeeEvaluationRequests);
@@ -13,6 +13,8 @@ export declare class EvaluationEligibilitySetting extends BaseModel {
13
13
  /** Last day of the evaluation month (1–31) when submissions close. */
14
14
  evaluation_end_date: number;
15
15
  is_active: boolean;
16
+ /** Maximum employees allowed in one evaluation request for this dept/section window. */
17
+ max_employees_per_request: number;
16
18
  employees?: EvaluationEligibilitySettingEmployee[];
17
19
  }
18
20
  export declare class EvaluationEligibilitySettingEmployee extends BaseModel {
@@ -43,6 +43,10 @@ __decorate([
43
43
  (0, typeorm_1.Column)({ type: 'boolean', default: true }),
44
44
  __metadata("design:type", Boolean)
45
45
  ], EvaluationEligibilitySetting.prototype, "is_active", void 0);
46
+ __decorate([
47
+ (0, typeorm_1.Column)({ type: 'int', default: 50 }),
48
+ __metadata("design:type", Number)
49
+ ], EvaluationEligibilitySetting.prototype, "max_employees_per_request", void 0);
46
50
  __decorate([
47
51
  (0, typeorm_1.OneToMany)(() => EvaluationEligibilitySettingEmployee, (e) => e.evaluation_eligibility_setting),
48
52
  __metadata("design:type", Array)
package/package.json CHANGED
@@ -1,24 +1,24 @@
1
- {
2
- "name": "@platform-modules/foreign-ministry",
3
- "version": "1.3.286",
4
- "main": "dist/index.js",
5
- "types": "dist/index.d.ts",
6
- "scripts": {
7
- "build": "tsc",
8
- "dev": "ts-node src/scripts.ts"
9
- },
10
- "publishConfig": {
11
- "access": "public"
12
- },
13
- "dependencies": {
14
- "moment-timezone": "^0.6.0",
15
- "pg": "^8.16.0",
16
- "typeorm": "^0.3.17"
17
- },
18
- "devDependencies": {
19
- "@types/moment-timezone": "^0.5.30",
20
- "dotenv": "^16.5.0",
21
- "ts-node": "^10.9.2",
22
- "typescript": "^5.2.0"
23
- }
24
- }
1
+ {
2
+ "name": "@platform-modules/foreign-ministry",
3
+ "version": "1.3.290",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "scripts": {
7
+ "build": "tsc",
8
+ "dev": "ts-node src/scripts.ts"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "dependencies": {
14
+ "moment-timezone": "^0.6.0",
15
+ "pg": "^8.16.0",
16
+ "typeorm": "^0.3.17"
17
+ },
18
+ "devDependencies": {
19
+ "@types/moment-timezone": "^0.5.30",
20
+ "dotenv": "^16.5.0",
21
+ "ts-node": "^10.9.2",
22
+ "typescript": "^5.2.0"
23
+ }
24
+ }
@@ -0,0 +1,11 @@
1
+ -- Treat missing approver role as NULL (not 0)
2
+ ALTER TABLE employee_evaluation_approvals
3
+ ALTER COLUMN approver_role_id DROP NOT NULL;
4
+
5
+ UPDATE employee_evaluation_approvals
6
+ SET approver_role_id = NULL
7
+ WHERE approver_role_id = 0;
8
+
9
+ UPDATE employee_evaluation_workflows
10
+ SET role_id = NULL
11
+ WHERE role_id = 0;
@@ -0,0 +1,63 @@
1
+ -- Employee evaluation request v2: request aggregates, person scores, answers by request/user/form
2
+
3
+ -- Request: evaluation_year as string + aggregates + form snapshot on request
4
+ ALTER TABLE employee_evaluation_requests
5
+ ALTER COLUMN evaluation_year TYPE varchar(10) USING evaluation_year::text;
6
+
7
+ ALTER TABLE employee_evaluation_requests
8
+ ADD COLUMN IF NOT EXISTS total_score double precision,
9
+ ADD COLUMN IF NOT EXISTS average_score double precision,
10
+ ADD COLUMN IF NOT EXISTS employee_count integer NOT NULL DEFAULT 0,
11
+ ADD COLUMN IF NOT EXISTS dynamic_evaluation_form jsonb;
12
+
13
+ -- Person scores (per employee in a request)
14
+ CREATE TABLE IF NOT EXISTS employee_evaluation_person_scores (
15
+ id serial PRIMARY KEY,
16
+ request_id integer NOT NULL REFERENCES employee_evaluation_requests(id) ON DELETE CASCADE,
17
+ user_id integer NOT NULL,
18
+ us_feedback varchar(32),
19
+ is_rca boolean NOT NULL DEFAULT false,
20
+ total_score double precision,
21
+ created_by varchar(255),
22
+ updated_by varchar(255),
23
+ created_at timestamptz DEFAULT now(),
24
+ updated_at timestamptz DEFAULT now(),
25
+ is_deleted boolean NOT NULL DEFAULT false,
26
+ UNIQUE (request_id, user_id)
27
+ );
28
+
29
+ -- Answers: migrate from employee_evaluation_id to request_id / user_id / form_id
30
+ ALTER TABLE employee_evaluation_answers
31
+ ADD COLUMN IF NOT EXISTS request_id integer,
32
+ ADD COLUMN IF NOT EXISTS user_id integer,
33
+ ADD COLUMN IF NOT EXISTS form_id integer,
34
+ ADD COLUMN IF NOT EXISTS section_id integer,
35
+ ADD COLUMN IF NOT EXISTS question_id integer;
36
+
37
+ UPDATE employee_evaluation_answers a
38
+ SET
39
+ request_id = ev.evaluation_request_id,
40
+ user_id = ev.user_id,
41
+ section_id = a.evaluation_section_id,
42
+ question_id = a.evaluation_question_id,
43
+ form_id = fs.form_id
44
+ FROM employee_evaluations ev
45
+ LEFT JOIN evaluation_form_sections fs ON fs.id = a.evaluation_section_id
46
+ WHERE a.employee_evaluation_id = ev.id
47
+ AND a.request_id IS NULL;
48
+
49
+ -- Backfill form_id from questions if section join missed
50
+ UPDATE employee_evaluation_answers a
51
+ SET form_id = fq.form_section_id
52
+ FROM evaluation_form_questions fq
53
+ WHERE a.form_id IS NULL AND a.question_id = fq.id;
54
+
55
+ UPDATE employee_evaluation_answers a
56
+ SET form_id = fs.form_id
57
+ FROM evaluation_form_sections fs
58
+ WHERE a.form_id IS NULL AND a.section_id = fs.id;
59
+
60
+ -- Drop legacy FK columns when safe (optional — run after app deploy)
61
+ -- ALTER TABLE employee_evaluation_answers DROP COLUMN IF EXISTS employee_evaluation_id;
62
+ -- ALTER TABLE employee_evaluation_answers DROP COLUMN IF EXISTS evaluation_section_id;
63
+ -- ALTER TABLE employee_evaluation_answers DROP COLUMN IF EXISTS evaluation_question_id;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE evaluation_eligibility_settings
2
+ ADD COLUMN IF NOT EXISTS max_employees_per_request integer NOT NULL DEFAULT 50;