@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.
Files changed (74) hide show
  1. package/dist/data-source.js +2 -0
  2. package/dist/helpers/cancellation-bilingual-persist.helper.d.ts +37 -0
  3. package/dist/helpers/cancellation-bilingual-persist.helper.js +77 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +1 -0
  6. package/dist/models/IconsModel.d.ts +7 -0
  7. package/dist/models/IconsModel.js +39 -0
  8. package/dist/models/SlaApprovalsViewModel.js +54 -54
  9. package/dist/models/importantLinksModel.d.ts +1 -0
  10. package/dist/models/importantLinksModel.js +5 -0
  11. package/package.json +1 -1
  12. package/scripts/sync-sla-reports-sql.js +92 -92
  13. package/sql/README.md +21 -21
  14. package/sql/add_important_links_icon_id.sql +17 -0
  15. package/sql/create_icons.sql +21 -0
  16. package/sql/sla_reports_admin_procedures.sql +322 -323
  17. package/sql/sla_reports_approvals_workbook.sql +427 -430
  18. package/sql/sla_reports_procedures.sql +883 -886
  19. package/sql/vw_sla_approvals.sql +115 -115
  20. package/sql/vw_sla_my_requests.sql +58 -58
  21. package/src/data-source.ts +2 -0
  22. package/src/index.ts +1 -0
  23. package/src/models/AccessCardRequestModel.ts +135 -135
  24. package/src/models/AirportEntryPermitModel.ts +276 -276
  25. package/src/models/AnnualTrainingPlanRequestModel.ts +153 -153
  26. package/src/models/DocumentDriveModel.ts +28 -28
  27. package/src/models/DocumentFolderModel.ts +45 -45
  28. package/src/models/HotelApprovalModel.ts +83 -83
  29. package/src/models/HousingContractCancelApprovalModel.ts +64 -64
  30. package/src/models/HousingContractRenewalApprovalModel.ts +64 -64
  31. package/src/models/ITRequestAttachmentModel.ts +73 -73
  32. package/src/models/IconsModel.ts +21 -0
  33. package/src/models/ItApprovalsModel.ts +84 -84
  34. package/src/models/LegalConsultationApprovalModel.ts +65 -65
  35. package/src/models/MissionTravelPassportExpiryNotificationConfigModel.ts +36 -36
  36. package/src/models/NotificationModel.ts +89 -89
  37. package/src/models/ResidentialUnitRentalApprovalModel.ts +143 -143
  38. package/src/models/ServiceExtensionAfter60ApprovalModel.ts +87 -87
  39. package/src/models/ServiceSlaApprovalModel.ts +64 -64
  40. package/src/models/ServicesNotificationConfigModel.ts +55 -55
  41. package/src/models/SlaApprovalsViewModel.ts +142 -142
  42. package/src/models/StudyLeaveRequestModel.ts +144 -144
  43. package/src/models/TrainingRequestModel.ts +164 -164
  44. package/src/models/TrainingRoomBookingRequestModel.ts +142 -142
  45. package/src/models/TrainingRoomNotificationConfigModel.ts +30 -30
  46. package/src/models/importantLinksModel.ts +4 -0
  47. package/src/models/role.ts +34 -34
  48. package/src/sla/sla-table-sync.service.ts +90 -90
  49. package/dist/models/DocumentMetadataModel.d.ts +0 -45
  50. package/dist/models/DocumentMetadataModel.js +0 -171
  51. package/dist/models/DocumentationDepartmentsModel.d.ts +0 -13
  52. package/dist/models/DocumentationDepartmentsModel.js +0 -53
  53. package/dist/models/FolderModel.d.ts +0 -16
  54. package/dist/models/FolderModel.js +0 -85
  55. package/dist/models/ImportExportMaterialModels.d.ts +0 -92
  56. package/dist/models/ImportExportMaterialModels.js +0 -307
  57. package/dist/models/PermissionModel.d.ts +0 -18
  58. package/dist/models/PermissionModel.js +0 -68
  59. package/dist/models/SecurityAccessApprovalModel.d.ts +0 -23
  60. package/dist/models/SecurityAccessApprovalModel.js +0 -82
  61. package/dist/models/SecurityAccessAttachmentModel.d.ts +0 -12
  62. package/dist/models/SecurityAccessAttachmentModel.js +0 -56
  63. package/dist/models/SecurityAccessChatModel.d.ts +0 -12
  64. package/dist/models/SecurityAccessChatModel.js +0 -56
  65. package/dist/models/SecurityAccessRequestModel.d.ts +0 -25
  66. package/dist/models/SecurityAccessRequestModel.js +0 -80
  67. package/dist/models/SecurityAccessWorkflowModel.d.ts +0 -24
  68. package/dist/models/SecurityAccessWorkflowModel.js +0 -84
  69. package/dist/models/ServiceExtensionAfterAge60Models.d.ts +0 -93
  70. package/dist/models/ServiceExtensionAfterAge60Models.js +0 -312
  71. package/dist/models/UUIDBaseModel.d.ts +0 -14
  72. package/dist/models/UUIDBaseModel.js +0 -66
  73. package/dist/models/WorkingHoursExtensionModels.d.ts +0 -88
  74. package/dist/models/WorkingHoursExtensionModels.js +0 -295
@@ -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,7 @@
1
+ import { BaseModel } from "./BaseModel";
2
+ export declare class Icons extends BaseModel {
3
+ icon_name: string;
4
+ icon_name_arabic: string | null;
5
+ url: string;
6
+ constructor(icon_name: string, url: string);
7
+ }
@@ -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).
@@ -2,5 +2,6 @@ import { BaseModel } from './BaseModel';
2
2
  export declare class ImportantLinks extends BaseModel {
3
3
  title: string;
4
4
  url: string;
5
+ icon_id: number | null;
5
6
  constructor(title: string, url: string);
6
7
  }
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "@platform-modules/civil-aviation-authority",
3
- "version": "2.3.312",
3
+ "version": "2.3.314",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -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);