@platform-modules/civil-aviation-authority 2.3.300 → 2.3.302
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.
- package/dist/auth/user-session-validation.d.ts +22 -0
- package/dist/auth/user-session-validation.js +53 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models/ResidentialUnitRentalRequestModel.d.ts +1 -0
- package/dist/models/ResidentialUnitRentalRequestModel.js +4 -0
- package/dist/models/StudyLeaveWorkflowModel.d.ts +3 -1
- package/dist/models/StudyLeaveWorkflowModel.js +12 -2
- package/dist/models/TrainingWorkflowModel.d.ts +3 -1
- package/dist/models/TrainingWorkflowModel.js +12 -2
- package/package.json +1 -1
- package/sql/caa_api_payload_changes_2026_07.sql +3 -0
- package/src/auth/user-session-validation.ts +63 -0
- package/src/index.ts +1 -0
- package/src/models/ResidentialUnitRentalRequestModel.ts +2 -2
- package/src/models/StudyLeaveWorkflowModel.ts +11 -1
- package/src/models/TrainingWorkflowModel.ts +11 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side JWT session binding (CAA VAPT M003/M004).
|
|
3
|
+
* JWT remains valid cryptographically until exp; access is allowed only while
|
|
4
|
+
* the bound user_sessions row is active and not expired.
|
|
5
|
+
*/
|
|
6
|
+
export type UserSessionReader = {
|
|
7
|
+
isSessionActiveById(sessionId: number, userId: number): Promise<boolean>;
|
|
8
|
+
/** Legacy fallback when REQUIRE_JWT_SESSION_ID=false and token has no sessionId. */
|
|
9
|
+
isSessionActive?(userId: number): Promise<unknown>;
|
|
10
|
+
};
|
|
11
|
+
/** When true (default), JWT must include sessionId and that session must be active. */
|
|
12
|
+
export declare function isRequireJwtSessionId(): boolean;
|
|
13
|
+
export declare function resolveJwtSessionId(sessionId: unknown): number | null;
|
|
14
|
+
/**
|
|
15
|
+
* Validate that a verified JWT is still authorized (not logged out / expired server-side).
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateUserSessionBinding(userId: number, sessionId: number | null | undefined, reader: UserSessionReader): Promise<boolean>;
|
|
18
|
+
/** Shared TypeORM filters: active, not deleted, not past expires_at. */
|
|
19
|
+
export declare function activeUserSessionSql(alias?: string): {
|
|
20
|
+
clause: string;
|
|
21
|
+
params: Record<string, unknown>;
|
|
22
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Server-side JWT session binding (CAA VAPT M003/M004).
|
|
4
|
+
* JWT remains valid cryptographically until exp; access is allowed only while
|
|
5
|
+
* the bound user_sessions row is active and not expired.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.isRequireJwtSessionId = isRequireJwtSessionId;
|
|
9
|
+
exports.resolveJwtSessionId = resolveJwtSessionId;
|
|
10
|
+
exports.validateUserSessionBinding = validateUserSessionBinding;
|
|
11
|
+
exports.activeUserSessionSql = activeUserSessionSql;
|
|
12
|
+
/** When true (default), JWT must include sessionId and that session must be active. */
|
|
13
|
+
function isRequireJwtSessionId() {
|
|
14
|
+
const raw = (process.env.REQUIRE_JWT_SESSION_ID ?? 'true').trim().toLowerCase();
|
|
15
|
+
return raw !== 'false' && raw !== '0' && raw !== 'no';
|
|
16
|
+
}
|
|
17
|
+
function resolveJwtSessionId(sessionId) {
|
|
18
|
+
if (sessionId == null || sessionId === '')
|
|
19
|
+
return null;
|
|
20
|
+
const sid = Number(sessionId);
|
|
21
|
+
if (!Number.isFinite(sid) || sid <= 0)
|
|
22
|
+
return null;
|
|
23
|
+
return sid;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Validate that a verified JWT is still authorized (not logged out / expired server-side).
|
|
27
|
+
*/
|
|
28
|
+
async function validateUserSessionBinding(userId, sessionId, reader) {
|
|
29
|
+
if (!Number.isFinite(userId) || userId <= 0)
|
|
30
|
+
return false;
|
|
31
|
+
const sid = resolveJwtSessionId(sessionId);
|
|
32
|
+
if (sid != null) {
|
|
33
|
+
return reader.isSessionActiveById(sid, userId);
|
|
34
|
+
}
|
|
35
|
+
if (isRequireJwtSessionId()) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (!reader.isSessionActive)
|
|
39
|
+
return false;
|
|
40
|
+
const legacy = await reader.isSessionActive(userId);
|
|
41
|
+
return !!legacy;
|
|
42
|
+
}
|
|
43
|
+
/** Shared TypeORM filters: active, not deleted, not past expires_at. */
|
|
44
|
+
function activeUserSessionSql(alias = 'user_sessions') {
|
|
45
|
+
return {
|
|
46
|
+
clause: `${alias}.is_active = :is_active AND ${alias}.is_deleted = :is_deleted AND (${alias}.expires_at IS NULL OR ${alias}.expires_at > :session_now)`,
|
|
47
|
+
params: {
|
|
48
|
+
is_active: true,
|
|
49
|
+
is_deleted: false,
|
|
50
|
+
session_now: new Date(),
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './models/user';
|
|
2
2
|
export * from './models/role';
|
|
3
3
|
export * from './models/user-sessions';
|
|
4
|
+
export * from './auth/user-session-validation';
|
|
4
5
|
export * from './models/ITHelpDeskModel';
|
|
5
6
|
export * from './models/ServiceTypeModel';
|
|
6
7
|
export * from './models/CAAServices';
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ exports.RespondToEnquiriesRequestAttachment = exports.RespondToEnquiriesWorkFlow
|
|
|
20
20
|
__exportStar(require("./models/user"), exports);
|
|
21
21
|
__exportStar(require("./models/role"), exports);
|
|
22
22
|
__exportStar(require("./models/user-sessions"), exports);
|
|
23
|
+
__exportStar(require("./auth/user-session-validation"), exports);
|
|
23
24
|
__exportStar(require("./models/ITHelpDeskModel"), exports);
|
|
24
25
|
// export * from './models/ITServicesTypesSalalahModel'; // REMOVED - table no longer used
|
|
25
26
|
// export * from './models/ITServicesTypesMuscatModel'; // REMOVED - table no longer used
|
|
@@ -69,6 +69,10 @@ __decorate([
|
|
|
69
69
|
(0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
|
|
70
70
|
__metadata("design:type", String)
|
|
71
71
|
], ResidentialUnitRentalRequest.prototype, "location_of_unit", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
(0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
|
|
74
|
+
__metadata("design:type", Object)
|
|
75
|
+
], ResidentialUnitRentalRequest.prototype, "number_of_apartments", void 0);
|
|
72
76
|
__decorate([
|
|
73
77
|
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
74
78
|
__metadata("design:type", String)
|
|
@@ -15,7 +15,9 @@ export declare class StudyLeaveWorkFlow extends BaseModel {
|
|
|
15
15
|
approver_role_id: number | null;
|
|
16
16
|
approver_user_id: number | null;
|
|
17
17
|
approved_by: number | null;
|
|
18
|
+
department_id: number | null;
|
|
19
|
+
section_id: number | null;
|
|
18
20
|
status: StudyLeaveWorkFlowStatus;
|
|
19
21
|
status_ar: string | null;
|
|
20
|
-
constructor(request_id: number, content: string, status: StudyLeaveWorkFlowStatus, service_id?: number | null, sub_service_id?: number | null, order?: number, approver_role_id?: number | null, approver_user_id?: number | null, approved_by?: number | null);
|
|
22
|
+
constructor(request_id: number, content: string, status: StudyLeaveWorkFlowStatus, service_id?: number | null, sub_service_id?: number | null, order?: number, approver_role_id?: number | null, approver_user_id?: number | null, approved_by?: number | null, department_id?: number | null, section_id?: number | null);
|
|
21
23
|
}
|
|
@@ -20,7 +20,7 @@ var StudyLeaveWorkFlowStatus;
|
|
|
20
20
|
StudyLeaveWorkFlowStatus["REJECTED"] = "Rejected";
|
|
21
21
|
})(StudyLeaveWorkFlowStatus || (exports.StudyLeaveWorkFlowStatus = StudyLeaveWorkFlowStatus = {}));
|
|
22
22
|
let StudyLeaveWorkFlow = class StudyLeaveWorkFlow extends BaseModel_1.BaseModel {
|
|
23
|
-
constructor(request_id, content, status, service_id, sub_service_id, order, approver_role_id, approver_user_id, approved_by) {
|
|
23
|
+
constructor(request_id, content, status, service_id, sub_service_id, order, approver_role_id, approver_user_id, approved_by, department_id, section_id) {
|
|
24
24
|
super();
|
|
25
25
|
this.request_id = request_id;
|
|
26
26
|
this.service_id = service_id || null;
|
|
@@ -31,6 +31,8 @@ let StudyLeaveWorkFlow = class StudyLeaveWorkFlow extends BaseModel_1.BaseModel
|
|
|
31
31
|
this.approver_role_id = approver_role_id || null;
|
|
32
32
|
this.approver_user_id = approver_user_id || null;
|
|
33
33
|
this.approved_by = approved_by || null;
|
|
34
|
+
this.department_id = department_id || null;
|
|
35
|
+
this.section_id = section_id || null;
|
|
34
36
|
}
|
|
35
37
|
};
|
|
36
38
|
exports.StudyLeaveWorkFlow = StudyLeaveWorkFlow;
|
|
@@ -70,6 +72,14 @@ __decorate([
|
|
|
70
72
|
(0, typeorm_1.Column)({ type: "integer", nullable: true }),
|
|
71
73
|
__metadata("design:type", Object)
|
|
72
74
|
], StudyLeaveWorkFlow.prototype, "approved_by", void 0);
|
|
75
|
+
__decorate([
|
|
76
|
+
(0, typeorm_1.Column)({ type: "integer", nullable: true }),
|
|
77
|
+
__metadata("design:type", Object)
|
|
78
|
+
], StudyLeaveWorkFlow.prototype, "department_id", void 0);
|
|
79
|
+
__decorate([
|
|
80
|
+
(0, typeorm_1.Column)({ type: "integer", nullable: true }),
|
|
81
|
+
__metadata("design:type", Object)
|
|
82
|
+
], StudyLeaveWorkFlow.prototype, "section_id", void 0);
|
|
73
83
|
__decorate([
|
|
74
84
|
(0, typeorm_1.Column)({
|
|
75
85
|
type: "enum",
|
|
@@ -85,5 +95,5 @@ __decorate([
|
|
|
85
95
|
], StudyLeaveWorkFlow.prototype, "status_ar", void 0);
|
|
86
96
|
exports.StudyLeaveWorkFlow = StudyLeaveWorkFlow = __decorate([
|
|
87
97
|
(0, typeorm_1.Entity)({ name: "study_leave_workflows" }),
|
|
88
|
-
__metadata("design:paramtypes", [Number, String, String, Object, Object, Number, Object, Object, Object])
|
|
98
|
+
__metadata("design:paramtypes", [Number, String, String, Object, Object, Number, Object, Object, Object, Object, Object])
|
|
89
99
|
], StudyLeaveWorkFlow);
|
|
@@ -15,7 +15,9 @@ export declare class TrainingWorkFlow extends BaseModel {
|
|
|
15
15
|
approver_role_id: number | null;
|
|
16
16
|
approver_user_id: number | null;
|
|
17
17
|
approved_by: number | null;
|
|
18
|
+
department_id: number | null;
|
|
19
|
+
section_id: number | null;
|
|
18
20
|
status: TrainingWorkFlowStatus;
|
|
19
21
|
status_ar: string | null;
|
|
20
|
-
constructor(request_id: number, content: string, status: TrainingWorkFlowStatus, service_id?: number | null, sub_service_id?: number | null, order?: number, approver_role_id?: number | null, approver_user_id?: number | null, approved_by?: number | null);
|
|
22
|
+
constructor(request_id: number, content: string, status: TrainingWorkFlowStatus, service_id?: number | null, sub_service_id?: number | null, order?: number, approver_role_id?: number | null, approver_user_id?: number | null, approved_by?: number | null, department_id?: number | null, section_id?: number | null);
|
|
21
23
|
}
|
|
@@ -20,7 +20,7 @@ var TrainingWorkFlowStatus;
|
|
|
20
20
|
TrainingWorkFlowStatus["REJECTED"] = "Rejected";
|
|
21
21
|
})(TrainingWorkFlowStatus || (exports.TrainingWorkFlowStatus = TrainingWorkFlowStatus = {}));
|
|
22
22
|
let TrainingWorkFlow = class TrainingWorkFlow extends BaseModel_1.BaseModel {
|
|
23
|
-
constructor(request_id, content, status, service_id, sub_service_id, order, approver_role_id, approver_user_id, approved_by) {
|
|
23
|
+
constructor(request_id, content, status, service_id, sub_service_id, order, approver_role_id, approver_user_id, approved_by, department_id, section_id) {
|
|
24
24
|
super();
|
|
25
25
|
this.request_id = request_id;
|
|
26
26
|
this.service_id = service_id || null;
|
|
@@ -31,6 +31,8 @@ let TrainingWorkFlow = class TrainingWorkFlow extends BaseModel_1.BaseModel {
|
|
|
31
31
|
this.approver_role_id = approver_role_id || null;
|
|
32
32
|
this.approver_user_id = approver_user_id || null;
|
|
33
33
|
this.approved_by = approved_by || null;
|
|
34
|
+
this.department_id = department_id || null;
|
|
35
|
+
this.section_id = section_id || null;
|
|
34
36
|
}
|
|
35
37
|
};
|
|
36
38
|
exports.TrainingWorkFlow = TrainingWorkFlow;
|
|
@@ -70,6 +72,14 @@ __decorate([
|
|
|
70
72
|
(0, typeorm_1.Column)({ type: "integer", nullable: true }),
|
|
71
73
|
__metadata("design:type", Object)
|
|
72
74
|
], TrainingWorkFlow.prototype, "approved_by", void 0);
|
|
75
|
+
__decorate([
|
|
76
|
+
(0, typeorm_1.Column)({ type: "integer", nullable: true }),
|
|
77
|
+
__metadata("design:type", Object)
|
|
78
|
+
], TrainingWorkFlow.prototype, "department_id", void 0);
|
|
79
|
+
__decorate([
|
|
80
|
+
(0, typeorm_1.Column)({ type: "integer", nullable: true }),
|
|
81
|
+
__metadata("design:type", Object)
|
|
82
|
+
], TrainingWorkFlow.prototype, "section_id", void 0);
|
|
73
83
|
__decorate([
|
|
74
84
|
(0, typeorm_1.Column)({
|
|
75
85
|
type: "enum",
|
|
@@ -85,5 +95,5 @@ __decorate([
|
|
|
85
95
|
], TrainingWorkFlow.prototype, "status_ar", void 0);
|
|
86
96
|
exports.TrainingWorkFlow = TrainingWorkFlow = __decorate([
|
|
87
97
|
(0, typeorm_1.Entity)({ name: "training_workflows" }),
|
|
88
|
-
__metadata("design:paramtypes", [Number, String, String, Object, Object, Number, Object, Object, Object])
|
|
98
|
+
__metadata("design:paramtypes", [Number, String, String, Object, Object, Number, Object, Object, Object, Object, Object])
|
|
89
99
|
], TrainingWorkFlow);
|
package/package.json
CHANGED
|
@@ -9,6 +9,9 @@ ALTER TYPE asset_maintenance_category_en ADD VALUE IF NOT EXISTS 'Other';
|
|
|
9
9
|
ALTER TABLE residential_unit_rental_requests
|
|
10
10
|
ALTER COLUMN preferred_start_date DROP NOT NULL;
|
|
11
11
|
|
|
12
|
+
ALTER TABLE residential_unit_rental_requests
|
|
13
|
+
ADD COLUMN IF NOT EXISTS number_of_apartments VARCHAR(255);
|
|
14
|
+
|
|
12
15
|
-- 3. Appeal against administrative decision: optional / removed payload fields
|
|
13
16
|
ALTER TABLE appeal_against_administrative_decision_requests
|
|
14
17
|
ALTER COLUMN description DROP NOT NULL,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side JWT session binding (CAA VAPT M003/M004).
|
|
3
|
+
* JWT remains valid cryptographically until exp; access is allowed only while
|
|
4
|
+
* the bound user_sessions row is active and not expired.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export type UserSessionReader = {
|
|
8
|
+
isSessionActiveById(sessionId: number, userId: number): Promise<boolean>;
|
|
9
|
+
/** Legacy fallback when REQUIRE_JWT_SESSION_ID=false and token has no sessionId. */
|
|
10
|
+
isSessionActive?(userId: number): Promise<unknown>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** When true (default), JWT must include sessionId and that session must be active. */
|
|
14
|
+
export function isRequireJwtSessionId(): boolean {
|
|
15
|
+
const raw = (process.env.REQUIRE_JWT_SESSION_ID ?? 'true').trim().toLowerCase();
|
|
16
|
+
return raw !== 'false' && raw !== '0' && raw !== 'no';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function resolveJwtSessionId(sessionId: unknown): number | null {
|
|
20
|
+
if (sessionId == null || sessionId === '') return null;
|
|
21
|
+
const sid = Number(sessionId);
|
|
22
|
+
if (!Number.isFinite(sid) || sid <= 0) return null;
|
|
23
|
+
return sid;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Validate that a verified JWT is still authorized (not logged out / expired server-side).
|
|
28
|
+
*/
|
|
29
|
+
export async function validateUserSessionBinding(
|
|
30
|
+
userId: number,
|
|
31
|
+
sessionId: number | null | undefined,
|
|
32
|
+
reader: UserSessionReader,
|
|
33
|
+
): Promise<boolean> {
|
|
34
|
+
if (!Number.isFinite(userId) || userId <= 0) return false;
|
|
35
|
+
|
|
36
|
+
const sid = resolveJwtSessionId(sessionId);
|
|
37
|
+
if (sid != null) {
|
|
38
|
+
return reader.isSessionActiveById(sid, userId);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (isRequireJwtSessionId()) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!reader.isSessionActive) return false;
|
|
46
|
+
const legacy = await reader.isSessionActive(userId);
|
|
47
|
+
return !!legacy;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Shared TypeORM filters: active, not deleted, not past expires_at. */
|
|
51
|
+
export function activeUserSessionSql(alias = 'user_sessions'): {
|
|
52
|
+
clause: string;
|
|
53
|
+
params: Record<string, unknown>;
|
|
54
|
+
} {
|
|
55
|
+
return {
|
|
56
|
+
clause: `${alias}.is_active = :is_active AND ${alias}.is_deleted = :is_deleted AND (${alias}.expires_at IS NULL OR ${alias}.expires_at > :session_now)`,
|
|
57
|
+
params: {
|
|
58
|
+
is_active: true,
|
|
59
|
+
is_deleted: false,
|
|
60
|
+
session_now: new Date(),
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { JobTransferRequestStatus } from './models/JobTransferRequestModel';
|
|
|
3
3
|
export * from './models/user';
|
|
4
4
|
export * from './models/role';
|
|
5
5
|
export * from './models/user-sessions';
|
|
6
|
+
export * from './auth/user-session-validation';
|
|
6
7
|
export * from './models/ITHelpDeskModel';
|
|
7
8
|
// export * from './models/ITServicesTypesSalalahModel'; // REMOVED - table no longer used
|
|
8
9
|
// export * from './models/ITServicesTypesMuscatModel'; // REMOVED - table no longer used
|
|
@@ -113,8 +113,8 @@ export class ResidentialUnitRentalRequest extends BaseModel {
|
|
|
113
113
|
|
|
114
114
|
location_of_unit: string;
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
@Column({ type: 'varchar', length: 255, nullable: true })
|
|
117
|
+
number_of_apartments: string | null;
|
|
118
118
|
|
|
119
119
|
@Column({ type: 'text', nullable: true })
|
|
120
120
|
|
|
@@ -37,6 +37,12 @@ export class StudyLeaveWorkFlow extends BaseModel {
|
|
|
37
37
|
@Column({ type: "integer", nullable: true })
|
|
38
38
|
approved_by: number | null;
|
|
39
39
|
|
|
40
|
+
@Column({ type: "integer", nullable: true })
|
|
41
|
+
department_id: number | null;
|
|
42
|
+
|
|
43
|
+
@Column({ type: "integer", nullable: true })
|
|
44
|
+
section_id: number | null;
|
|
45
|
+
|
|
40
46
|
@Column({
|
|
41
47
|
type: "enum",
|
|
42
48
|
enum: StudyLeaveWorkFlowStatus,
|
|
@@ -57,7 +63,9 @@ export class StudyLeaveWorkFlow extends BaseModel {
|
|
|
57
63
|
order?: number,
|
|
58
64
|
approver_role_id?: number | null,
|
|
59
65
|
approver_user_id?: number | null,
|
|
60
|
-
approved_by?: number | null
|
|
66
|
+
approved_by?: number | null,
|
|
67
|
+
department_id?: number | null,
|
|
68
|
+
section_id?: number | null
|
|
61
69
|
) {
|
|
62
70
|
super();
|
|
63
71
|
this.request_id = request_id;
|
|
@@ -69,6 +77,8 @@ export class StudyLeaveWorkFlow extends BaseModel {
|
|
|
69
77
|
this.approver_role_id = approver_role_id || null;
|
|
70
78
|
this.approver_user_id = approver_user_id || null;
|
|
71
79
|
this.approved_by = approved_by || null;
|
|
80
|
+
this.department_id = department_id || null;
|
|
81
|
+
this.section_id = section_id || null;
|
|
72
82
|
}
|
|
73
83
|
}
|
|
74
84
|
|
|
@@ -37,6 +37,12 @@ export class TrainingWorkFlow extends BaseModel {
|
|
|
37
37
|
@Column({ type: "integer", nullable: true })
|
|
38
38
|
approved_by: number | null;
|
|
39
39
|
|
|
40
|
+
@Column({ type: "integer", nullable: true })
|
|
41
|
+
department_id: number | null;
|
|
42
|
+
|
|
43
|
+
@Column({ type: "integer", nullable: true })
|
|
44
|
+
section_id: number | null;
|
|
45
|
+
|
|
40
46
|
@Column({
|
|
41
47
|
type: "enum",
|
|
42
48
|
enum: TrainingWorkFlowStatus,
|
|
@@ -57,7 +63,9 @@ export class TrainingWorkFlow extends BaseModel {
|
|
|
57
63
|
order?: number,
|
|
58
64
|
approver_role_id?: number | null,
|
|
59
65
|
approver_user_id?: number | null,
|
|
60
|
-
approved_by?: number | null
|
|
66
|
+
approved_by?: number | null,
|
|
67
|
+
department_id?: number | null,
|
|
68
|
+
section_id?: number | null
|
|
61
69
|
) {
|
|
62
70
|
super();
|
|
63
71
|
this.request_id = request_id;
|
|
@@ -69,6 +77,8 @@ export class TrainingWorkFlow extends BaseModel {
|
|
|
69
77
|
this.approver_role_id = approver_role_id || null;
|
|
70
78
|
this.approver_user_id = approver_user_id || null;
|
|
71
79
|
this.approved_by = approved_by || null;
|
|
80
|
+
this.department_id = department_id || null;
|
|
81
|
+
this.section_id = section_id || null;
|
|
72
82
|
}
|
|
73
83
|
}
|
|
74
84
|
|