@platform-modules/civil-aviation-authority 2.3.290 → 2.3.292

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 (119) hide show
  1. package/dist/data-source.js +2 -0
  2. package/dist/i18n/workflow-chat-i18n.json +45 -41
  3. package/dist/i18n/workflow-chat-message.builder.d.ts +9 -0
  4. package/dist/i18n/workflow-chat-message.builder.js +60 -27
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +1 -0
  7. package/dist/models/AppealAgainstAdministrativeDecisionRequestModel.d.ts +4 -4
  8. package/dist/models/AppealAgainstAdministrativeDecisionRequestModel.js +8 -8
  9. package/dist/models/CyberSecurityAuditRequestModel.d.ts +2 -0
  10. package/dist/models/CyberSecurityAuditRequestModel.js +8 -0
  11. package/dist/models/CyberSecurityRiskManagementRiskModel.d.ts +2 -0
  12. package/dist/models/CyberSecurityRiskManagementRiskModel.js +8 -0
  13. package/dist/models/FollowUpReportItemModel.d.ts +16 -0
  14. package/dist/models/FollowUpReportItemModel.js +74 -0
  15. package/dist/models/FollowUpReportRequestModel.d.ts +5 -0
  16. package/dist/models/FollowUpReportRequestModel.js +20 -0
  17. package/dist/models/MaintenanceRequestModel.d.ts +3 -1
  18. package/dist/models/MaintenanceRequestModel.js +2 -0
  19. package/dist/models/RequestATenderRequestModel.d.ts +2 -0
  20. package/dist/models/RequestATenderRequestModel.js +8 -0
  21. package/dist/models/ResidentialUnitRentalRequestModel.d.ts +1 -1
  22. package/dist/models/ResidentialUnitRentalRequestModel.js +2 -2
  23. package/package.json +1 -1
  24. package/sql/add_all_workflow_chat_arabic_columns.sql +1 -1
  25. package/sql/caa_api_payload_changes_2026_07.sql +32 -0
  26. package/src/data-source.ts +2 -0
  27. package/src/i18n/workflow-chat-i18n.json +45 -41
  28. package/src/i18n/workflow-chat-message.builder.ts +77 -26
  29. package/src/index.ts +1 -0
  30. package/src/models/AccessCardChatModel.ts +6 -6
  31. package/src/models/AccessCardWorkflowModel.ts +6 -6
  32. package/src/models/AccommodationChatModel.ts +6 -6
  33. package/src/models/AccommodationWorkflowModel.ts +6 -6
  34. package/src/models/AirportEntryPermitChatModel.ts +6 -6
  35. package/src/models/AirportEntryPermitWorkflowModel.ts +6 -6
  36. package/src/models/AnnualTrainingPlanChatModel.ts +6 -6
  37. package/src/models/AnnualTrainingPlanWorkflowModel.ts +6 -6
  38. package/src/models/AppealAgainstAdministrativeDecisionRequestModel.ts +8 -8
  39. package/src/models/AssignTasksEmpChatModel.ts +6 -6
  40. package/src/models/AssignTasksEmpWorkflowModel.ts +6 -6
  41. package/src/models/ComplaintLostPropertyReportChatModel.ts +6 -6
  42. package/src/models/ComplaintLostPropertyReportWorkflowModel.ts +6 -6
  43. package/src/models/CyberSecurityAuditRequestModel.ts +6 -0
  44. package/src/models/CyberSecurityRiskManagementRiskModel.ts +6 -0
  45. package/src/models/DutyMissionChatModel.ts +6 -6
  46. package/src/models/DutyMissionWorkflowModel.ts +6 -6
  47. package/src/models/EventSupportChatModel.ts +6 -6
  48. package/src/models/EventSupportWorkflowModel.ts +6 -6
  49. package/src/models/FollowUpReportChatModel.ts +6 -6
  50. package/src/models/FollowUpReportItemModel.ts +47 -0
  51. package/src/models/FollowUpReportRequestModel.ts +15 -0
  52. package/src/models/FollowUpReportWorkflowModel.ts +6 -6
  53. package/src/models/FoodChatModel.ts +6 -6
  54. package/src/models/FoodWorkflowModel.ts +6 -6
  55. package/src/models/HallChatModel.ts +6 -6
  56. package/src/models/HallWorkflowModel.ts +6 -6
  57. package/src/models/HotelChatModel.ts +6 -6
  58. package/src/models/HotelWorkFlowModel.ts +6 -6
  59. package/src/models/HousingContractCancelChatModel.ts +6 -6
  60. package/src/models/HousingContractCancelWorkflowModel.ts +6 -6
  61. package/src/models/HousingContractRenewalChatModel.ts +6 -6
  62. package/src/models/HousingContractRenewalWorkflowModel.ts +6 -6
  63. package/src/models/HrServiceChatModel.ts +6 -6
  64. package/src/models/HrServiceWorkflowModel.ts +6 -6
  65. package/src/models/ITRequestChatModel.ts +6 -6
  66. package/src/models/ImportExportMaterialChatModel.ts +6 -6
  67. package/src/models/ImportExportMaterialWorkflowModel.ts +6 -6
  68. package/src/models/InformationSecurityChatModel.ts +6 -6
  69. package/src/models/InformationSecurityWorkflowModel.ts +6 -6
  70. package/src/models/ItWorkflowModel.ts +6 -6
  71. package/src/models/LegalComplaintChatModel.ts +6 -6
  72. package/src/models/LegalComplaintWorkflowModel.ts +6 -6
  73. package/src/models/LegalConsultationChatModel.ts +6 -6
  74. package/src/models/LegalConsultationWorkflowModel.ts +6 -6
  75. package/src/models/LegalContractReviewChatModel.ts +6 -6
  76. package/src/models/LegalContractReviewWorkflowModel.ts +6 -6
  77. package/src/models/LogisticsChatModel.ts +6 -6
  78. package/src/models/LogisticsVehicleMaintenanceChatModel.ts +6 -6
  79. package/src/models/LogisticsVehicleMaintenanceWorkflowModel.ts +6 -6
  80. package/src/models/LogisticsWorkflowModel.ts +6 -6
  81. package/src/models/MaintenanceChatModel.ts +6 -6
  82. package/src/models/MaintenanceExternalStationsChatModel.ts +6 -6
  83. package/src/models/MaintenanceExternalStationsWorkflowModel.ts +6 -6
  84. package/src/models/MaintenanceRequestModel.ts +2 -0
  85. package/src/models/MaintenanceWorkflowModel.ts +6 -6
  86. package/src/models/MediaPublicationsChatModel.ts +6 -6
  87. package/src/models/MediaPublicationsWorkflowModel.ts +6 -6
  88. package/src/models/MultiPurposeHallChatModel.ts +6 -6
  89. package/src/models/MultiPurposeHallWorkflowModel.ts +6 -6
  90. package/src/models/RequestATenderRequestModel.ts +6 -0
  91. package/src/models/RequestForCoverageChatModel.ts +6 -6
  92. package/src/models/RequestForCoverageWorkflowModel.ts +6 -6
  93. package/src/models/RequestForPresidentsCoverageChatModel.ts +6 -6
  94. package/src/models/RequestForPresidentsCoverageWorkflowModel.ts +6 -6
  95. package/src/models/ResidentialUnitRentalChatModel.ts +6 -6
  96. package/src/models/ResidentialUnitRentalRequestModel.ts +2 -2
  97. package/src/models/ResidentialUnitRentalWorkflowModel.ts +6 -6
  98. package/src/models/RespondToEnquiriesChatModel.ts +6 -6
  99. package/src/models/RespondToEnquiriesWorkflowModel.ts +6 -6
  100. package/src/models/ScholarshipChatModel.ts +6 -6
  101. package/src/models/ScholarshipWorkflowModel.ts +6 -6
  102. package/src/models/SecurityAwarenessChatModel.ts +6 -6
  103. package/src/models/SecurityAwarenessWorkflowModel.ts +6 -6
  104. package/src/models/SecurityThreatChatModel.ts +6 -6
  105. package/src/models/SecurityThreatWorkflowModel.ts +6 -6
  106. package/src/models/ServiceExtensionAfter60ChatModel.ts +6 -6
  107. package/src/models/ServiceExtensionAfter60WorkflowModel.ts +6 -6
  108. package/src/models/StudyLeaveChatModel.ts +6 -6
  109. package/src/models/StudyLeaveWorkflowModel.ts +6 -6
  110. package/src/models/TrainingChatModel.ts +6 -6
  111. package/src/models/TrainingRoomBookingChatModel.ts +6 -6
  112. package/src/models/TrainingRoomBookingWorkflowModel.ts +6 -6
  113. package/src/models/TrainingWorkflowModel.ts +6 -6
  114. package/src/models/VipHallChatModel.ts +6 -6
  115. package/src/models/VipHallWorkflowModel.ts +6 -6
  116. package/src/models/VpnRequestChatModel.ts +6 -6
  117. package/src/models/VpnWorkflowModel.ts +6 -6
  118. package/src/models/WorkingHoursExtensionChatModel.ts +6 -6
  119. package/src/models/WorkingHoursExtensionWorkflowModel.ts +6 -6
