@platform-modules/civil-aviation-authority 2.3.306 → 2.3.308
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/i18n/workflow-chat-message.builder.js +76 -1
- package/dist/models/FollowUpReportRequestModel.d.ts +1 -0
- package/dist/models/FollowUpReportRequestModel.js +4 -0
- package/package.json +1 -1
- package/sql/caa_api_payload_changes_2026_07.sql +4 -0
- package/src/i18n/workflow-chat-message.builder.ts +92 -1
- package/src/models/FollowUpReportRequestModel.ts +3 -0
|
@@ -1044,7 +1044,9 @@ function matchTemplateMessage(templateEn, message) {
|
|
|
1044
1044
|
}
|
|
1045
1045
|
groupIndex += 1;
|
|
1046
1046
|
captures.push({ key, groupIndex });
|
|
1047
|
-
|
|
1047
|
+
const rest = templateEn.slice(tokenMatch.index + tokenMatch[0].length);
|
|
1048
|
+
const isLastPlaceholder = !/\{\{\w+\}\}/.test(rest);
|
|
1049
|
+
regexBody += key === 'modifiers' || isLastPlaceholder ? '(.*)' : '(.+?)';
|
|
1048
1050
|
cursor = tokenMatch.index + tokenMatch[0].length;
|
|
1049
1051
|
}
|
|
1050
1052
|
regexBody += escapeRegexLiteral(templateEn.slice(cursor));
|
|
@@ -1103,6 +1105,54 @@ function countTemplatePlaceholders(templateEn) {
|
|
|
1103
1105
|
function listWorkflowTemplatesBySpecificity() {
|
|
1104
1106
|
return Object.entries(WORKFLOW_TEMPLATES).sort(([, a], [, b]) => countTemplatePlaceholders(b.en) - countTemplatePlaceholders(a.en));
|
|
1105
1107
|
}
|
|
1108
|
+
const IT_HELPDESK_REASSIGN_WORKFLOW_KEYS = [
|
|
1109
|
+
'it_helpdesk_wf_reassigned_l3',
|
|
1110
|
+
'it_helpdesk_wf_reassigned_technician',
|
|
1111
|
+
'it_helpdesk_wf_reassigned_generic',
|
|
1112
|
+
];
|
|
1113
|
+
const IT_HELPDESK_REASSIGN_CHAT_KEYS = [
|
|
1114
|
+
'it_helpdesk_reassigned_to_l3',
|
|
1115
|
+
'it_helpdesk_reassigned_to_role',
|
|
1116
|
+
'it_helpdesk_reassigned_generic',
|
|
1117
|
+
];
|
|
1118
|
+
/**
|
|
1119
|
+
* IT Helpdesk reassignment templates share placeholder-heavy shapes; the generic
|
|
1120
|
+
* workflow template must not win over "reassigned request to L3/Technician".
|
|
1121
|
+
*/
|
|
1122
|
+
function tryResolveItHelpdeskReassignmentWorkflowAr(normalized, actors) {
|
|
1123
|
+
for (const key of IT_HELPDESK_REASSIGN_WORKFLOW_KEYS) {
|
|
1124
|
+
const tpl = WORKFLOW_TEMPLATES[key];
|
|
1125
|
+
if (!tpl)
|
|
1126
|
+
continue;
|
|
1127
|
+
const params = matchTemplateMessage(tpl.en, normalized);
|
|
1128
|
+
if (!params)
|
|
1129
|
+
continue;
|
|
1130
|
+
if (key === 'it_helpdesk_wf_reassigned_generic' && !/^\d+$/.test((params.level ?? '').trim())) {
|
|
1131
|
+
continue;
|
|
1132
|
+
}
|
|
1133
|
+
return interpolate(tpl.ar, buildArabicWorkflowTemplateParams(params, actors));
|
|
1134
|
+
}
|
|
1135
|
+
return null;
|
|
1136
|
+
}
|
|
1137
|
+
function tryResolveItHelpdeskReassignmentChatAr(normalized, actors) {
|
|
1138
|
+
for (const key of IT_HELPDESK_REASSIGN_CHAT_KEYS) {
|
|
1139
|
+
const tpl = CHAT_TEMPLATES[key];
|
|
1140
|
+
if (!tpl)
|
|
1141
|
+
continue;
|
|
1142
|
+
const params = matchTemplateMessage(tpl.en, normalized);
|
|
1143
|
+
if (!params)
|
|
1144
|
+
continue;
|
|
1145
|
+
if (key === 'it_helpdesk_reassigned_generic' && !/^\d+$/.test((params.level ?? '').trim())) {
|
|
1146
|
+
continue;
|
|
1147
|
+
}
|
|
1148
|
+
if (key === 'it_helpdesk_reassigned_to_role' &&
|
|
1149
|
+
(params.reassignedRoleName ?? '').trim().toLowerCase() === 'l3') {
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
return interpolate(tpl.ar, buildArabicChatTemplateParams(params, actors));
|
|
1153
|
+
}
|
|
1154
|
+
return null;
|
|
1155
|
+
}
|
|
1106
1156
|
/** Parse legacy IT Helpdesk Muscat EN workflow strings before generic template matching. */
|
|
1107
1157
|
function tryResolveItHelpdeskMuscatLegacyWorkflowAr(content, actors) {
|
|
1108
1158
|
const { base, comment } = splitWorkflowColonComment(content);
|
|
@@ -1298,6 +1348,9 @@ function resolveWorkflowContentAr(content, actors) {
|
|
|
1298
1348
|
const itHelpdeskLegacyAr = tryResolveItHelpdeskMuscatLegacyWorkflowAr(normalized, actors);
|
|
1299
1349
|
if (itHelpdeskLegacyAr)
|
|
1300
1350
|
return itHelpdeskLegacyAr;
|
|
1351
|
+
const itHelpdeskReassignAr = tryResolveItHelpdeskReassignmentWorkflowAr(normalized, actors);
|
|
1352
|
+
if (itHelpdeskReassignAr)
|
|
1353
|
+
return itHelpdeskReassignAr;
|
|
1301
1354
|
for (const tpl of Object.values(WORKFLOW_TEMPLATES)) {
|
|
1302
1355
|
if (tpl.en === normalized || tpl.en.toLowerCase() === normalized.toLowerCase())
|
|
1303
1356
|
return tpl.ar;
|
|
@@ -1308,6 +1361,10 @@ function resolveWorkflowContentAr(content, actors) {
|
|
|
1308
1361
|
const params = matchTemplateMessage(tpl.en, normalized);
|
|
1309
1362
|
if (!params)
|
|
1310
1363
|
continue;
|
|
1364
|
+
if (tpl.en === WORKFLOW_TEMPLATES.it_helpdesk_wf_reassigned_generic?.en &&
|
|
1365
|
+
!/^\d+$/.test((params.level ?? '').trim())) {
|
|
1366
|
+
continue;
|
|
1367
|
+
}
|
|
1311
1368
|
return interpolate(tpl.ar, buildArabicWorkflowTemplateParams(params, actors));
|
|
1312
1369
|
}
|
|
1313
1370
|
const commentIdx = normalized.indexOf(': ');
|
|
@@ -1399,12 +1456,23 @@ function resolveChatMessageAr(message, actors) {
|
|
|
1399
1456
|
if (tpl.en === normalized)
|
|
1400
1457
|
return tpl.ar;
|
|
1401
1458
|
}
|
|
1459
|
+
const itHelpdeskReassignChatAr = tryResolveItHelpdeskReassignmentChatAr(normalized, actors);
|
|
1460
|
+
if (itHelpdeskReassignChatAr)
|
|
1461
|
+
return itHelpdeskReassignChatAr;
|
|
1402
1462
|
for (const tpl of Object.values(CHAT_TEMPLATES)) {
|
|
1403
1463
|
if (!/\{\{\w+\}\}/.test(tpl.en))
|
|
1404
1464
|
continue;
|
|
1405
1465
|
const params = matchTemplateMessage(tpl.en, normalized);
|
|
1406
1466
|
if (!params)
|
|
1407
1467
|
continue;
|
|
1468
|
+
if (tpl.en === CHAT_TEMPLATES.it_helpdesk_reassigned_generic?.en &&
|
|
1469
|
+
!/^\d+$/.test((params.level ?? '').trim())) {
|
|
1470
|
+
continue;
|
|
1471
|
+
}
|
|
1472
|
+
if (tpl.en === CHAT_TEMPLATES.it_helpdesk_reassigned_to_role?.en &&
|
|
1473
|
+
(params.reassignedRoleName ?? '').trim().toLowerCase() === 'l3') {
|
|
1474
|
+
continue;
|
|
1475
|
+
}
|
|
1408
1476
|
return interpolate(tpl.ar, buildArabicChatTemplateParams(params, actors));
|
|
1409
1477
|
}
|
|
1410
1478
|
const receivedByPrefix = 'Request Received by ';
|
|
@@ -1484,6 +1552,13 @@ function enrichWorkflowLog(log) {
|
|
|
1484
1552
|
existingAr.includes(actors.roleName.trim())) {
|
|
1485
1553
|
content_ar = resolvedAr;
|
|
1486
1554
|
}
|
|
1555
|
+
if (content &&
|
|
1556
|
+
existingAr &&
|
|
1557
|
+
resolvedAr &&
|
|
1558
|
+
existingAr !== resolvedAr &&
|
|
1559
|
+
/reassigned request to (L3|Technician)/i.test(content)) {
|
|
1560
|
+
content_ar = resolvedAr;
|
|
1561
|
+
}
|
|
1487
1562
|
const itHelpdeskMixedEnglish = /routed to L3|assignment path|Workflow decision made|L3 Technical Support approved|L3 assignment not required|HOS notification not required|routing completed/i;
|
|
1488
1563
|
if (content &&
|
|
1489
1564
|
existingAr &&
|
|
@@ -40,6 +40,7 @@ export declare class FollowUpReportRequests extends BaseModel {
|
|
|
40
40
|
subject_classification: FollowUpReportSubjectClassification;
|
|
41
41
|
topic: string;
|
|
42
42
|
concerned_department: FollowUpReportConcernedDepartment;
|
|
43
|
+
relevant_department: string | null;
|
|
43
44
|
date_from: Date;
|
|
44
45
|
date_to: Date;
|
|
45
46
|
general_manager_comment: string | null;
|
|
@@ -101,6 +101,10 @@ __decorate([
|
|
|
101
101
|
}),
|
|
102
102
|
__metadata("design:type", String)
|
|
103
103
|
], FollowUpReportRequests.prototype, "concerned_department", void 0);
|
|
104
|
+
__decorate([
|
|
105
|
+
(0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
|
|
106
|
+
__metadata("design:type", Object)
|
|
107
|
+
], FollowUpReportRequests.prototype, "relevant_department", void 0);
|
|
104
108
|
__decorate([
|
|
105
109
|
(0, typeorm_1.Column)({ type: 'date', nullable: false }),
|
|
106
110
|
__metadata("design:type", Date)
|
package/package.json
CHANGED
|
@@ -143,3 +143,7 @@ ALTER TABLE followup_report_items
|
|
|
143
143
|
-- 10. Departments: optional parent DG department reference (self FK to departments.id)
|
|
144
144
|
ALTER TABLE departments
|
|
145
145
|
ADD COLUMN IF NOT EXISTS "DG_department_id" INTEGER NULL;
|
|
146
|
+
|
|
147
|
+
-- 11. Follow-up report requests: optional relevant department
|
|
148
|
+
ALTER TABLE followup_report_requests
|
|
149
|
+
ADD COLUMN IF NOT EXISTS relevant_department VARCHAR(255) NULL;
|
|
@@ -1659,7 +1659,9 @@ function matchTemplateMessage(
|
|
|
1659
1659
|
|
|
1660
1660
|
groupIndex += 1;
|
|
1661
1661
|
captures.push({ key, groupIndex });
|
|
1662
|
-
|
|
1662
|
+
const rest = templateEn.slice(tokenMatch.index + tokenMatch[0].length);
|
|
1663
|
+
const isLastPlaceholder = !/\{\{\w+\}\}/.test(rest);
|
|
1664
|
+
regexBody += key === 'modifiers' || isLastPlaceholder ? '(.*)' : '(.+?)';
|
|
1663
1665
|
cursor = tokenMatch.index + tokenMatch[0].length;
|
|
1664
1666
|
}
|
|
1665
1667
|
regexBody += escapeRegexLiteral(templateEn.slice(cursor));
|
|
@@ -1733,6 +1735,62 @@ function listWorkflowTemplatesBySpecificity(): Array<[string, BilingualText]> {
|
|
|
1733
1735
|
);
|
|
1734
1736
|
}
|
|
1735
1737
|
|
|
1738
|
+
const IT_HELPDESK_REASSIGN_WORKFLOW_KEYS = [
|
|
1739
|
+
'it_helpdesk_wf_reassigned_l3',
|
|
1740
|
+
'it_helpdesk_wf_reassigned_technician',
|
|
1741
|
+
'it_helpdesk_wf_reassigned_generic',
|
|
1742
|
+
] as const;
|
|
1743
|
+
|
|
1744
|
+
const IT_HELPDESK_REASSIGN_CHAT_KEYS = [
|
|
1745
|
+
'it_helpdesk_reassigned_to_l3',
|
|
1746
|
+
'it_helpdesk_reassigned_to_role',
|
|
1747
|
+
'it_helpdesk_reassigned_generic',
|
|
1748
|
+
] as const;
|
|
1749
|
+
|
|
1750
|
+
/**
|
|
1751
|
+
* IT Helpdesk reassignment templates share placeholder-heavy shapes; the generic
|
|
1752
|
+
* workflow template must not win over "reassigned request to L3/Technician".
|
|
1753
|
+
*/
|
|
1754
|
+
function tryResolveItHelpdeskReassignmentWorkflowAr(
|
|
1755
|
+
normalized: string,
|
|
1756
|
+
actors?: BilingualActorNames,
|
|
1757
|
+
): string | null {
|
|
1758
|
+
for (const key of IT_HELPDESK_REASSIGN_WORKFLOW_KEYS) {
|
|
1759
|
+
const tpl = WORKFLOW_TEMPLATES[key];
|
|
1760
|
+
if (!tpl) continue;
|
|
1761
|
+
const params = matchTemplateMessage(tpl.en, normalized);
|
|
1762
|
+
if (!params) continue;
|
|
1763
|
+
if (key === 'it_helpdesk_wf_reassigned_generic' && !/^\d+$/.test((params.level ?? '').trim())) {
|
|
1764
|
+
continue;
|
|
1765
|
+
}
|
|
1766
|
+
return interpolate(tpl.ar, buildArabicWorkflowTemplateParams(params, actors));
|
|
1767
|
+
}
|
|
1768
|
+
return null;
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
function tryResolveItHelpdeskReassignmentChatAr(
|
|
1772
|
+
normalized: string,
|
|
1773
|
+
actors?: BilingualActorNames,
|
|
1774
|
+
): string | null {
|
|
1775
|
+
for (const key of IT_HELPDESK_REASSIGN_CHAT_KEYS) {
|
|
1776
|
+
const tpl = CHAT_TEMPLATES[key];
|
|
1777
|
+
if (!tpl) continue;
|
|
1778
|
+
const params = matchTemplateMessage(tpl.en, normalized);
|
|
1779
|
+
if (!params) continue;
|
|
1780
|
+
if (key === 'it_helpdesk_reassigned_generic' && !/^\d+$/.test((params.level ?? '').trim())) {
|
|
1781
|
+
continue;
|
|
1782
|
+
}
|
|
1783
|
+
if (
|
|
1784
|
+
key === 'it_helpdesk_reassigned_to_role' &&
|
|
1785
|
+
(params.reassignedRoleName ?? '').trim().toLowerCase() === 'l3'
|
|
1786
|
+
) {
|
|
1787
|
+
continue;
|
|
1788
|
+
}
|
|
1789
|
+
return interpolate(tpl.ar, buildArabicChatTemplateParams(params, actors));
|
|
1790
|
+
}
|
|
1791
|
+
return null;
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1736
1794
|
/** Parse legacy IT Helpdesk Muscat EN workflow strings before generic template matching. */
|
|
1737
1795
|
function tryResolveItHelpdeskMuscatLegacyWorkflowAr(
|
|
1738
1796
|
content: string,
|
|
@@ -1957,6 +2015,9 @@ export function resolveWorkflowContentAr(
|
|
|
1957
2015
|
const itHelpdeskLegacyAr = tryResolveItHelpdeskMuscatLegacyWorkflowAr(normalized, actors);
|
|
1958
2016
|
if (itHelpdeskLegacyAr) return itHelpdeskLegacyAr;
|
|
1959
2017
|
|
|
2018
|
+
const itHelpdeskReassignAr = tryResolveItHelpdeskReassignmentWorkflowAr(normalized, actors);
|
|
2019
|
+
if (itHelpdeskReassignAr) return itHelpdeskReassignAr;
|
|
2020
|
+
|
|
1960
2021
|
for (const tpl of Object.values(WORKFLOW_TEMPLATES)) {
|
|
1961
2022
|
if (tpl.en === normalized || tpl.en.toLowerCase() === normalized.toLowerCase()) return tpl.ar;
|
|
1962
2023
|
}
|
|
@@ -1965,6 +2026,12 @@ export function resolveWorkflowContentAr(
|
|
|
1965
2026
|
if (!/\{\{\w+\}\}/.test(tpl.en)) continue;
|
|
1966
2027
|
const params = matchTemplateMessage(tpl.en, normalized);
|
|
1967
2028
|
if (!params) continue;
|
|
2029
|
+
if (
|
|
2030
|
+
tpl.en === WORKFLOW_TEMPLATES.it_helpdesk_wf_reassigned_generic?.en &&
|
|
2031
|
+
!/^\d+$/.test((params.level ?? '').trim())
|
|
2032
|
+
) {
|
|
2033
|
+
continue;
|
|
2034
|
+
}
|
|
1968
2035
|
return interpolate(tpl.ar, buildArabicWorkflowTemplateParams(params, actors));
|
|
1969
2036
|
}
|
|
1970
2037
|
|
|
@@ -2067,10 +2134,25 @@ export function resolveChatMessageAr(
|
|
|
2067
2134
|
if (tpl.en === normalized) return tpl.ar;
|
|
2068
2135
|
}
|
|
2069
2136
|
|
|
2137
|
+
const itHelpdeskReassignChatAr = tryResolveItHelpdeskReassignmentChatAr(normalized, actors);
|
|
2138
|
+
if (itHelpdeskReassignChatAr) return itHelpdeskReassignChatAr;
|
|
2139
|
+
|
|
2070
2140
|
for (const tpl of Object.values(CHAT_TEMPLATES)) {
|
|
2071
2141
|
if (!/\{\{\w+\}\}/.test(tpl.en)) continue;
|
|
2072
2142
|
const params = matchTemplateMessage(tpl.en, normalized);
|
|
2073
2143
|
if (!params) continue;
|
|
2144
|
+
if (
|
|
2145
|
+
tpl.en === CHAT_TEMPLATES.it_helpdesk_reassigned_generic?.en &&
|
|
2146
|
+
!/^\d+$/.test((params.level ?? '').trim())
|
|
2147
|
+
) {
|
|
2148
|
+
continue;
|
|
2149
|
+
}
|
|
2150
|
+
if (
|
|
2151
|
+
tpl.en === CHAT_TEMPLATES.it_helpdesk_reassigned_to_role?.en &&
|
|
2152
|
+
(params.reassignedRoleName ?? '').trim().toLowerCase() === 'l3'
|
|
2153
|
+
) {
|
|
2154
|
+
continue;
|
|
2155
|
+
}
|
|
2074
2156
|
return interpolate(tpl.ar, buildArabicChatTemplateParams(params, actors));
|
|
2075
2157
|
}
|
|
2076
2158
|
|
|
@@ -2172,6 +2254,15 @@ export function enrichWorkflowLog(log: Record<string, unknown>): Record<string,
|
|
|
2172
2254
|
) {
|
|
2173
2255
|
content_ar = resolvedAr;
|
|
2174
2256
|
}
|
|
2257
|
+
if (
|
|
2258
|
+
content &&
|
|
2259
|
+
existingAr &&
|
|
2260
|
+
resolvedAr &&
|
|
2261
|
+
existingAr !== resolvedAr &&
|
|
2262
|
+
/reassigned request to (L3|Technician)/i.test(content)
|
|
2263
|
+
) {
|
|
2264
|
+
content_ar = resolvedAr;
|
|
2265
|
+
}
|
|
2175
2266
|
const itHelpdeskMixedEnglish =
|
|
2176
2267
|
/routed to L3|assignment path|Workflow decision made|L3 Technical Support approved|L3 assignment not required|HOS notification not required|routing completed/i;
|
|
2177
2268
|
if (
|
|
@@ -81,6 +81,9 @@ export class FollowUpReportRequests extends BaseModel {
|
|
|
81
81
|
})
|
|
82
82
|
concerned_department: FollowUpReportConcernedDepartment;
|
|
83
83
|
|
|
84
|
+
@Column({ type: 'varchar', length: 255, nullable: true })
|
|
85
|
+
relevant_department: string | null;
|
|
86
|
+
|
|
84
87
|
@Column({ type: 'date', nullable: false })
|
|
85
88
|
date_from: Date;
|
|
86
89
|
|