@platform-modules/civil-aviation-authority 2.3.312 → 2.3.314
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/data-source.js +2 -0
- package/dist/helpers/cancellation-bilingual-persist.helper.d.ts +37 -0
- package/dist/helpers/cancellation-bilingual-persist.helper.js +77 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models/IconsModel.d.ts +7 -0
- package/dist/models/IconsModel.js +39 -0
- package/dist/models/SlaApprovalsViewModel.js +54 -54
- package/dist/models/importantLinksModel.d.ts +1 -0
- package/dist/models/importantLinksModel.js +5 -0
- package/package.json +1 -1
- package/scripts/sync-sla-reports-sql.js +92 -92
- package/sql/README.md +21 -21
- package/sql/add_important_links_icon_id.sql +17 -0
- package/sql/create_icons.sql +21 -0
- package/sql/sla_reports_admin_procedures.sql +322 -323
- package/sql/sla_reports_approvals_workbook.sql +427 -430
- package/sql/sla_reports_procedures.sql +883 -886
- package/sql/vw_sla_approvals.sql +115 -115
- package/sql/vw_sla_my_requests.sql +58 -58
- package/src/data-source.ts +2 -0
- package/src/index.ts +1 -0
- package/src/models/AccessCardRequestModel.ts +135 -135
- package/src/models/AirportEntryPermitModel.ts +276 -276
- package/src/models/AnnualTrainingPlanRequestModel.ts +153 -153
- package/src/models/DocumentDriveModel.ts +28 -28
- package/src/models/DocumentFolderModel.ts +45 -45
- package/src/models/HotelApprovalModel.ts +83 -83
- package/src/models/HousingContractCancelApprovalModel.ts +64 -64
- package/src/models/HousingContractRenewalApprovalModel.ts +64 -64
- package/src/models/ITRequestAttachmentModel.ts +73 -73
- package/src/models/IconsModel.ts +21 -0
- package/src/models/ItApprovalsModel.ts +84 -84
- package/src/models/LegalConsultationApprovalModel.ts +65 -65
- package/src/models/MissionTravelPassportExpiryNotificationConfigModel.ts +36 -36
- package/src/models/NotificationModel.ts +89 -89
- package/src/models/ResidentialUnitRentalApprovalModel.ts +143 -143
- package/src/models/ServiceExtensionAfter60ApprovalModel.ts +87 -87
- package/src/models/ServiceSlaApprovalModel.ts +64 -64
- package/src/models/ServicesNotificationConfigModel.ts +55 -55
- package/src/models/SlaApprovalsViewModel.ts +142 -142
- package/src/models/StudyLeaveRequestModel.ts +144 -144
- package/src/models/TrainingRequestModel.ts +164 -164
- package/src/models/TrainingRoomBookingRequestModel.ts +142 -142
- package/src/models/TrainingRoomNotificationConfigModel.ts +30 -30
- package/src/models/importantLinksModel.ts +4 -0
- package/src/models/role.ts +34 -34
- package/src/sla/sla-table-sync.service.ts +90 -90
- package/dist/models/DocumentMetadataModel.d.ts +0 -45
- package/dist/models/DocumentMetadataModel.js +0 -171
- package/dist/models/DocumentationDepartmentsModel.d.ts +0 -13
- package/dist/models/DocumentationDepartmentsModel.js +0 -53
- package/dist/models/FolderModel.d.ts +0 -16
- package/dist/models/FolderModel.js +0 -85
- package/dist/models/ImportExportMaterialModels.d.ts +0 -92
- package/dist/models/ImportExportMaterialModels.js +0 -307
- package/dist/models/PermissionModel.d.ts +0 -18
- package/dist/models/PermissionModel.js +0 -68
- package/dist/models/SecurityAccessApprovalModel.d.ts +0 -23
- package/dist/models/SecurityAccessApprovalModel.js +0 -82
- package/dist/models/SecurityAccessAttachmentModel.d.ts +0 -12
- package/dist/models/SecurityAccessAttachmentModel.js +0 -56
- package/dist/models/SecurityAccessChatModel.d.ts +0 -12
- package/dist/models/SecurityAccessChatModel.js +0 -56
- package/dist/models/SecurityAccessRequestModel.d.ts +0 -25
- package/dist/models/SecurityAccessRequestModel.js +0 -80
- package/dist/models/SecurityAccessWorkflowModel.d.ts +0 -24
- package/dist/models/SecurityAccessWorkflowModel.js +0 -84
- package/dist/models/ServiceExtensionAfterAge60Models.d.ts +0 -93
- package/dist/models/ServiceExtensionAfterAge60Models.js +0 -312
- package/dist/models/UUIDBaseModel.d.ts +0 -14
- package/dist/models/UUIDBaseModel.js +0 -66
- package/dist/models/WorkingHoursExtensionModels.d.ts +0 -88
- package/dist/models/WorkingHoursExtensionModels.js +0 -295
package/dist/data-source.js
CHANGED
|
@@ -257,6 +257,7 @@ const SlaApprovalsViewModel_1 = require("./models/SlaApprovalsViewModel");
|
|
|
257
257
|
const ServiceSlaApprovalModel_1 = require("./models/ServiceSlaApprovalModel");
|
|
258
258
|
const SlaConfigModel_1 = require("./models/SlaConfigModel");
|
|
259
259
|
const ChatbotQnsAnsMappingModel_1 = require("./models/ChatbotQnsAnsMappingModel");
|
|
260
|
+
const IconsModel_1 = require("./models/IconsModel");
|
|
260
261
|
const CSRMBusinessImpactRatingMasterModel_1 = require("./models/CSRMBusinessImpactRatingMasterModel");
|
|
261
262
|
const CSRMLikelihoodMasterModel_1 = require("./models/CSRMLikelihoodMasterModel");
|
|
262
263
|
const LocationModel_1 = require("./models/LocationModel");
|
|
@@ -581,6 +582,7 @@ exports.AppDataSource = new typeorm_1.DataSource({
|
|
|
581
582
|
ServiceSlaApprovalModel_1.ServiceSlaApproval,
|
|
582
583
|
SlaConfigModel_1.SlaConfig,
|
|
583
584
|
ChatbotQnsAnsMappingModel_1.ChatbotQnsAnsMapping,
|
|
585
|
+
IconsModel_1.Icons,
|
|
584
586
|
CSRMBusinessImpactRatingMasterModel_1.CSRMBusinessImpactRatingMaster,
|
|
585
587
|
CSRMLikelihoodMasterModel_1.CSRMLikelihoodMaster,
|
|
586
588
|
LocationModel_1.Location,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { EntityManager } from 'typeorm';
|
|
2
|
+
import { CancellationMessageType } from '../models/CancellationChatModel';
|
|
3
|
+
import { CancellationWorkFlowStatus } from '../models/CancellationWorkflowModel';
|
|
4
|
+
export type CancellationWorkflowRowInput = {
|
|
5
|
+
request_id: number;
|
|
6
|
+
service_id?: number | null;
|
|
7
|
+
sub_service_id?: number | null;
|
|
8
|
+
content: string;
|
|
9
|
+
content_ar?: string | null;
|
|
10
|
+
status: CancellationWorkFlowStatus;
|
|
11
|
+
status_ar?: string | null;
|
|
12
|
+
user_id?: number | null;
|
|
13
|
+
role_id?: number | null;
|
|
14
|
+
department_id?: number | null;
|
|
15
|
+
section_id?: number | null;
|
|
16
|
+
step_order?: number | null;
|
|
17
|
+
created_by?: number | null;
|
|
18
|
+
};
|
|
19
|
+
export type CancellationChatRowInput = {
|
|
20
|
+
request_id: number;
|
|
21
|
+
service_id?: number | null;
|
|
22
|
+
sub_service_id?: number | null;
|
|
23
|
+
user_id: number;
|
|
24
|
+
role_id?: number | null;
|
|
25
|
+
message: string;
|
|
26
|
+
message_ar?: string | null;
|
|
27
|
+
messageType?: CancellationMessageType;
|
|
28
|
+
status?: string | null;
|
|
29
|
+
status_ar?: string | null;
|
|
30
|
+
created_by?: number | string | null;
|
|
31
|
+
};
|
|
32
|
+
/** Force-persist Arabic workflow columns (guards against stale TypeORM entity metadata). */
|
|
33
|
+
export declare function patchCancellationWorkflowArabic(manager: EntityManager, workflowId: number, contentAr: string | null, statusAr: string | null): Promise<void>;
|
|
34
|
+
/** Force-persist Arabic chat columns (guards against stale TypeORM entity metadata). */
|
|
35
|
+
export declare function patchCancellationChatArabic(manager: EntityManager, chatId: number, messageAr: string | null, statusAr: string | null): Promise<void>;
|
|
36
|
+
export declare function insertCancellationWorkflowRow(manager: EntityManager, input: CancellationWorkflowRowInput): Promise<number>;
|
|
37
|
+
export declare function insertCancellationChatRow(manager: EntityManager, input: CancellationChatRowInput): Promise<number>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.patchCancellationWorkflowArabic = patchCancellationWorkflowArabic;
|
|
4
|
+
exports.patchCancellationChatArabic = patchCancellationChatArabic;
|
|
5
|
+
exports.insertCancellationWorkflowRow = insertCancellationWorkflowRow;
|
|
6
|
+
exports.insertCancellationChatRow = insertCancellationChatRow;
|
|
7
|
+
const CancellationChatModel_1 = require("../models/CancellationChatModel");
|
|
8
|
+
const CancellationWorkflowModel_1 = require("../models/CancellationWorkflowModel");
|
|
9
|
+
const workflow_chat_i18n_1 = require("../i18n/workflow-chat-i18n");
|
|
10
|
+
function resolveWorkflowRowId(insertResult) {
|
|
11
|
+
const id = insertResult.raw?.[0]?.id ?? insertResult.identifiers?.[0]?.id;
|
|
12
|
+
if (!id) {
|
|
13
|
+
throw new Error('Failed to insert cancellation workflow row');
|
|
14
|
+
}
|
|
15
|
+
return id;
|
|
16
|
+
}
|
|
17
|
+
function resolveChatRowId(insertResult) {
|
|
18
|
+
const id = insertResult.raw?.[0]?.id ?? insertResult.identifiers?.[0]?.id;
|
|
19
|
+
if (!id) {
|
|
20
|
+
throw new Error('Failed to insert cancellation chat row');
|
|
21
|
+
}
|
|
22
|
+
return id;
|
|
23
|
+
}
|
|
24
|
+
/** Force-persist Arabic workflow columns (guards against stale TypeORM entity metadata). */
|
|
25
|
+
async function patchCancellationWorkflowArabic(manager, workflowId, contentAr, statusAr) {
|
|
26
|
+
await manager.query(`UPDATE cancellation_workflows
|
|
27
|
+
SET content_ar = $1,
|
|
28
|
+
status_ar = $2,
|
|
29
|
+
updated_at = CURRENT_TIMESTAMP
|
|
30
|
+
WHERE id = $3`, [contentAr, statusAr, workflowId]);
|
|
31
|
+
}
|
|
32
|
+
/** Force-persist Arabic chat columns (guards against stale TypeORM entity metadata). */
|
|
33
|
+
async function patchCancellationChatArabic(manager, chatId, messageAr, statusAr) {
|
|
34
|
+
await manager.query(`UPDATE cancellation_chats
|
|
35
|
+
SET message_ar = $1,
|
|
36
|
+
status_ar = $2,
|
|
37
|
+
updated_at = CURRENT_TIMESTAMP
|
|
38
|
+
WHERE id = $3`, [messageAr, statusAr, chatId]);
|
|
39
|
+
}
|
|
40
|
+
async function insertCancellationWorkflowRow(manager, input) {
|
|
41
|
+
const contentAr = input.content_ar ?? null;
|
|
42
|
+
const statusAr = input.status_ar ?? (0, workflow_chat_i18n_1.resolveWorkflowStatusAr)(input.status);
|
|
43
|
+
const insertResult = await manager
|
|
44
|
+
.createQueryBuilder()
|
|
45
|
+
.insert()
|
|
46
|
+
.into(CancellationWorkflowModel_1.CancellationWorkFlow)
|
|
47
|
+
.values({
|
|
48
|
+
...input,
|
|
49
|
+
content_ar: contentAr,
|
|
50
|
+
status_ar: statusAr,
|
|
51
|
+
})
|
|
52
|
+
.returning('id')
|
|
53
|
+
.execute();
|
|
54
|
+
const id = resolveWorkflowRowId(insertResult);
|
|
55
|
+
await patchCancellationWorkflowArabic(manager, id, contentAr, statusAr);
|
|
56
|
+
return id;
|
|
57
|
+
}
|
|
58
|
+
async function insertCancellationChatRow(manager, input) {
|
|
59
|
+
const messageAr = input.message_ar ?? null;
|
|
60
|
+
const statusAr = input.status_ar ?? (0, workflow_chat_i18n_1.resolveChatStatusAr)(input.status ?? null);
|
|
61
|
+
const messageType = input.messageType ?? CancellationChatModel_1.CancellationMessageType.TEXT;
|
|
62
|
+
const insertResult = await manager
|
|
63
|
+
.createQueryBuilder()
|
|
64
|
+
.insert()
|
|
65
|
+
.into(CancellationChatModel_1.CancellationRequestChat)
|
|
66
|
+
.values({
|
|
67
|
+
...input,
|
|
68
|
+
message_ar: messageAr,
|
|
69
|
+
status_ar: statusAr,
|
|
70
|
+
messageType,
|
|
71
|
+
})
|
|
72
|
+
.returning('id')
|
|
73
|
+
.execute();
|
|
74
|
+
const id = resolveChatRowId(insertResult);
|
|
75
|
+
await patchCancellationChatArabic(manager, id, messageAr, statusAr);
|
|
76
|
+
return id;
|
|
77
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -415,6 +415,7 @@ export * from './models/ContractServiceRequestModel';
|
|
|
415
415
|
export * from './models/ContractServiceRequestDocumentModel';
|
|
416
416
|
export * from './models/SlaConfigModel';
|
|
417
417
|
export * from './models/ChatbotQnsAnsMappingModel';
|
|
418
|
+
export * from './models/IconsModel';
|
|
418
419
|
export * from './models/SlaRequestModel';
|
|
419
420
|
export * from './models/SlaMyRequestsViewModel';
|
|
420
421
|
export * from './models/SlaApprovalsViewModel';
|
package/dist/index.js
CHANGED
|
@@ -604,6 +604,7 @@ __exportStar(require("./models/ContractServiceRequestModel"), exports);
|
|
|
604
604
|
__exportStar(require("./models/ContractServiceRequestDocumentModel"), exports);
|
|
605
605
|
__exportStar(require("./models/SlaConfigModel"), exports);
|
|
606
606
|
__exportStar(require("./models/ChatbotQnsAnsMappingModel"), exports);
|
|
607
|
+
__exportStar(require("./models/IconsModel"), exports);
|
|
607
608
|
__exportStar(require("./models/SlaRequestModel"), exports);
|
|
608
609
|
__exportStar(require("./models/SlaMyRequestsViewModel"), exports);
|
|
609
610
|
__exportStar(require("./models/SlaApprovalsViewModel"), exports);
|
|
@@ -0,0 +1,39 @@
|
|
|
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.Icons = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const BaseModel_1 = require("./BaseModel");
|
|
15
|
+
let Icons = class Icons extends BaseModel_1.BaseModel {
|
|
16
|
+
constructor(icon_name, url) {
|
|
17
|
+
super();
|
|
18
|
+
this.icon_name = icon_name;
|
|
19
|
+
this.url = url;
|
|
20
|
+
this.icon_name_arabic = null;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
exports.Icons = Icons;
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, typeorm_1.Column)({ type: "varchar", length: 255, nullable: false }),
|
|
26
|
+
__metadata("design:type", String)
|
|
27
|
+
], Icons.prototype, "icon_name", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, typeorm_1.Column)({ type: "varchar", length: 255, nullable: true }),
|
|
30
|
+
__metadata("design:type", Object)
|
|
31
|
+
], Icons.prototype, "icon_name_arabic", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, typeorm_1.Column)({ type: "varchar", length: 2000, nullable: false }),
|
|
34
|
+
__metadata("design:type", String)
|
|
35
|
+
], Icons.prototype, "url", void 0);
|
|
36
|
+
exports.Icons = Icons = __decorate([
|
|
37
|
+
(0, typeorm_1.Entity)({ name: "icons" }),
|
|
38
|
+
__metadata("design:paramtypes", [String, String])
|
|
39
|
+
], Icons);
|
|
@@ -11,60 +11,60 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.SlaApprovalsView = void 0;
|
|
13
13
|
const typeorm_1 = require("typeorm");
|
|
14
|
-
const VW_SLA_APPROVALS_SQL = `
|
|
15
|
-
SELECT
|
|
16
|
-
sa.id AS sla_approval_id,
|
|
17
|
-
sa.source_approval_id,
|
|
18
|
-
sa.request_id,
|
|
19
|
-
sa.service_id AS service_id,
|
|
20
|
-
sa.sub_service_id AS sub_service_id,
|
|
21
|
-
TRIM(COALESCE(svc.name, ''))::TEXT AS service_name,
|
|
22
|
-
TRIM(COALESCE(subsvc.sub_service_name, ''))::TEXT AS sub_service_name,
|
|
23
|
-
sa.approver_role_id AS approval_role_id,
|
|
24
|
-
TRIM(COALESCE(ar.name, ''))::TEXT AS approval_role_name,
|
|
25
|
-
sa.department_id AS approval_department_id,
|
|
26
|
-
TRIM(COALESCE(adpt.department_name, ''))::TEXT AS approval_department_name,
|
|
27
|
-
sa.section_id AS approval_section_id,
|
|
28
|
-
TRIM(COALESCE(asec.section_name, ''))::TEXT AS approval_section_name,
|
|
29
|
-
sa.approval_status::TEXT AS approval_status,
|
|
30
|
-
sr.status::TEXT AS request_status,
|
|
31
|
-
sa.level AS level,
|
|
32
|
-
sa.approver_user_id AS approver_user_id,
|
|
33
|
-
TRIM(COALESCE(au.employee_name, ''))::TEXT AS approver_user_name,
|
|
34
|
-
sa.delegate_user_id AS delegate_user_id,
|
|
35
|
-
TRIM(COALESCE(du.employee_name, ''))::TEXT AS delegate_user_name,
|
|
36
|
-
sa.approved_by AS approved_by,
|
|
37
|
-
TRIM(COALESCE(ab.employee_name, ''))::TEXT AS approved_by_name,
|
|
38
|
-
sa.comment::TEXT AS comment,
|
|
39
|
-
sa.created_at AS created_at,
|
|
40
|
-
sa.updated_at AS updated_at
|
|
41
|
-
FROM sla_approval sa
|
|
42
|
-
INNER JOIN sla_requests sr
|
|
43
|
-
ON sr.id = (
|
|
44
|
-
SELECT MIN(sr2.id)
|
|
45
|
-
FROM sla_requests sr2
|
|
46
|
-
WHERE sr2.request_id = sa.request_id
|
|
47
|
-
AND COALESCE(sr2.is_deleted, false) = false
|
|
48
|
-
AND (sa.service_id IS NULL OR sr2.service_id = sa.service_id)
|
|
49
|
-
AND (sa.sub_service_id IS NULL OR sr2.sub_service_id = sa.sub_service_id)
|
|
50
|
-
)
|
|
51
|
-
LEFT JOIN caa_services svc
|
|
52
|
-
ON svc.id = sa.service_id AND COALESCE(svc.is_deleted, false) = false
|
|
53
|
-
LEFT JOIN caa_sub_services subsvc
|
|
54
|
-
ON subsvc.id = sa.sub_service_id AND COALESCE(subsvc.is_deleted, false) = false
|
|
55
|
-
LEFT JOIN departments adpt
|
|
56
|
-
ON adpt.id = sa.department_id AND COALESCE(adpt.is_deleted, false) = false
|
|
57
|
-
LEFT JOIN sections asec
|
|
58
|
-
ON asec.id = sa.section_id AND COALESCE(asec.is_deleted, false) = false
|
|
59
|
-
LEFT JOIN role ar
|
|
60
|
-
ON ar.id = sa.approver_role_id AND COALESCE(ar.is_deleted, false) = false
|
|
61
|
-
LEFT JOIN users au
|
|
62
|
-
ON au.id = sa.approver_user_id AND COALESCE(au.is_deleted, false) = false
|
|
63
|
-
LEFT JOIN users du
|
|
64
|
-
ON du.id = sa.delegate_user_id AND COALESCE(du.is_deleted, false) = false
|
|
65
|
-
LEFT JOIN users ab
|
|
66
|
-
ON ab.id = sa.approved_by AND COALESCE(ab.is_deleted, false) = false
|
|
67
|
-
WHERE COALESCE(sa.is_deleted, false) = false
|
|
14
|
+
const VW_SLA_APPROVALS_SQL = `
|
|
15
|
+
SELECT
|
|
16
|
+
sa.id AS sla_approval_id,
|
|
17
|
+
sa.source_approval_id,
|
|
18
|
+
sa.request_id,
|
|
19
|
+
sa.service_id AS service_id,
|
|
20
|
+
sa.sub_service_id AS sub_service_id,
|
|
21
|
+
TRIM(COALESCE(svc.name, ''))::TEXT AS service_name,
|
|
22
|
+
TRIM(COALESCE(subsvc.sub_service_name, ''))::TEXT AS sub_service_name,
|
|
23
|
+
sa.approver_role_id AS approval_role_id,
|
|
24
|
+
TRIM(COALESCE(ar.name, ''))::TEXT AS approval_role_name,
|
|
25
|
+
sa.department_id AS approval_department_id,
|
|
26
|
+
TRIM(COALESCE(adpt.department_name, ''))::TEXT AS approval_department_name,
|
|
27
|
+
sa.section_id AS approval_section_id,
|
|
28
|
+
TRIM(COALESCE(asec.section_name, ''))::TEXT AS approval_section_name,
|
|
29
|
+
sa.approval_status::TEXT AS approval_status,
|
|
30
|
+
sr.status::TEXT AS request_status,
|
|
31
|
+
sa.level AS level,
|
|
32
|
+
sa.approver_user_id AS approver_user_id,
|
|
33
|
+
TRIM(COALESCE(au.employee_name, ''))::TEXT AS approver_user_name,
|
|
34
|
+
sa.delegate_user_id AS delegate_user_id,
|
|
35
|
+
TRIM(COALESCE(du.employee_name, ''))::TEXT AS delegate_user_name,
|
|
36
|
+
sa.approved_by AS approved_by,
|
|
37
|
+
TRIM(COALESCE(ab.employee_name, ''))::TEXT AS approved_by_name,
|
|
38
|
+
sa.comment::TEXT AS comment,
|
|
39
|
+
sa.created_at AS created_at,
|
|
40
|
+
sa.updated_at AS updated_at
|
|
41
|
+
FROM sla_approval sa
|
|
42
|
+
INNER JOIN sla_requests sr
|
|
43
|
+
ON sr.id = (
|
|
44
|
+
SELECT MIN(sr2.id)
|
|
45
|
+
FROM sla_requests sr2
|
|
46
|
+
WHERE sr2.request_id = sa.request_id
|
|
47
|
+
AND COALESCE(sr2.is_deleted, false) = false
|
|
48
|
+
AND (sa.service_id IS NULL OR sr2.service_id = sa.service_id)
|
|
49
|
+
AND (sa.sub_service_id IS NULL OR sr2.sub_service_id = sa.sub_service_id)
|
|
50
|
+
)
|
|
51
|
+
LEFT JOIN caa_services svc
|
|
52
|
+
ON svc.id = sa.service_id AND COALESCE(svc.is_deleted, false) = false
|
|
53
|
+
LEFT JOIN caa_sub_services subsvc
|
|
54
|
+
ON subsvc.id = sa.sub_service_id AND COALESCE(subsvc.is_deleted, false) = false
|
|
55
|
+
LEFT JOIN departments adpt
|
|
56
|
+
ON adpt.id = sa.department_id AND COALESCE(adpt.is_deleted, false) = false
|
|
57
|
+
LEFT JOIN sections asec
|
|
58
|
+
ON asec.id = sa.section_id AND COALESCE(asec.is_deleted, false) = false
|
|
59
|
+
LEFT JOIN role ar
|
|
60
|
+
ON ar.id = sa.approver_role_id AND COALESCE(ar.is_deleted, false) = false
|
|
61
|
+
LEFT JOIN users au
|
|
62
|
+
ON au.id = sa.approver_user_id AND COALESCE(au.is_deleted, false) = false
|
|
63
|
+
LEFT JOIN users du
|
|
64
|
+
ON du.id = sa.delegate_user_id AND COALESCE(du.is_deleted, false) = false
|
|
65
|
+
LEFT JOIN users ab
|
|
66
|
+
ON ab.id = sa.approved_by AND COALESCE(ab.is_deleted, false) = false
|
|
67
|
+
WHERE COALESCE(sa.is_deleted, false) = false
|
|
68
68
|
`;
|
|
69
69
|
/**
|
|
70
70
|
* Read-only view for SLA approvals listings (TypeORM).
|
|
@@ -17,6 +17,7 @@ let ImportantLinks = class ImportantLinks extends BaseModel_1.BaseModel {
|
|
|
17
17
|
super();
|
|
18
18
|
this.title = title;
|
|
19
19
|
this.url = url;
|
|
20
|
+
this.icon_id = null;
|
|
20
21
|
}
|
|
21
22
|
};
|
|
22
23
|
exports.ImportantLinks = ImportantLinks;
|
|
@@ -28,6 +29,10 @@ __decorate([
|
|
|
28
29
|
(0, typeorm_1.Column)({ type: 'varchar', nullable: false }),
|
|
29
30
|
__metadata("design:type", String)
|
|
30
31
|
], ImportantLinks.prototype, "url", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, typeorm_1.Column)({ type: 'integer', nullable: true }),
|
|
34
|
+
__metadata("design:type", Object)
|
|
35
|
+
], ImportantLinks.prototype, "icon_id", void 0);
|
|
31
36
|
exports.ImportantLinks = ImportantLinks = __decorate([
|
|
32
37
|
(0, typeorm_1.Entity)({ name: 'important_links' }),
|
|
33
38
|
__metadata("design:paramtypes", [String, String])
|
package/package.json
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Applies SLA report views + stored procedures to PostgreSQL (idempotent CREATE OR REPLACE).
|
|
3
|
-
*
|
|
4
|
-
* Env from shared_models/.env only:
|
|
5
|
-
* DB_HOST / TYPEORM_HOST
|
|
6
|
-
* DB_PORT / TYPEORM_PORT
|
|
7
|
-
* DB_USER / TYPEORM_USERNAME
|
|
8
|
-
* DB_PASS / TYPEORM_PASSWORD
|
|
9
|
-
* DB_NAME / TYPEORM_DATABASE
|
|
10
|
-
*
|
|
11
|
-
* Usage:
|
|
12
|
-
* node scripts/sync-sla-reports-sql.js
|
|
13
|
-
* npm run sync:sla-sql (from shared_models)
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
const fs = require('fs');
|
|
17
|
-
const path = require('path');
|
|
18
|
-
const { Client } = require('pg');
|
|
19
|
-
|
|
20
|
-
function loadEnvFiles() {
|
|
21
|
-
const dotenv = require('dotenv');
|
|
22
|
-
const packageRoot = path.resolve(__dirname, '..');
|
|
23
|
-
const packageEnv = path.join(packageRoot, '.env');
|
|
24
|
-
|
|
25
|
-
if (!fs.existsSync(packageEnv)) {
|
|
26
|
-
throw new Error(`Missing env file: ${packageEnv}`);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
dotenv.config({ path: packageEnv, override: true });
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function getDbConfig() {
|
|
33
|
-
const host = (process.env.DB_HOST || process.env.TYPEORM_HOST || '').trim();
|
|
34
|
-
const port = parseInt(process.env.DB_PORT || process.env.TYPEORM_PORT || '5432', 10);
|
|
35
|
-
const user = (process.env.DB_USER || process.env.TYPEORM_USERNAME || '').trim();
|
|
36
|
-
const password = process.env.DB_PASS || process.env.TYPEORM_PASSWORD || '';
|
|
37
|
-
const database = (process.env.DB_NAME || process.env.TYPEORM_DATABASE || '').trim();
|
|
38
|
-
|
|
39
|
-
if (!host || !user || !database) {
|
|
40
|
-
throw new Error(
|
|
41
|
-
'Missing DB config. Set DB_HOST, DB_USER, DB_NAME (and DB_PASS) in shared_models/.env'
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return { host, port, user, password, database };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async function main() {
|
|
49
|
-
const skipSync = process.argv.includes('--skip');
|
|
50
|
-
if (skipSync || process.env.SKIP_SLA_SQL_SYNC === 'true') {
|
|
51
|
-
console.log('[sync-sla-reports-sql] skipped (SKIP_SLA_SQL_SYNC or --skip)');
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
loadEnvFiles();
|
|
56
|
-
const config = getDbConfig();
|
|
57
|
-
const sqlDir = path.join(__dirname, '..', 'sql');
|
|
58
|
-
const manifestPath = path.join(sqlDir, 'sla-reports-sync.manifest.json');
|
|
59
|
-
|
|
60
|
-
if (!fs.existsSync(manifestPath)) {
|
|
61
|
-
throw new Error(`Manifest not found: ${manifestPath}`);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const files = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
65
|
-
if (!Array.isArray(files) || files.length === 0) {
|
|
66
|
-
throw new Error('sla-reports-sync.manifest.json must be a non-empty array');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const client = new Client(config);
|
|
70
|
-
await client.connect();
|
|
71
|
-
console.log(`[sync-sla-reports-sql] connected to ${config.host}/${config.database}`);
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
for (const file of files) {
|
|
75
|
-
const filePath = path.join(sqlDir, file);
|
|
76
|
-
if (!fs.existsSync(filePath)) {
|
|
77
|
-
throw new Error(`SQL file missing: ${filePath}`);
|
|
78
|
-
}
|
|
79
|
-
const sql = fs.readFileSync(filePath, 'utf8');
|
|
80
|
-
await client.query(sql);
|
|
81
|
-
console.log(`[sync-sla-reports-sql] applied ${file}`);
|
|
82
|
-
}
|
|
83
|
-
console.log('[sync-sla-reports-sql] done');
|
|
84
|
-
} finally {
|
|
85
|
-
await client.end();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
main().catch((err) => {
|
|
90
|
-
console.error('[sync-sla-reports-sql] failed:', err.message);
|
|
91
|
-
process.exit(1);
|
|
92
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* Applies SLA report views + stored procedures to PostgreSQL (idempotent CREATE OR REPLACE).
|
|
3
|
+
*
|
|
4
|
+
* Env from shared_models/.env only:
|
|
5
|
+
* DB_HOST / TYPEORM_HOST
|
|
6
|
+
* DB_PORT / TYPEORM_PORT
|
|
7
|
+
* DB_USER / TYPEORM_USERNAME
|
|
8
|
+
* DB_PASS / TYPEORM_PASSWORD
|
|
9
|
+
* DB_NAME / TYPEORM_DATABASE
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* node scripts/sync-sla-reports-sql.js
|
|
13
|
+
* npm run sync:sla-sql (from shared_models)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const { Client } = require('pg');
|
|
19
|
+
|
|
20
|
+
function loadEnvFiles() {
|
|
21
|
+
const dotenv = require('dotenv');
|
|
22
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
23
|
+
const packageEnv = path.join(packageRoot, '.env');
|
|
24
|
+
|
|
25
|
+
if (!fs.existsSync(packageEnv)) {
|
|
26
|
+
throw new Error(`Missing env file: ${packageEnv}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
dotenv.config({ path: packageEnv, override: true });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getDbConfig() {
|
|
33
|
+
const host = (process.env.DB_HOST || process.env.TYPEORM_HOST || '').trim();
|
|
34
|
+
const port = parseInt(process.env.DB_PORT || process.env.TYPEORM_PORT || '5432', 10);
|
|
35
|
+
const user = (process.env.DB_USER || process.env.TYPEORM_USERNAME || '').trim();
|
|
36
|
+
const password = process.env.DB_PASS || process.env.TYPEORM_PASSWORD || '';
|
|
37
|
+
const database = (process.env.DB_NAME || process.env.TYPEORM_DATABASE || '').trim();
|
|
38
|
+
|
|
39
|
+
if (!host || !user || !database) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
'Missing DB config. Set DB_HOST, DB_USER, DB_NAME (and DB_PASS) in shared_models/.env'
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return { host, port, user, password, database };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function main() {
|
|
49
|
+
const skipSync = process.argv.includes('--skip');
|
|
50
|
+
if (skipSync || process.env.SKIP_SLA_SQL_SYNC === 'true') {
|
|
51
|
+
console.log('[sync-sla-reports-sql] skipped (SKIP_SLA_SQL_SYNC or --skip)');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
loadEnvFiles();
|
|
56
|
+
const config = getDbConfig();
|
|
57
|
+
const sqlDir = path.join(__dirname, '..', 'sql');
|
|
58
|
+
const manifestPath = path.join(sqlDir, 'sla-reports-sync.manifest.json');
|
|
59
|
+
|
|
60
|
+
if (!fs.existsSync(manifestPath)) {
|
|
61
|
+
throw new Error(`Manifest not found: ${manifestPath}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const files = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
65
|
+
if (!Array.isArray(files) || files.length === 0) {
|
|
66
|
+
throw new Error('sla-reports-sync.manifest.json must be a non-empty array');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const client = new Client(config);
|
|
70
|
+
await client.connect();
|
|
71
|
+
console.log(`[sync-sla-reports-sql] connected to ${config.host}/${config.database}`);
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
for (const file of files) {
|
|
75
|
+
const filePath = path.join(sqlDir, file);
|
|
76
|
+
if (!fs.existsSync(filePath)) {
|
|
77
|
+
throw new Error(`SQL file missing: ${filePath}`);
|
|
78
|
+
}
|
|
79
|
+
const sql = fs.readFileSync(filePath, 'utf8');
|
|
80
|
+
await client.query(sql);
|
|
81
|
+
console.log(`[sync-sla-reports-sql] applied ${file}`);
|
|
82
|
+
}
|
|
83
|
+
console.log('[sync-sla-reports-sql] done');
|
|
84
|
+
} finally {
|
|
85
|
+
await client.end();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
main().catch((err) => {
|
|
90
|
+
console.error('[sync-sla-reports-sql] failed:', err.message);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
});
|
package/sql/README.md
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# SLA reports — database objects
|
|
2
|
-
|
|
3
|
-
Applied in order by `npm run sync:sla-sql` (see `sla-reports-sync.manifest.json`).
|
|
4
|
-
|
|
5
|
-
| File | Description |
|
|
6
|
-
|------|-------------|
|
|
7
|
-
| `vw_sla_my_requests.sql` | My-requests view |
|
|
8
|
-
| `vw_sla_approvals.sql` | Approvals view |
|
|
9
|
-
| `sla_reports_procedures.sql` | User SLA report functions + Excel helpers |
|
|
10
|
-
| `sla_reports_approvals_workbook.sql` | Approvals Excel workbook (Requests + Approvals per sub-service) |
|
|
11
|
-
| `sla_reports_admin_procedures.sql` | Admin SLA report functions (requires procedures file) |
|
|
12
|
-
|
|
13
|
-
From **shared_models** (reads DB config from `shared_models/.env` only — `DB_HOST`, `DB_USER`, `DB_PASS`, `DB_NAME`):
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
cd shared_models && npm run sync:sla-sql
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Skip sync: `SKIP_SLA_SQL_SYNC=true` or pass `--skip`.
|
|
20
|
-
|
|
21
|
-
Reports_Service does not run SQL sync — apply these objects before using the reports API (local dev, CI, or deployment pipeline).
|
|
1
|
+
# SLA reports — database objects
|
|
2
|
+
|
|
3
|
+
Applied in order by `npm run sync:sla-sql` (see `sla-reports-sync.manifest.json`).
|
|
4
|
+
|
|
5
|
+
| File | Description |
|
|
6
|
+
|------|-------------|
|
|
7
|
+
| `vw_sla_my_requests.sql` | My-requests view |
|
|
8
|
+
| `vw_sla_approvals.sql` | Approvals view |
|
|
9
|
+
| `sla_reports_procedures.sql` | User SLA report functions + Excel helpers |
|
|
10
|
+
| `sla_reports_approvals_workbook.sql` | Approvals Excel workbook (Requests + Approvals per sub-service) |
|
|
11
|
+
| `sla_reports_admin_procedures.sql` | Admin SLA report functions (requires procedures file) |
|
|
12
|
+
|
|
13
|
+
From **shared_models** (reads DB config from `shared_models/.env` only — `DB_HOST`, `DB_USER`, `DB_PASS`, `DB_NAME`):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cd shared_models && npm run sync:sla-sql
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Skip sync: `SKIP_SLA_SQL_SYNC=true` or pass `--skip`.
|
|
20
|
+
|
|
21
|
+
Reports_Service does not run SQL sync — apply these objects before using the reports API (local dev, CI, or deployment pipeline).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Add icon_id column to important_links table (CAA).
|
|
2
|
+
-- Run once per environment before deploying updated services.
|
|
3
|
+
|
|
4
|
+
ALTER TABLE IF EXISTS important_links
|
|
5
|
+
ADD COLUMN IF NOT EXISTS icon_id INTEGER NULL;
|
|
6
|
+
|
|
7
|
+
CREATE INDEX IF NOT EXISTS idx_important_links_icon_id
|
|
8
|
+
ON important_links (icon_id)
|
|
9
|
+
WHERE is_deleted = FALSE;
|
|
10
|
+
|
|
11
|
+
DO $$ BEGIN
|
|
12
|
+
ALTER TABLE important_links
|
|
13
|
+
ADD CONSTRAINT fk_important_links_icon_id
|
|
14
|
+
FOREIGN KEY (icon_id) REFERENCES icons (id);
|
|
15
|
+
EXCEPTION
|
|
16
|
+
WHEN duplicate_object THEN NULL;
|
|
17
|
+
END $$;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
-- Icons master table (User Service)
|
|
2
|
+
-- PostgreSQL
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS icons (
|
|
5
|
+
id SERIAL PRIMARY KEY,
|
|
6
|
+
icon_name VARCHAR(255) NOT NULL,
|
|
7
|
+
icon_name_arabic VARCHAR(255) NULL,
|
|
8
|
+
url VARCHAR(2000) NOT NULL,
|
|
9
|
+
created_by INTEGER NULL,
|
|
10
|
+
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
11
|
+
updated_by INTEGER NULL,
|
|
12
|
+
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
13
|
+
is_deleted BOOLEAN DEFAULT FALSE
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_icons_icon_name
|
|
17
|
+
ON icons (LOWER(icon_name))
|
|
18
|
+
WHERE is_deleted = FALSE;
|
|
19
|
+
|
|
20
|
+
CREATE INDEX IF NOT EXISTS idx_icons_is_deleted
|
|
21
|
+
ON icons (is_deleted);
|