@@ -0,0 +1,74 @@
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.FollowUpReportItem = void 0;
13
+ const typeorm_1 = require("typeorm");
14
+ const BaseModel_1 = require("./BaseModel");
15
+ const FollowUpReportRequestModel_1 = require("./FollowUpReportRequestModel");
16
+ let FollowUpReportItem = class FollowUpReportItem extends BaseModel_1.BaseModel {
17
+ };
18
+ exports.FollowUpReportItem = FollowUpReportItem;
19
+ __decorate([
20
+ (0, typeorm_1.Column)({ type: 'integer', nullable: false }),
21
+ __metadata("design:type", Number)
22
+ ], FollowUpReportItem.prototype, "request_id", void 0);
23
+ __decorate([
24
+ (0, typeorm_1.Column)({ type: 'integer', nullable: true }),
25
+ __metadata("design:type", Object)
26
+ ], FollowUpReportItem.prototype, "service_id", void 0);
27
+ __decorate([
28
+ (0, typeorm_1.Column)({ type: 'integer', nullable: true }),
29
+ __metadata("design:type", Object)
30
+ ], FollowUpReportItem.prototype, "sub_service_id", void 0);
31
+ __decorate([
32
+ (0, typeorm_1.Column)({ type: 'varchar', length: 100, nullable: true }),
33
+ __metadata("design:type", Object)
34
+ ], FollowUpReportItem.prototype, "reference_type", void 0);
35
+ __decorate([
36
+ (0, typeorm_1.Column)({ type: 'date', nullable: true }),
37
+ __metadata("design:type", Object)
38
+ ], FollowUpReportItem.prototype, "letter_date", void 0);
39
+ __decorate([
40
+ (0, typeorm_1.Column)({ type: 'varchar', length: 500, nullable: true }),
41
+ __metadata("design:type", Object)
42
+ ], FollowUpReportItem.prototype, "subject", void 0);
43
+ __decorate([
44
+ (0, typeorm_1.Column)({
45
+ type: 'enum',
46
+ enum: FollowUpReportRequestModel_1.FollowUpReportSubjectClassification,
47
+ enumName: 'maintenance_subject_classification_en',
48
+ nullable: true,
49
+ }),
50
+ __metadata("design:type", Object)
51
+ ], FollowUpReportItem.prototype, "subject_classification", void 0);
52
+ __decorate([
53
+ (0, typeorm_1.Column)({ type: 'varchar', length: 500, nullable: true }),
54
+ __metadata("design:type", Object)
55
+ ], FollowUpReportItem.prototype, "general_manager_comment", void 0);
56
+ __decorate([
57
+ (0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
58
+ __metadata("design:type", Object)
59
+ ], FollowUpReportItem.prototype, "response_date_target", void 0);
60
+ __decorate([
61
+ (0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
62
+ __metadata("design:type", Object)
63
+ ], FollowUpReportItem.prototype, "action_status", void 0);
64
+ __decorate([
65
+ (0, typeorm_1.Column)({ type: 'text', nullable: true }),
66
+ __metadata("design:type", Object)
67
+ ], FollowUpReportItem.prototype, "action_taken", void 0);
68
+ __decorate([
69
+ (0, typeorm_1.Column)({ type: 'varchar', length: 100, nullable: true }),
70
+ __metadata("design:type", Object)
71
+ ], FollowUpReportItem.prototype, "delay_period", void 0);
72
+ exports.FollowUpReportItem = FollowUpReportItem = __decorate([
73
+ (0, typeorm_1.Entity)({ name: 'followup_report_items' })
74
+ ], FollowUpReportItem);
@@ -36,6 +36,11 @@ export declare class FollowUpReportRequests extends BaseModel {
36
36
  concerned_department: FollowUpReportConcernedDepartment;
37
37
  date_from: Date;
38
38
  date_to: Date;
39
+ general_manager_comment: string | null;
40
+ response_date_target: string | null;
41
+ action_status: string | null;
42
+ action_taken: string | null;
43
+ delay_period: string | null;
39
44
  request_submission_date: Date;
40
45
  status: FollowUpReportRequestStatus;
41
46
  workflow_execution_id: string | null;
@@ -103,6 +103,26 @@ __decorate([
103
103
  (0, typeorm_1.Column)({ type: 'date', nullable: false }),
104
104
  __metadata("design:type", Date)
105
105
  ], FollowUpReportRequests.prototype, "date_to", void 0);
106
+ __decorate([
107
+ (0, typeorm_1.Column)({ type: 'varchar', length: 500, nullable: true }),
108
+ __metadata("design:type", Object)
109
+ ], FollowUpReportRequests.prototype, "general_manager_comment", void 0);
110
+ __decorate([
111
+ (0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
112
+ __metadata("design:type", Object)
113
+ ], FollowUpReportRequests.prototype, "response_date_target", void 0);
114
+ __decorate([
115
+ (0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
116
+ __metadata("design:type", Object)
117
+ ], FollowUpReportRequests.prototype, "action_status", void 0);
118
+ __decorate([
119
+ (0, typeorm_1.Column)({ type: 'text', nullable: true }),
120
+ __metadata("design:type", Object)
121
+ ], FollowUpReportRequests.prototype, "action_taken", void 0);
122
+ __decorate([
123
+ (0, typeorm_1.Column)({ type: 'varchar', length: 100, nullable: true }),
124
+ __metadata("design:type", Object)
125
+ ], FollowUpReportRequests.prototype, "delay_period", void 0);
106
126
  __decorate([
107
127
  (0, typeorm_1.Column)({ type: 'date', nullable: false, default: () => 'CURRENT_DATE' }),
108
128
  __metadata("design:type", Date)
@@ -3,7 +3,9 @@ export declare enum AssetMaintenanceCategory {
3
3
  BUILDING = "Building",
4
4
  EQUIPMENT = "Equipment",
5
5
  RESIDENTIAL = "Residential",
6
- STATION = "Station"
6
+ STATION = "Station",
7
+ PLOT_OF_LAND = "Plot of land",
8
+ OTHER = "Other"
7
9
  }
8
10
  export declare enum AssetMaintenanceSubCategory {
9
11
  ELECTRICAL = "Electrical",
@@ -18,6 +18,8 @@ var AssetMaintenanceCategory;
18
18
  AssetMaintenanceCategory["EQUIPMENT"] = "Equipment";
19
19
  AssetMaintenanceCategory["RESIDENTIAL"] = "Residential";
20
20
  AssetMaintenanceCategory["STATION"] = "Station";
21
+ AssetMaintenanceCategory["PLOT_OF_LAND"] = "Plot of land";
22
+ AssetMaintenanceCategory["OTHER"] = "Other";
21
23
  })(AssetMaintenanceCategory || (exports.MaintenanceCategory = exports.AssetMaintenanceCategory = AssetMaintenanceCategory = {}));
22
24
  var AssetMaintenanceSubCategory;
23
25
  (function (AssetMaintenanceSubCategory) {
@@ -18,6 +18,8 @@ export declare class RequestATenderRequest extends BaseModel {
18
18
  scope_of_work: string;
19
19
  type_of_request: RequestATenderType;
20
20
  date_of_submission: Date;
21
+ date: Date | null;
22
+ time: string | null;
21
23
  phone: string;
22
24
  budget_code: string | null;
23
25
  estimated_cost: string;
@@ -69,6 +69,14 @@ __decorate([
69
69
  (0, typeorm_1.Column)({ type: "date", nullable: false }),
70
70
  __metadata("design:type", Date)
71
71
  ], RequestATenderRequest.prototype, "date_of_submission", void 0);
72
+ __decorate([
73
+ (0, typeorm_1.Column)({ type: "date", nullable: true }),
74
+ __metadata("design:type", Object)
75
+ ], RequestATenderRequest.prototype, "date", void 0);
76
+ __decorate([
77
+ (0, typeorm_1.Column)({ type: "varchar", length: 8, nullable: true }),
78
+ __metadata("design:type", Object)
79
+ ], RequestATenderRequest.prototype, "time", void 0);
72
80
  __decorate([
73
81
  (0, typeorm_1.Column)({ type: "varchar", length: 30, nullable: false }),
74
82
  __metadata("design:type", String)
@@ -19,7 +19,7 @@ export declare class ResidentialUnitRentalRequest extends BaseModel {
19
19
  three_room?: boolean;
20
20
  };
21
21
  extension_number: string;
22
- preferred_start_date: Date;
22
+ preferred_start_date: Date | null;
23
23
  family_size: number;
24
24
  phone_number: string;
25
25
  location_of_unit: string;
@@ -54,8 +54,8 @@ __decorate([
54
54
  __metadata("design:type", String)
55
55
  ], ResidentialUnitRentalRequest.prototype, "extension_number", void 0);
56
56
  __decorate([
57
- (0, typeorm_1.Column)({ type: 'date', nullable: false }),
58
- __metadata("design:type", Date)
57
+ (0, typeorm_1.Column)({ type: 'date', nullable: true }),
58
+ __metadata("design:type", Object)
59
59
  ], ResidentialUnitRentalRequest.prototype, "preferred_start_date", void 0);
60
60
  __decorate([
61
61
  (0, typeorm_1.Column)({ type: 'int', nullable: false }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platform-modules/civil-aviation-authority",
3
- "version": "2.3.290",
3
+ "version": "2.3.292",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -1 +1 @@
1
- -- Auto-generated: Arabic columns for all CAA workflow/chat tables
1
+ -- Auto-generated: Arabic columns for all CAA workflow/chat tables
@@ -0,0 +1,32 @@
1
+ -- CAA API payload changes (Jul 2026)
2
+ -- Run after deploying updated shared_models and services.
3
+
4
+ -- 1. Maintenance: add category enum values
5
+ ALTER TYPE asset_maintenance_category_en ADD VALUE IF NOT EXISTS 'Plot of land';
6
+ ALTER TYPE asset_maintenance_category_en ADD VALUE IF NOT EXISTS 'Other';
7
+
8
+ -- 2. Residential unit rental: preferred_start_date optional
9
+ ALTER TABLE residential_unit_rental_requests
10
+ ALTER COLUMN preferred_start_date DROP NOT NULL;
11
+
12
+ -- 3. Appeal against administrative decision: optional / removed payload fields
13
+ ALTER TABLE appeal_against_administrative_decision_requests
14
+ ALTER COLUMN description DROP NOT NULL,
15
+ ALTER COLUMN grievance_details DROP NOT NULL,
16
+ ALTER COLUMN decision_date DROP NOT NULL,
17
+ ALTER COLUMN grievant_name DROP NOT NULL;
18
+
19
+ -- 4. Cyber security audit: date and time fields
20
+ ALTER TABLE cyber_security_audit_requests
21
+ ADD COLUMN IF NOT EXISTS date DATE,
22
+ ADD COLUMN IF NOT EXISTS time VARCHAR(8);
23
+
24
+ -- 5. Request a tender: date and time fields
25
+ ALTER TABLE request_a_tender_requests
26
+ ADD COLUMN IF NOT EXISTS date DATE,
27
+ ADD COLUMN IF NOT EXISTS time VARCHAR(8);
28
+
29
+ -- 6. Cyber security risk management risks: treatment and action fields
30
+ ALTER TABLE cyber_security_risk_management_risks
31
+ ADD COLUMN IF NOT EXISTS treatment TEXT,
32
+ ADD COLUMN IF NOT EXISTS action TEXT;
@@ -234,6 +234,7 @@ import { MaintenanceExternalStationsAttachment } from './models/MaintenanceExter
234
234
  import { MaintenanceExternalStationsChat } from './models/MaintenanceExternalStationsChatModel';
235
235
  import { MaintenanceExternalStationsWorkFlow } from './models/MaintenanceExternalStationsWorkflowModel';
236
236
  import { FollowUpReportRequests } from './models/FollowUpReportRequestModel';
237
+ import { FollowUpReportItem } from './models/FollowUpReportItemModel';
237
238
  import { FollowUpReportApprovalDetails } from './models/FollowUpReportApprovalModel';
238
239
  import { FollowUpReportAttachment } from './models/FollowUpReportAttachmentModel';
239
240
  import { FollowUpReportChat } from './models/FollowUpReportChatModel';
@@ -557,6 +558,7 @@ export const AppDataSource = new DataSource({
557
558
  MaintenanceExternalStationsChat,
558
559
  MaintenanceExternalStationsWorkFlow,
559
560
  FollowUpReportRequests,
561
+ FollowUpReportItem,
560
562
  FollowUpReportApprovalDetails,
561
563
  FollowUpReportAttachment,
562
564
  FollowUpReportChat,
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "request_approval_pending": {
20
20
  "en": "Request Approval Pending",
21
- "ar": "في انتظار الموافقة على الطلب"
21
+ "ar": "الموافقة على الطلب قيد الانتظار"
22
22
  },
23
23
  "request_approval_in_progress_from": {
24
24
  "en": "Request Approval In Progress from {{name}}",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "request_approval_pending_from": {
28
28
  "en": "Request Approval Pending from {{name}}",
29
- "ar": "في انتظار موافقة {{name}}"
29
+ "ar": "الموافقة على الطلب قيد الانتظار من {{name}}"
30
30
  },
31
31
  "request_approved_by": {
32
32
  "en": "Request Approved by {{name}}{{comment}}",
@@ -46,11 +46,11 @@
46
46
  },
47
47
  "request_returned_for_modification_by": {
48
48
  "en": "Request Returned for Modification by {{name}}{{comment}}",
49
- "ar": "تم إرجاع الطلب للتعديل من قبل {{name}}{{comment}}"
49
+ "ar": "تمت إعادة الطلب للتعديل من قبل {{name}}{{comment}}"
50
50
  },
51
51
  "request_returned_for_modification": {
52
52
  "en": "Request Returned for Modification{{comment}}",
53
- "ar": "تم إرجاع الطلب للتعديل{{comment}}"
53
+ "ar": "تمت إعادة الطلب للتعديل{{comment}}"
54
54
  },
55
55
  "request_closed_by": {
56
56
  "en": "Request Closed by: {{name}}{{comment}}",
@@ -62,47 +62,47 @@
62
62
  },
63
63
  "it_helpdesk_wf_hos_assigned": {
64
64
  "en": "{{approverRoleName}} assigned the request to {{assignedRoleName}}{{comment}}",
65
- "ar": "قام {{approverRoleName}} بتعيين الطلب إلى {{assignedRoleName}}{{comment}}"
65
+ "ar": "تم تعيين الطلب إلى {{assignedRoleName}} من قبل {{approverRoleName}}{{comment}}"
66
66
  },
67
67
  "it_helpdesk_wf_technician_assigned": {
68
68
  "en": "IT technician {{level}} assigned by {{approverRoleName}}{{comment}}",
69
- "ar": "تم تعيين فني IT {{level}} بواسطة {{approverRoleName}}{{comment}}"
69
+ "ar": "تم تعيين فني تقنية المعلومات {{level}} من قبل {{approverRoleName}}{{comment}}"
70
70
  },
71
71
  "it_helpdesk_wf_reassigned_technician": {
72
72
  "en": "{{approverRoleName}} reassigned request to Technician{{comment}}{{modifiers}}",
73
- "ar": "أعاد {{approverRoleName}} تعيين الطلب إلى الفني{{comment}}{{modifiers}}"
73
+ "ar": "{{approverRoleName}} تمت إعادة تعيين الطلب إلى الفني{{comment}}{{modifiers}}"
74
74
  },
75
75
  "it_helpdesk_wf_reassigned_l3": {
76
76
  "en": "{{approverRoleName}} reassigned request to L3{{comment}}{{modifiers}}",
77
- "ar": "أعاد {{approverRoleName}} تعيين الطلب إلى L3{{comment}}{{modifiers}}"
77
+ "ar": "{{approverRoleName}} تمت إعادة تعيين الطلب إلى المستوى الثالث (L3){{comment}}{{modifiers}}"
78
78
  },
79
79
  "it_helpdesk_wf_reassigned_generic": {
80
80
  "en": "{{approverRoleName}} {{level}} reassigned{{comment}}{{modifiers}}",
81
- "ar": "أعاد {{approverRoleName}} {{level}} التعيين{{comment}}{{modifiers}}"
81
+ "ar": "{{approverRoleName}} {{level}} إعادة التعيين{{comment}}{{modifiers}}"
82
82
  },
83
83
  "it_helpdesk_wf_closed_request": {
84
84
  "en": "{{approverRoleName}} closed request{{comment}}",
85
- "ar": "أغلق {{approverRoleName}} الطلب{{comment}}"
85
+ "ar": "تم إغلاق الطلب من قبل {{approverRoleName}}{{comment}}"
86
86
  },
87
87
  "it_helpdesk_wf_closed_request_cap": {
88
88
  "en": "{{approverRoleName}} Closed request{{comment}}",
89
- "ar": "أغلق {{approverRoleName}} الطلب{{comment}}"
89
+ "ar": "تم إغلاق الطلب من قبل {{approverRoleName}}{{comment}}"
90
90
  },
91
91
  "it_helpdesk_wf_l3_approved_by": {
92
92
  "en": "{{roleName}} approved the request by {{userName}}{{comment}}",
93
- "ar": "وافق {{roleName}} على الطلب من قبل {{userName}}{{comment}}"
93
+ "ar": "{{roleName}} تمت الموافقة على الطلب من قبل {{userName}}{{comment}}"
94
94
  },
95
95
  "it_helpdesk_wf_l3_rejected_by": {
96
96
  "en": "{{roleName}} rejected the request by {{userName}}{{comment}}",
97
- "ar": "رفض {{roleName}} على الطلب من قبل {{userName}}{{comment}}"
97
+ "ar": "{{roleName}} تم رفض الطلب من قبل {{userName}}{{comment}}"
98
98
  },
99
99
  "it_helpdesk_wf_level_approved": {
100
100
  "en": "Level {{level}} approved by {{approverRoleName}}{{comment}}",
101
- "ar": "تمت الموافقة على المستوى {{level}} من قبل {{approverRoleName}}{{comment}}"
101
+ "ar": "تمت الموافقة من قبل {{approverRoleName}} للمستوى {{level}}{{comment}}"
102
102
  },
103
103
  "it_helpdesk_wf_rejected": {
104
104
  "en": "{{approverRoleName}} rejected the request{{comment}}",
105
- "ar": "رفض {{approverRoleName}} الطلب{{comment}}"
105
+ "ar": "{{approverRoleName}} تم رفض الطلب{{comment}}"
106
106
  },
107
107
  "it_helpdesk_wf_status_by_role": {
108
108
  "en": "Request {{status}} by {{approverRoleName}}{{comment}}",
@@ -110,29 +110,29 @@
110
110
  },
111
111
  "it_helpdesk_wf_l3_step_rejected": {
112
112
  "en": "{{roleName}} rejected the request{{comment}}",
113
- "ar": "رفض {{roleName}} الطلب{{comment}}"
113
+ "ar": "{{roleName}} تم رفض الطلب{{comment}}"
114
114
  },
115
115
  "it_helpdesk_wf_technician_completed": {
116
116
  "en": "Technician action completed - request closed by {{roleName}}{{comment}}",
117
- "ar": "اكتمل إجراء الفني - تم إغلاق الطلب بواسطة {{roleName}}{{comment}}"
117
+ "ar": "تم استكمال إجراء الفني - تم إغلاق الطلب من قبل {{roleName}}{{comment}}"
118
118
  },
119
119
  "it_helpdesk_wf_routing_rejected": {
120
120
  "en": "Workflow routing completed - request rejected at L3{{comment}}",
121
- "ar": "اكتمل توجيه سير العمل - تم رفض الطلب في L3{{comment}}"
121
+ "ar": "تم استكمال مسار سير العمل - تم رفض الطلب في المستوى الثالث (L3){{comment}}"
122
122
  },
123
123
  "it_helpdesk_wf_routing_resolved": {
124
124
  "en": "Workflow routing completed - request resolved at L3",
125
- "ar": "اكتمل توجيه سير العمل - تم حل الطلب في L3"
125
+ "ar": "تم استكمال مسار سير العمل - تم حل الطلب في المستوى الثالث (L3)"
126
126
  }
127
127
  },
128
128
  "chatTemplates": {
129
129
  "request_submitted_by": {
130
130
  "en": "Request Submitted by {{userName}} ({{employeeId}})",
131
- "ar": "تم تقديم الطلب بواسطة {{userName}} ({{employeeId}})"
131
+ "ar": "تم تقديم الطلب من قبل {{userName}} ({{employeeId}})"
132
132
  },
133
133
  "cancellation_submitted_by": {
134
134
  "en": "Cancellation request submitted by {{userName}} ({{employeeId}})",
135
- "ar": "تم تقديم طلب الإلغاء بواسطة {{userName}} ({{employeeId}})"
135
+ "ar": "تم تقديم طلب الإلغاء من قبل {{userName}} ({{employeeId}})"
136
136
  },
137
137
  "cancellation_submitted": {
138
138
  "en": "Cancellation request submitted",
@@ -142,6 +142,10 @@
142
142
  "en": "Request Received",
143
143
  "ar": "تم استلام الطلب"
144
144
  },
145
+ "request_assigned_by_role": {
146
+ "en": "Request assigned by {{roleName}}{{comment}}",
147
+ "ar": "تم تعيين الطلب من قبل {{roleName}}{{comment}}"
148
+ },
145
149
  "request_approved_by_role": {
146
150
  "en": "Request Approved by: {{roleName}}{{comment}}",
147
151
  "ar": "تمت الموافقة على الطلب من قبل: {{roleName}}{{comment}}"
@@ -152,7 +156,7 @@
152
156
  },
153
157
  "request_returned_for_modification_by_role": {
154
158
  "en": "Request Returned for Modification by: {{roleName}}{{comment}}",
155
- "ar": "تم إرجاع الطلب للتعديل من قبل: {{roleName}}{{comment}}"
159
+ "ar": "تمت إعادة الطلب للتعديل من قبل: {{roleName}}{{comment}}"
156
160
  },
157
161
  "request_approved": {
158
162
  "en": "Request Approved{{comment}}",
@@ -164,7 +168,7 @@
164
168
  },
165
169
  "request_returned_for_modification": {
166
170
  "en": "Request Returned for Modification{{comment}}",
167
- "ar": "تم إرجاع الطلب للتعديل{{comment}}"
171
+ "ar": "تمت إعادة الطلب للتعديل{{comment}}"
168
172
  },
169
173
  "request_closed_by_role": {
170
174
  "en": "Request Closed by: {{roleName}}{{comment}}",
@@ -172,11 +176,11 @@
172
176
  },
173
177
  "request_for_change_by_role": {
174
178
  "en": "Request For Change by: {{roleName}}{{comment}}",
175
- "ar": "طلب تعديل من قبل: {{roleName}}{{comment}}"
179
+ "ar": "طلب تغيير من قبل: {{roleName}}{{comment}}"
176
180
  },
177
181
  "request_for_change_requested_by_role": {
178
182
  "en": "Request For Change requested by: {{roleName}}{{comment}}",
179
- "ar": "تم طلب التعديل من قبل: {{roleName}}{{comment}}"
183
+ "ar": "تم طلب التغيير من قبل: {{roleName}}{{comment}}"
180
184
  },
181
185
  "attachment_uploaded": {
182
186
  "en": "Attachment uploaded: {{fileName}}",
@@ -188,11 +192,11 @@
188
192
  },
189
193
  "task_status_in_progress_by_role": {
190
194
  "en": "Task status updated to \"In Progress\" by: {{roleName}}",
191
- "ar": "تم تحديث حالة المهمة إلى \"قيد التنفيذ\" بواسطة: {{roleName}}"
195
+ "ar": "تم تحديث حالة المهمة إلى \"قيد التنفيذ\" من قبل: {{roleName}}"
192
196
  },
193
197
  "task_completed_by_role": {
194
198
  "en": "Task Completed by: {{roleName}}{{comment}}",
195
- "ar": "تم إكمال المهمة بواسطة: {{roleName}}{{comment}}"
199
+ "ar": "اكتملت المهمة من قبل: {{roleName}}{{comment}}"
196
200
  },
197
201
  "task_status_updated": {
198
202
  "en": "Task status updated to {{status}}",
@@ -204,23 +208,23 @@
204
208
  },
205
209
  "it_helpdesk_technician_assigned": {
206
210
  "en": "IT technician {{level}} assigned to {{assignedRoleName}}: {{assignedUserName}}{{comment}}",
207
- "ar": "تم تعيين فني IT {{level}} إلى {{assignedRoleName}}: {{assignedUserName}}{{comment}}"
211
+ "ar": "تم تعيين فني تقنية المعلومات {{level}} إلى {{assignedRoleName}}: {{assignedUserName}}{{comment}}"
208
212
  },
209
213
  "it_helpdesk_reassigned_to_role": {
210
214
  "en": "{{approverRoleName}} reassigned request to {{reassignedRoleName}}{{comment}}",
211
- "ar": "أعاد {{approverRoleName}} تعيين الطلب إلى {{reassignedRoleName}}{{comment}}"
215
+ "ar": "{{approverRoleName}} تمت إعادة تعيين الطلب إلى {{reassignedRoleName}}{{comment}}"
212
216
  },
213
217
  "it_helpdesk_reassigned_to_l3": {
214
218
  "en": "{{approverRoleName}} reassigned request to L3{{comment}}",
215
- "ar": "أعاد {{approverRoleName}} تعيين الطلب إلى L3{{comment}}"
219
+ "ar": "{{approverRoleName}} تمت إعادة تعيين الطلب إلى المستوى الثالث (L3){{comment}}"
216
220
  },
217
221
  "it_helpdesk_reassigned_generic": {
218
222
  "en": "{{approverRoleName}} {{level}} reassigned the request{{comment}}",
219
- "ar": "أعاد {{approverRoleName}} {{level}} تعيين الطلب{{comment}}"
223
+ "ar": "{{approverRoleName}} {{level}} تمت إعادة تعيين الطلب{{comment}}"
220
224
  },
221
225
  "request_submitted_with_ref": {
222
226
  "en": "{{requestLabel}} #{{requestId}} has been submitted by {{userName}} ({{employeeId}})",
223
- "ar": "تم تقديم {{requestLabel}} رقم {{requestId}} بواسطة {{userName}} ({{employeeId}})"
227
+ "ar": "تم تقديم {{requestLabel}} رقم {{requestId}} من قبل {{userName}} ({{employeeId}})"
224
228
  },
225
229
  "security_access_approval_step": {
226
230
  "en": "{{productLabel}} request #{{requestId}} was {{statusWord}} (approval step {{approvalLevel}}).{{comment}}",
@@ -228,7 +232,7 @@
228
232
  },
229
233
  "logistics_actual_return_updated": {
230
234
  "en": "{{roleName}} updated the Vehicle Actual Return Date, Time, and Reason. Actual Return Date: {{date}}, Actual Return Time: {{time}}, Reason: {{reason}}",
231
- "ar": "قام {{roleName}} بتحديث تاريخ ووقت وسبب الإرجاع الفعلي للمركبة. تاريخ الإرجاع الفعلي: {{date}}، وقت الإرجاع الفعلي: {{time}}، السبب: {{reason}}"
235
+ "ar": "قام {{roleName}} بتحديث تاريخ الإرجاع الفعلي للمركبة والوقت والسبب. تاريخ الإرجاع الفعلي: {{date}}، وقت الإرجاع الفعلي: {{time}}، السبب: {{reason}}"
232
236
  }
233
237
  },
234
238
  "notificationTemplates": {
@@ -238,11 +242,11 @@
238
242
  },
239
243
  "it_helpdesk_notif_request_closed": {
240
244
  "en": "IT request #{{requestId}} has been closed",
241
- "ar": "تم إغلاق طلب IT رقم {{requestId}}"
245
+ "ar": "تم إغلاق طلب تقنية المعلومات رقم {{requestId}}"
242
246
  },
243
247
  "it_helpdesk_notif_request_rejected": {
244
248
  "en": "IT request #{{requestId}} has been rejected",
245
- "ar": "تم رفض طلب IT رقم {{requestId}}"
249
+ "ar": "تم رفض طلب تقنية المعلومات رقم {{requestId}}"
246
250
  }
247
251
  },
248
252
  "workflowStatusLabels": {
@@ -253,15 +257,15 @@
253
257
  "chatStatusLabels": {
254
258
  "Submitted": "تم التقديم",
255
259
  "Received": "تم الاستلام",
256
- "Approved": "موافق عليه",
257
- "Rejected": "مرفوض",
260
+ "Approved": "تم الموافقة",
261
+ "Rejected": "تم الرفض",
258
262
  "Pending": "قيد الانتظار",
259
- "Returned for Modification": "أُعيد للتعديل",
260
- "Request For Change": "طلب تعديل",
263
+ "Returned for Modification": "تمت إعادته للتعديل",
264
+ "Request For Change": "طلب تغيير",
261
265
  "Closed": "مغلق",
262
266
  "Completed": "مكتمل",
263
- "Assigned": "معيّن",
264
- "Reassigned": "أعيد التعيين",
267
+ "Assigned": "تم التعيين",
268
+ "Reassigned": "تمت إعادة التعيين",
265
269
  "In Progress": "قيد التنفيذ",
266
270
  "Attachment uploaded": "تم رفع المرفق"
267
271
  }
@@ -399,6 +399,19 @@ export function toChatPersistFields(
399
399
  };
400
400
  }
401
401
 
402
+ /** User-typed chat — never auto-translate; message_ar stays null. */
403
+ export function buildUserEnteredChatPersistFields(
404
+ message: string,
405
+ status: string,
406
+ ): { message: string; message_ar: null; status: string; status_ar: string | null } {
407
+ return {
408
+ message,
409
+ message_ar: null,
410
+ status,
411
+ status_ar: resolveChatStatusAr(status),
412
+ };
413
+ }
414
+
402
415
  export function buildApprovalWorkflowContent(params: {
403
416
  status: 'Approved' | 'Rejected' | 'Returned for Modification' | 'Pending' | string;
404
417
  roleName?: string | null;
@@ -1122,6 +1135,58 @@ function resolveArabicChatRoleName(
1122
1135
  return resolveBilingualName(parsedEnglishRole, actors?.roleArabicName);
1123
1136
  }
1124
1137
 
1138
+ function escapeRegexLiteral(value: string): string {
1139
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1140
+ }
1141
+
1142
+ /** Match a templated EN message and extract placeholder values (full-structure match). */
1143
+ function matchTemplateMessage(
1144
+ templateEn: string,
1145
+ message: string,
1146
+ ): Record<string, string> | null {
1147
+ if (!/\{\{\w+\}\}/.test(templateEn)) return null;
1148
+
1149
+ const placeholders: string[] = [];
1150
+ let regexBody = '';
1151
+ let cursor = 0;
1152
+ const tokenRe = /\{\{(\w+)\}\}/g;
1153
+ let tokenMatch: RegExpExecArray | null;
1154
+
1155
+ while ((tokenMatch = tokenRe.exec(templateEn)) !== null) {
1156
+ regexBody += escapeRegexLiteral(templateEn.slice(cursor, tokenMatch.index));
1157
+ const key = tokenMatch[1];
1158
+ placeholders.push(key);
1159
+ regexBody += key === 'comment' ? '(.*)' : '(.+?)';
1160
+ cursor = tokenMatch.index + tokenMatch[0].length;
1161
+ }
1162
+ regexBody += escapeRegexLiteral(templateEn.slice(cursor));
1163
+
1164
+ const match = message.match(new RegExp(`^${regexBody}$`, 's'));
1165
+ if (!match) return null;
1166
+
1167
+ const params: Record<string, string> = {};
1168
+ placeholders.forEach((key, index) => {
1169
+ params[key] = match[index + 1] ?? '';
1170
+ });
1171
+ return params;
1172
+ }
1173
+
1174
+ function buildArabicChatTemplateParams(
1175
+ params: Record<string, string>,
1176
+ actors?: BilingualActorNames,
1177
+ ): Record<string, string> {
1178
+ const arParams: Record<string, string> = { ...params };
1179
+ if (params.roleName !== undefined) {
1180
+ arParams.roleName = resolveArabicChatRoleName(actors, params.roleName.trim());
1181
+ }
1182
+ if (params.userName !== undefined) {
1183
+ arParams.userName = actors?.userName?.trim()
1184
+ ? resolveBilingualName(actors.userName, actors.userArabicName)
1185
+ : resolveBilingualName(params.userName.trim(), actors?.userArabicName);
1186
+ }
1187
+ return arParams;
1188
+ }
1189
+
1125
1190
  export function resolveWorkflowContentAr(
1126
1191
  content: string | null | undefined,
1127
1192
  actors?: BilingualActorNames,
@@ -1182,38 +1247,24 @@ export function resolveChatMessageAr(
1182
1247
  if (tpl.en === normalized) return tpl.ar;
1183
1248
  }
1184
1249
 
1185
- for (const tplKey of ['request_submitted_by', 'cancellation_submitted_by'] as const) {
1186
- const submittedTpl = CHAT_TEMPLATES[tplKey];
1187
- if (!submittedTpl) continue;
1188
- const prefix = submittedTpl.en.split('{{userName}}')[0];
1189
- if (!normalized.startsWith(prefix)) continue;
1190
- const afterPrefix = normalized.slice(prefix.length);
1191
- const parenMatch = afterPrefix.match(/^(.+?) \((.+)\)$/);
1192
- if (parenMatch) {
1193
- const userEn = parenMatch[1].trim();
1194
- const employeeId = parenMatch[2].trim();
1195
- const userAr = actors?.userName?.trim()
1196
- ? resolveBilingualName(actors.userName, actors.userArabicName)
1197
- : resolveBilingualName(userEn, actors?.userArabicName);
1198
- return interpolate(submittedTpl.ar, { userName: userAr, employeeId });
1199
- }
1200
- }
1201
-
1202
1250
  for (const tpl of Object.values(CHAT_TEMPLATES)) {
1203
- if (!tpl.en.includes('{{roleName}}')) continue;
1204
- const prefix = tpl.en.split('{{roleName}}')[0];
1205
- if (!normalized.startsWith(prefix)) continue;
1206
- const rest = normalized.slice(prefix.length);
1207
- const commentIdx = rest.lastIndexOf(' - ');
1208
- const roleNameEn = commentIdx >= 0 ? rest.slice(0, commentIdx) : rest;
1209
- const commentSuffix = commentIdx >= 0 ? rest.slice(commentIdx) : '';
1210
- const roleNameAr = resolveArabicChatRoleName(actors, roleNameEn.trim());
1211
- return interpolate(tpl.ar, { roleName: roleNameAr, comment: commentSuffix });
1251
+ if (!/\{\{\w+\}\}/.test(tpl.en)) continue;
1252
+ const params = matchTemplateMessage(tpl.en, normalized);
1253
+ if (!params) continue;
1254
+ return interpolate(tpl.ar, buildArabicChatTemplateParams(params, actors));
1212
1255
  }
1213
1256
 
1214
1257
  return null;
1215
1258
  }
1216
1259
 
1260
+ /** True when message matches a known system chat template (safe to resolve message_ar). */
1261
+ export function isSystemGeneratedChatMessage(
1262
+ message: string | null | undefined,
1263
+ actors?: BilingualActorNames,
1264
+ ): boolean {
1265
+ return resolveChatMessageAr(message, actors) != null;
1266
+ }
1267
+
1217
1268
  /** Generic workflow log enricher — use in all module repositories. */
1218
1269
  export function enrichWorkflowLog(log: Record<string, unknown>): Record<string, unknown> {
1219
1270
  const status = log.status != null ? String(log.status) : null;
package/src/index.ts CHANGED
@@ -425,6 +425,7 @@ export * from './models/MaintenanceAttachmentModel';
425
425
  export * from './models/MaintenanceChatModel';
426
426
  export * from './models/MaintenanceWorkflowModel';
427
427
  export * from './models/FollowUpReportRequestModel';
428
+ export * from './models/FollowUpReportItemModel';
428
429
  export * from './models/FollowUpReportApprovalModel';
429
430
  export * from './models/FollowUpReportAttachmentModel';
430
431
  export * from './models/FollowUpReportChatModel';