@hotmeshio/long-tail 0.4.13 → 0.4.15
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/build/api/escalations/claim.js +1 -10
- package/build/api/escalations/create.js +1 -11
- package/build/api/escalations/helpers.d.ts +14 -0
- package/build/api/escalations/helpers.js +14 -0
- package/build/api/escalations/index.d.ts +1 -0
- package/build/api/escalations/index.js +5 -1
- package/build/api/escalations/metadata.d.ts +58 -0
- package/build/api/escalations/metadata.js +172 -0
- package/build/api/escalations/resolve.js +4 -23
- package/build/bin/ltc.js +19 -0
- package/build/lib/cli/commands/escalations.d.ts +11 -0
- package/build/lib/cli/commands/escalations.js +40 -0
- package/build/lib/db/schemas/010_metadata_gin.sql +5 -0
- package/build/lib/events/publish.js +2 -0
- package/build/routes/escalations/index.js +3 -0
- package/build/routes/escalations/metadata.d.ts +6 -0
- package/build/routes/escalations/metadata.js +88 -0
- package/build/sdk/index.d.ts +21 -0
- package/build/sdk/index.js +3 -0
- package/build/services/escalation/crud.d.ts +5 -0
- package/build/services/escalation/crud.js +80 -3
- package/build/services/escalation/sql.d.ts +5 -0
- package/build/services/escalation/sql.js +42 -1
- package/build/services/interceptor/activities/escalation.js +1 -0
- package/build/services/interceptor/activities/task.js +2 -23
- package/build/services/interceptor/completion.js +2 -22
- package/build/services/interceptor/escalation.js +5 -44
- package/build/services/interceptor/index.js +26 -2
- package/build/services/interceptor/lifecycle.d.ts +1 -1
- package/build/services/interceptor/lifecycle.js +18 -32
- package/build/services/task/crud.js +36 -2
- package/build/start/server.js +5 -4
- package/build/tsconfig.tsbuildinfo +1 -1
- package/dashboard/dist/assets/{AdminDashboard-Jwr3Fsaz.js → AdminDashboard-BuqyRY2r.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Jwr3Fsaz.js.map → AdminDashboard-BuqyRY2r.js.map} +1 -1
- package/dashboard/dist/assets/AgentConfigPage-Bum1dUIi.js +16 -0
- package/dashboard/dist/assets/AgentConfigPage-Bum1dUIi.js.map +1 -0
- package/dashboard/dist/assets/{AgentDetailPage-Cw7foCHd.js → AgentDetailPage-0Kq-tBF2.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-Cw7foCHd.js.map → AgentDetailPage-0Kq-tBF2.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-DzpWsTFO.js → AgentsPage-B5gYDSOX.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-DzpWsTFO.js.map → AgentsPage-B5gYDSOX.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-BWHThQDC.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-BWHThQDC.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-Ddu4V0uf.js → BotPicker-BQ336piW.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-Ddu4V0uf.js.map → BotPicker-BQ336piW.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-BTd-uYTM.js → CapabilitiesPage-CkiJROX-.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-BTd-uYTM.js.map → CapabilitiesPage-CkiJROX-.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-DM-75khr.js → CollapsibleSection-SM8_UjNe.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-DM-75khr.js.map → CollapsibleSection-SM8_UjNe.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-BQNraRZu.js → CredentialsPage-f6niro9_.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-BQNraRZu.js.map → CredentialsPage-f6niro9_.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-CPuMNBua.js → CronLabel-DINmdqoe.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-CPuMNBua.js.map → CronLabel-DINmdqoe.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-CLq8B89Y.js → CustomDurationPicker-BCUcYxfB.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-CLq8B89Y.js.map → CustomDurationPicker-BCUcYxfB.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-8lk94nZt.js → ElapsedCell-DPYZnXsX.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-8lk94nZt.js.map → ElapsedCell-DPYZnXsX.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-BfSrQ7A5.js → EscalationsOverview-CTB8AEBd.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-BfSrQ7A5.js.map → EscalationsOverview-CTB8AEBd.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-D3IOLoxv.js → EventTable-8_r3Tg09.js} +2 -2
- package/dashboard/dist/assets/{EventTable-D3IOLoxv.js.map → EventTable-8_r3Tg09.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-RO3qbF38.js → HomePage-Bjxnjv6p.js} +2 -2
- package/dashboard/dist/assets/{HomePage-RO3qbF38.js.map → HomePage-Bjxnjv6p.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-4lObXT3_.js → ListToolbar-B60JrvJ9.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-4lObXT3_.js.map → ListToolbar-B60JrvJ9.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-BdLivZv8.js → McpOverview-whVRP_Nj.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-BdLivZv8.js.map → McpOverview-whVRP_Nj.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DKFkH1qa.js → McpQueryDetailPage-DPuujJkH.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DKFkH1qa.js.map → McpQueryDetailPage-DPuujJkH.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-AFV_QPwm.js → McpQueryPage-DciK6r7r.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-AFV_QPwm.js.map → McpQueryPage-DciK6r7r.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-DQJ41oKW.js → McpRunDetailPage-QEz8BCTu.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-DQJ41oKW.js.map → McpRunDetailPage-QEz8BCTu.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-CzVS7zcc.js → McpRunsPage-BA6AVpi_.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-CzVS7zcc.js.map → McpRunsPage-BA6AVpi_.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-DrUMzwnl.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-DrUMzwnl.js.map +1 -0
- package/dashboard/dist/assets/{ProcessDetailPage-qibro3Dm.js → ProcessDetailPage-Dc5ASJpQ.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-qibro3Dm.js.map → ProcessDetailPage-Dc5ASJpQ.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CPgiDbdS.js → ProcessesListPage-Sa-bjC-g.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CPgiDbdS.js.map → ProcessesListPage-Sa-bjC-g.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-BAj88I_Y.js → RolesPage-DmO8Jlbw.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-BAj88I_Y.js.map → RolesPage-DmO8Jlbw.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-IdZ-qOfl.js → RunAsSelector-yWEwIZRe.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-IdZ-qOfl.js.map → RunAsSelector-yWEwIZRe.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-WQ6VMuqg.js → SwimlaneTimeline-CmzfFQ09.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-WQ6VMuqg.js.map → SwimlaneTimeline-CmzfFQ09.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-buNgjwiz.js → TaskDetailPage-CI4JTC62.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-buNgjwiz.js.map → TaskDetailPage-CI4JTC62.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-BQjjNjRC.js → TasksListPage-xdNmQsNE.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-BQjjNjRC.js.map → TasksListPage-xdNmQsNE.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-Dvkw4shy.js → TimeAgo-B_um9BWR.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-Dvkw4shy.js.map → TimeAgo-B_um9BWR.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DGEGdbOW.js → TimestampCell-BJ6trAqW.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DGEGdbOW.js.map → TimestampCell-BJ6trAqW.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-GY3n1V12.js → ToolTestPanel-DMQhLDES.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-GY3n1V12.js.map → ToolTestPanel-DMQhLDES.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-CGim5yi0.js → TopicDetailPage-YeGQA0vD.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-CGim5yi0.js.map → TopicDetailPage-YeGQA0vD.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DLyRlo0A.js → TopicsPage-B3QZNlWz.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DLyRlo0A.js.map → TopicsPage-B3QZNlWz.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-B8dGlxj9.js → UserName-MpSZ2_EH.js} +2 -2
- package/dashboard/dist/assets/{UserName-B8dGlxj9.js.map → UserName-MpSZ2_EH.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-BQbIIdIA.js → WorkflowExecutionPage-DqMqDb1h.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-BQbIIdIA.js.map → WorkflowExecutionPage-DqMqDb1h.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DL6oRbka.js → WorkflowsDashboard-BF7FpMmk.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DL6oRbka.js.map → WorkflowsDashboard-BF7FpMmk.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-Reab_xHT.js → WorkflowsOverview-YFc_KBMS.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-Reab_xHT.js.map → WorkflowsOverview-YFc_KBMS.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BoFstOcp.js → YamlWorkflowsPage-BOLs5KTB.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BoFstOcp.js.map → YamlWorkflowsPage-BOLs5KTB.js.map} +1 -1
- package/dashboard/dist/assets/{agents-CQsJU21y.js → agents-CPYVSCQ3.js} +2 -2
- package/dashboard/dist/assets/{agents-CQsJU21y.js.map → agents-CPYVSCQ3.js.map} +1 -1
- package/dashboard/dist/assets/{bots-t1FPESbm.js → bots-DCXjHjID.js} +2 -2
- package/dashboard/dist/assets/{bots-t1FPESbm.js.map → bots-DCXjHjID.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-D1Y3hVvf.js → capabilities-CreogBYU.js} +2 -2
- package/dashboard/dist/assets/{capabilities-D1Y3hVvf.js.map → capabilities-CreogBYU.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CV-y8cfH.js → controlplane-Cm_-Gb1x.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CV-y8cfH.js.map → controlplane-Cm_-Gb1x.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-CLqe28Ba.js +2 -0
- package/dashboard/dist/assets/escalation-columns-CLqe28Ba.js.map +1 -0
- package/dashboard/dist/assets/{escalation-Bf_SO_75.js → escalation-ulsBFHVb.js} +2 -2
- package/dashboard/dist/assets/{escalation-Bf_SO_75.js.map → escalation-ulsBFHVb.js.map} +1 -1
- package/dashboard/dist/assets/{helpers-nWSTagzD.js → helpers-etjHeZEI.js} +2 -2
- package/dashboard/dist/assets/{helpers-nWSTagzD.js.map → helpers-etjHeZEI.js.map} +1 -1
- package/dashboard/dist/assets/{index-BRYCB_g0.js → index-7Fbktqcl.js} +2 -2
- package/dashboard/dist/assets/{index-BRYCB_g0.js.map → index-7Fbktqcl.js.map} +1 -1
- package/dashboard/dist/assets/{index-CHBiEYmf.js → index-BkCkBW_D.js} +2 -2
- package/dashboard/dist/assets/{index-CHBiEYmf.js.map → index-BkCkBW_D.js.map} +1 -1
- package/dashboard/dist/assets/{index-B77P0ssX.js → index-BkOv2dQA.js} +2 -2
- package/dashboard/dist/assets/{index-B77P0ssX.js.map → index-BkOv2dQA.js.map} +1 -1
- package/dashboard/dist/assets/index-C37LMzJa.css +1 -0
- package/dashboard/dist/assets/{index-DUaF8VYe.js → index-CKDOaej4.js} +6 -6
- package/dashboard/dist/assets/index-CKDOaej4.js.map +1 -0
- package/dashboard/dist/assets/{index-Dp8iH4i2.js → index-CcvHiZW-.js} +2 -2
- package/dashboard/dist/assets/{index-Dp8iH4i2.js.map → index-CcvHiZW-.js.map} +1 -1
- package/dashboard/dist/assets/{index-BVXXvXlF.js → index-CihScSLF.js} +2 -2
- package/dashboard/dist/assets/{index-BVXXvXlF.js.map → index-CihScSLF.js.map} +1 -1
- package/dashboard/dist/assets/{index-wlL3EZ14.js → index-Cnpo94XG.js} +2 -2
- package/dashboard/dist/assets/{index-wlL3EZ14.js.map → index-Cnpo94XG.js.map} +1 -1
- package/dashboard/dist/assets/{index-CdUj8mKq.js → index-DFuHrLll.js} +2 -2
- package/dashboard/dist/assets/{index-CdUj8mKq.js.map → index-DFuHrLll.js.map} +1 -1
- package/dashboard/dist/assets/{index-0i5oHs_4.js → index-DGpIF_Td.js} +2 -2
- package/dashboard/dist/assets/{index-0i5oHs_4.js.map → index-DGpIF_Td.js.map} +1 -1
- package/dashboard/dist/assets/{index-C42ACUTi.js → index-DT0JeuiL.js} +2 -2
- package/dashboard/dist/assets/{index-C42ACUTi.js.map → index-DT0JeuiL.js.map} +1 -1
- package/dashboard/dist/assets/{index-MO0YnTPi.js → index-DT68ewTC.js} +2 -2
- package/dashboard/dist/assets/{index-MO0YnTPi.js.map → index-DT68ewTC.js.map} +1 -1
- package/dashboard/dist/assets/{index-DAQvhgrL.js → index-DVqtJBno.js} +2 -2
- package/dashboard/dist/assets/{index-DAQvhgrL.js.map → index-DVqtJBno.js.map} +1 -1
- package/dashboard/dist/assets/{index-BZu5zewH.js → index-DYmrNJ_H.js} +4 -4
- package/dashboard/dist/assets/index-DYmrNJ_H.js.map +1 -0
- package/dashboard/dist/assets/{knowledge-DJhm5z0p.js → knowledge-CXA2DJwY.js} +2 -2
- package/dashboard/dist/assets/{knowledge-DJhm5z0p.js.map → knowledge-CXA2DJwY.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-DMYXb9fv.js → mcp-DeC-PpeL.js} +2 -2
- package/dashboard/dist/assets/{mcp-DMYXb9fv.js.map → mcp-DeC-PpeL.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-DE-oPOvi.js → mcp-query-DldD_RPZ.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-DE-oPOvi.js.map → mcp-query-DldD_RPZ.js.map} +1 -1
- package/dashboard/dist/assets/{namespaces-Bjjm4EG1.js → namespaces-BIGZ6exX.js} +2 -2
- package/dashboard/dist/assets/{namespaces-Bjjm4EG1.js.map → namespaces-BIGZ6exX.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-C8aRprVr.js → pipelines-BtihifKT.js} +2 -2
- package/dashboard/dist/assets/{pipelines-C8aRprVr.js.map → pipelines-BtihifKT.js.map} +1 -1
- package/dashboard/dist/assets/{roles-CQsPYJXe.js → roles-4DocbpKy.js} +2 -2
- package/dashboard/dist/assets/{roles-CQsPYJXe.js.map → roles-4DocbpKy.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BQ1c7trT.js → tasks-B9P_7SR_.js} +2 -2
- package/dashboard/dist/assets/{tasks-BQ1c7trT.js.map → tasks-B9P_7SR_.js.map} +1 -1
- package/dashboard/dist/assets/{topics-DIziCjqg.js → topics-CcLT-IrY.js} +2 -2
- package/dashboard/dist/assets/{topics-DIziCjqg.js.map → topics-CcLT-IrY.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-CPxcH6zx.js → useEventHooks-B9UOxef_.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-CPxcH6zx.js.map → useEventHooks-B9UOxef_.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-DnPywDgy.js → useYamlActivityEvents-V_MENSI5.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DnPywDgy.js.map → useYamlActivityEvents-V_MENSI5.js.map} +1 -1
- package/dashboard/dist/assets/{users-CMGaVe_B.js → users-BHF3YOU1.js} +2 -2
- package/dashboard/dist/assets/{users-CMGaVe_B.js.map → users-BHF3YOU1.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-CD7-d5w8.js → workflows-DorgmYSk.js} +2 -2
- package/dashboard/dist/assets/{workflows-CD7-d5w8.js.map → workflows-DorgmYSk.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-CIeymjZr.js → yaml-workflows-DTGpqnEG.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-CIeymjZr.js.map → yaml-workflows-DTGpqnEG.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/http/escalations.md +98 -0
- package/docs/api/sdk/escalations.md +86 -0
- package/docs/cli.md +8 -0
- package/docs/sdk.md +1 -1
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentConfigPage-DbqbFXEq.js +0 -16
- package/dashboard/dist/assets/AgentConfigPage-DbqbFXEq.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-D2cxvpAK.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-D2cxvpAK.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-B_QmNzLw.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-B_QmNzLw.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-DgY8c1hM.js +0 -2
- package/dashboard/dist/assets/escalation-columns-DgY8c1hM.js.map +0 -1
- package/dashboard/dist/assets/index-BZu5zewH.js.map +0 -1
- package/dashboard/dist/assets/index-DUaF8VYe.js.map +0 -1
- package/dashboard/dist/assets/index-ib-nDwd6.css +0 -1
|
@@ -71,16 +71,7 @@ async function claimEscalation(input, auth) {
|
|
|
71
71
|
if (!result) {
|
|
72
72
|
return { status: 409, error: 'Escalation not available for claim' };
|
|
73
73
|
}
|
|
74
|
-
(
|
|
75
|
-
type: 'escalation.claimed',
|
|
76
|
-
source: 'api',
|
|
77
|
-
workflowId: escalation.workflow_id || '',
|
|
78
|
-
workflowName: escalation.workflow_type || '',
|
|
79
|
-
taskQueue: escalation.task_queue || '',
|
|
80
|
-
escalationId: id,
|
|
81
|
-
status: 'claimed',
|
|
82
|
-
data: { assigned_to: auth.userId },
|
|
83
|
-
});
|
|
74
|
+
// Event published by service layer (services/escalation/crud.ts)
|
|
84
75
|
return { status: 200, data: result };
|
|
85
76
|
}
|
|
86
77
|
catch (err) {
|
|
@@ -36,7 +36,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.createEscalation = createEscalation;
|
|
37
37
|
const escalationService = __importStar(require("../../services/escalation"));
|
|
38
38
|
const userService = __importStar(require("../../services/user"));
|
|
39
|
-
const publish_1 = require("../../lib/events/publish");
|
|
40
39
|
// ── Create ────────────────────────────────────────────────────────────────
|
|
41
40
|
/**
|
|
42
41
|
* Create a standalone escalation (not tied to a workflow).
|
|
@@ -83,16 +82,7 @@ async function createEscalation(input, auth) {
|
|
|
83
82
|
metadata: input.metadata,
|
|
84
83
|
escalation_payload: input.escalation_payload,
|
|
85
84
|
});
|
|
86
|
-
(
|
|
87
|
-
type: 'escalation.created',
|
|
88
|
-
source: 'api',
|
|
89
|
-
workflowId: '',
|
|
90
|
-
workflowName: '',
|
|
91
|
-
taskQueue: '',
|
|
92
|
-
escalationId: escalation.id,
|
|
93
|
-
status: 'pending',
|
|
94
|
-
data: { type: input.type, role },
|
|
95
|
-
});
|
|
85
|
+
// Event published by service layer (services/escalation/crud.ts)
|
|
96
86
|
return { status: 201, data: escalation };
|
|
97
87
|
}
|
|
98
88
|
catch (err) {
|
|
@@ -7,4 +7,18 @@ export declare function checkBulkPermission(userId: string, ids: string[]): Prom
|
|
|
7
7
|
status: 403;
|
|
8
8
|
error: string;
|
|
9
9
|
}>;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve an optional assignee external_id to an internal userId.
|
|
12
|
+
* When omitted, returns the caller's userId from auth.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveAssignee(assignee: string | undefined, auth: {
|
|
15
|
+
userId: string;
|
|
16
|
+
}): Promise<{
|
|
17
|
+
userId: string;
|
|
18
|
+
} | {
|
|
19
|
+
error: {
|
|
20
|
+
status: number;
|
|
21
|
+
error: string;
|
|
22
|
+
};
|
|
23
|
+
}>;
|
|
10
24
|
export declare function publishBulkClaimEvents(ids: string[], assignedTo: string): void;
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.getVisibleRoles = getVisibleRoles;
|
|
37
37
|
exports.validateIds = validateIds;
|
|
38
38
|
exports.checkBulkPermission = checkBulkPermission;
|
|
39
|
+
exports.resolveAssignee = resolveAssignee;
|
|
39
40
|
exports.publishBulkClaimEvents = publishBulkClaimEvents;
|
|
40
41
|
const escalationService = __importStar(require("../../services/escalation"));
|
|
41
42
|
const userService = __importStar(require("../../services/user"));
|
|
@@ -64,6 +65,19 @@ async function checkBulkPermission(userId, ids) {
|
|
|
64
65
|
}
|
|
65
66
|
return { allowed: true };
|
|
66
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Resolve an optional assignee external_id to an internal userId.
|
|
70
|
+
* When omitted, returns the caller's userId from auth.
|
|
71
|
+
*/
|
|
72
|
+
async function resolveAssignee(assignee, auth) {
|
|
73
|
+
if (!assignee)
|
|
74
|
+
return { userId: auth.userId };
|
|
75
|
+
const user = await userService.getUserByExternalId(assignee);
|
|
76
|
+
if (!user) {
|
|
77
|
+
return { error: { status: 404, error: `User not found for external_id: ${assignee}` } };
|
|
78
|
+
}
|
|
79
|
+
return { userId: user.id };
|
|
80
|
+
}
|
|
67
81
|
function publishBulkClaimEvents(ids, assignedTo) {
|
|
68
82
|
for (const id of ids) {
|
|
69
83
|
(0, publish_1.publishEscalationEvent)({
|
|
@@ -4,3 +4,4 @@ export { getEscalation, getEscalationsByWorkflowId, escalateToRole } from './sin
|
|
|
4
4
|
export { claimEscalation, releaseEscalation } from './claim';
|
|
5
5
|
export { releaseExpiredClaims, updatePriority, bulkClaim, bulkAssign, bulkEscalate, bulkTriage } from './bulk';
|
|
6
6
|
export { resolveEscalation } from './resolve';
|
|
7
|
+
export { findByMetadata, claimByMetadata, resolveByMetadata } from './metadata';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getEscalationStats = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
|
|
3
|
+
exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getEscalationStats = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
|
|
4
4
|
var create_1 = require("./create");
|
|
5
5
|
Object.defineProperty(exports, "createEscalation", { enumerable: true, get: function () { return create_1.createEscalation; } });
|
|
6
6
|
var list_1 = require("./list");
|
|
@@ -24,3 +24,7 @@ Object.defineProperty(exports, "bulkEscalate", { enumerable: true, get: function
|
|
|
24
24
|
Object.defineProperty(exports, "bulkTriage", { enumerable: true, get: function () { return bulk_1.bulkTriage; } });
|
|
25
25
|
var resolve_1 = require("./resolve");
|
|
26
26
|
Object.defineProperty(exports, "resolveEscalation", { enumerable: true, get: function () { return resolve_1.resolveEscalation; } });
|
|
27
|
+
var metadata_1 = require("./metadata");
|
|
28
|
+
Object.defineProperty(exports, "findByMetadata", { enumerable: true, get: function () { return metadata_1.findByMetadata; } });
|
|
29
|
+
Object.defineProperty(exports, "claimByMetadata", { enumerable: true, get: function () { return metadata_1.claimByMetadata; } });
|
|
30
|
+
Object.defineProperty(exports, "resolveByMetadata", { enumerable: true, get: function () { return metadata_1.resolveByMetadata; } });
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { LTApiAuth, LTApiResult } from '../../types/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Find escalations by a metadata key-value pair.
|
|
4
|
+
*
|
|
5
|
+
* Uses JSONB containment (`@>`) backed by a GIN index.
|
|
6
|
+
* Results are RBAC-scoped to the caller's visible roles.
|
|
7
|
+
*
|
|
8
|
+
* @param input.key — metadata field name (e.g. `"orderId"`)
|
|
9
|
+
* @param input.value — metadata field value (e.g. `"order-123"`)
|
|
10
|
+
* @param input.status — optional status filter (e.g. `"pending"`)
|
|
11
|
+
* @returns `{ status: 200, data: { escalations, total } }`
|
|
12
|
+
*/
|
|
13
|
+
export declare function findByMetadata(input: {
|
|
14
|
+
key: string;
|
|
15
|
+
value: string;
|
|
16
|
+
status?: string;
|
|
17
|
+
limit?: number;
|
|
18
|
+
offset?: number;
|
|
19
|
+
}, auth: LTApiAuth): Promise<LTApiResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Claim an escalation by metadata key-value pair.
|
|
22
|
+
*
|
|
23
|
+
* Finds one available (pending + unassigned/expired) escalation matching
|
|
24
|
+
* the metadata and claims it atomically. Optionally resolves an assignee
|
|
25
|
+
* from an external_id.
|
|
26
|
+
*
|
|
27
|
+
* @param input.key — metadata field name
|
|
28
|
+
* @param input.value — metadata field value
|
|
29
|
+
* @param input.durationMinutes — claim duration (default 30)
|
|
30
|
+
* @param input.assignee — optional external_id of the user to claim as
|
|
31
|
+
* @returns `{ status: 200, data: { escalation, isExtension } }`
|
|
32
|
+
*/
|
|
33
|
+
export declare function claimByMetadata(input: {
|
|
34
|
+
key: string;
|
|
35
|
+
value: string;
|
|
36
|
+
durationMinutes?: number;
|
|
37
|
+
assignee?: string;
|
|
38
|
+
metadata?: Record<string, any>;
|
|
39
|
+
}, auth: LTApiAuth): Promise<LTApiResult>;
|
|
40
|
+
/**
|
|
41
|
+
* Resolve an escalation by metadata key-value pair.
|
|
42
|
+
*
|
|
43
|
+
* Finds the pending escalation, auto-claims if unclaimed, then delegates
|
|
44
|
+
* to the standard resolve logic (supports all 5 resolution paths).
|
|
45
|
+
*
|
|
46
|
+
* @param input.key — metadata field name
|
|
47
|
+
* @param input.value — metadata field value
|
|
48
|
+
* @param input.resolverPayload — resolution data for the workflow
|
|
49
|
+
* @param input.assignee — optional external_id of the resolving user
|
|
50
|
+
* @returns result from the standard resolve endpoint
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveByMetadata(input: {
|
|
53
|
+
key: string;
|
|
54
|
+
value: string;
|
|
55
|
+
resolverPayload: Record<string, any>;
|
|
56
|
+
assignee?: string;
|
|
57
|
+
metadata?: Record<string, any>;
|
|
58
|
+
}, auth: LTApiAuth): Promise<LTApiResult>;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.findByMetadata = findByMetadata;
|
|
37
|
+
exports.claimByMetadata = claimByMetadata;
|
|
38
|
+
exports.resolveByMetadata = resolveByMetadata;
|
|
39
|
+
const escalationService = __importStar(require("../../services/escalation"));
|
|
40
|
+
const userService = __importStar(require("../../services/user"));
|
|
41
|
+
const helpers_1 = require("./helpers");
|
|
42
|
+
/**
|
|
43
|
+
* Find escalations by a metadata key-value pair.
|
|
44
|
+
*
|
|
45
|
+
* Uses JSONB containment (`@>`) backed by a GIN index.
|
|
46
|
+
* Results are RBAC-scoped to the caller's visible roles.
|
|
47
|
+
*
|
|
48
|
+
* @param input.key — metadata field name (e.g. `"orderId"`)
|
|
49
|
+
* @param input.value — metadata field value (e.g. `"order-123"`)
|
|
50
|
+
* @param input.status — optional status filter (e.g. `"pending"`)
|
|
51
|
+
* @returns `{ status: 200, data: { escalations, total } }`
|
|
52
|
+
*/
|
|
53
|
+
async function findByMetadata(input, auth) {
|
|
54
|
+
try {
|
|
55
|
+
if (!input.key || !input.value) {
|
|
56
|
+
return { status: 400, error: 'key and value are required' };
|
|
57
|
+
}
|
|
58
|
+
const result = await escalationService.findByMetadata(input.key, input.value, input.status, input.limit, input.offset);
|
|
59
|
+
// RBAC: scope to visible roles
|
|
60
|
+
const visibleRoles = await (0, helpers_1.getVisibleRoles)(auth.userId);
|
|
61
|
+
if (visibleRoles) {
|
|
62
|
+
const roleSet = new Set(visibleRoles);
|
|
63
|
+
result.escalations = result.escalations.filter(e => roleSet.has(e.role));
|
|
64
|
+
result.total = result.escalations.length;
|
|
65
|
+
}
|
|
66
|
+
return { status: 200, data: result };
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
return { status: 500, error: err.message };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Claim an escalation by metadata key-value pair.
|
|
74
|
+
*
|
|
75
|
+
* Finds one available (pending + unassigned/expired) escalation matching
|
|
76
|
+
* the metadata and claims it atomically. Optionally resolves an assignee
|
|
77
|
+
* from an external_id.
|
|
78
|
+
*
|
|
79
|
+
* @param input.key — metadata field name
|
|
80
|
+
* @param input.value — metadata field value
|
|
81
|
+
* @param input.durationMinutes — claim duration (default 30)
|
|
82
|
+
* @param input.assignee — optional external_id of the user to claim as
|
|
83
|
+
* @returns `{ status: 200, data: { escalation, isExtension } }`
|
|
84
|
+
*/
|
|
85
|
+
async function claimByMetadata(input, auth) {
|
|
86
|
+
try {
|
|
87
|
+
if (!input.key || !input.value) {
|
|
88
|
+
return { status: 400, error: 'key and value are required' };
|
|
89
|
+
}
|
|
90
|
+
const resolved = await (0, helpers_1.resolveAssignee)(input.assignee, auth);
|
|
91
|
+
if ('error' in resolved)
|
|
92
|
+
return resolved.error;
|
|
93
|
+
const claimUserId = resolved.userId;
|
|
94
|
+
// RBAC: find the candidate to check role membership before atomic claim
|
|
95
|
+
const candidates = await escalationService.findByMetadata(input.key, input.value, 'pending', 1, 0);
|
|
96
|
+
if (candidates.escalations.length === 0) {
|
|
97
|
+
return { status: 404, error: 'No pending escalation found for this metadata' };
|
|
98
|
+
}
|
|
99
|
+
const candidate = candidates.escalations[0];
|
|
100
|
+
const isSuperAdmin = await userService.isSuperAdmin(auth.userId);
|
|
101
|
+
if (!isSuperAdmin) {
|
|
102
|
+
const userHasRole = await userService.hasRole(claimUserId, candidate.role);
|
|
103
|
+
if (!userHasRole) {
|
|
104
|
+
return { status: 403, error: `User must have the "${candidate.role}" role to claim this escalation` };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const result = await escalationService.claimByMetadata(input.key, input.value, claimUserId, input.durationMinutes, input.metadata);
|
|
108
|
+
if (!result) {
|
|
109
|
+
return { status: 409, error: 'Escalation not available for claim' };
|
|
110
|
+
}
|
|
111
|
+
// Event published by service layer (services/escalation/crud.ts)
|
|
112
|
+
return { status: 200, data: result };
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
return { status: 500, error: err.message };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolve an escalation by metadata key-value pair.
|
|
120
|
+
*
|
|
121
|
+
* Finds the pending escalation, auto-claims if unclaimed, then delegates
|
|
122
|
+
* to the standard resolve logic (supports all 5 resolution paths).
|
|
123
|
+
*
|
|
124
|
+
* @param input.key — metadata field name
|
|
125
|
+
* @param input.value — metadata field value
|
|
126
|
+
* @param input.resolverPayload — resolution data for the workflow
|
|
127
|
+
* @param input.assignee — optional external_id of the resolving user
|
|
128
|
+
* @returns result from the standard resolve endpoint
|
|
129
|
+
*/
|
|
130
|
+
async function resolveByMetadata(input, auth) {
|
|
131
|
+
try {
|
|
132
|
+
if (!input.key || !input.value) {
|
|
133
|
+
return { status: 400, error: 'key and value are required' };
|
|
134
|
+
}
|
|
135
|
+
if (!input.resolverPayload) {
|
|
136
|
+
return { status: 400, error: 'resolverPayload is required' };
|
|
137
|
+
}
|
|
138
|
+
const candidates = await escalationService.findByMetadata(input.key, input.value, 'pending', 1, 0);
|
|
139
|
+
if (candidates.escalations.length === 0) {
|
|
140
|
+
return { status: 404, error: 'No pending escalation found for this metadata' };
|
|
141
|
+
}
|
|
142
|
+
const escalation = candidates.escalations[0];
|
|
143
|
+
const resolved = await (0, helpers_1.resolveAssignee)(input.assignee, auth);
|
|
144
|
+
if ('error' in resolved)
|
|
145
|
+
return resolved.error;
|
|
146
|
+
const resolveUserId = resolved.userId;
|
|
147
|
+
const isSuperAdmin = await userService.isSuperAdmin(auth.userId);
|
|
148
|
+
if (!isSuperAdmin) {
|
|
149
|
+
const userHasRole = await userService.hasRole(resolveUserId, escalation.role);
|
|
150
|
+
if (!userHasRole) {
|
|
151
|
+
return { status: 403, error: `User must have the "${escalation.role}" role` };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Merge additional metadata if provided
|
|
155
|
+
if (input.metadata && Object.keys(input.metadata).length > 0) {
|
|
156
|
+
await escalationService.updateEscalationMetadata(escalation.id, input.metadata);
|
|
157
|
+
}
|
|
158
|
+
// Auto-claim if unclaimed or expired
|
|
159
|
+
const isClaimed = escalation.assigned_to &&
|
|
160
|
+
escalation.assigned_until &&
|
|
161
|
+
new Date(escalation.assigned_until) > new Date();
|
|
162
|
+
if (!isClaimed) {
|
|
163
|
+
await escalationService.claimEscalation(escalation.id, resolveUserId, 5);
|
|
164
|
+
}
|
|
165
|
+
// Delegate to the full resolve logic (handles all 5 resolution paths)
|
|
166
|
+
const { resolveEscalation } = await Promise.resolve().then(() => __importStar(require('./resolve')));
|
|
167
|
+
return resolveEscalation({ id: escalation.id, resolverPayload: input.resolverPayload }, auth);
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
return { status: 500, error: err.message };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -36,7 +36,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.resolveEscalation = resolveEscalation;
|
|
37
37
|
const escalationService = __importStar(require("../../services/escalation"));
|
|
38
38
|
const taskService = __importStar(require("../../services/task"));
|
|
39
|
-
const publish_1 = require("../../lib/events/publish");
|
|
40
39
|
const escalation_strategy_1 = require("../../services/escalation-strategy");
|
|
41
40
|
const ephemeral_1 = require("../../services/iam/ephemeral");
|
|
42
41
|
const deployer_1 = require("../../services/yaml-workflow/deployer");
|
|
@@ -105,7 +104,7 @@ async function resolveViaConditionSignal(escalation, resolverPayload) {
|
|
|
105
104
|
const client = (0, workers_1.createClient)();
|
|
106
105
|
const handle = await client.workflow.getHandle(escalation.task_queue, escalation.workflow_type, escalation.workflow_id);
|
|
107
106
|
await handle.signal(signalId, { ...resolverPayload, $escalation_id: escalation.id });
|
|
108
|
-
|
|
107
|
+
// Event published by service layer (services/escalation/crud.ts)
|
|
109
108
|
return signaledResult(escalation, escalation.workflow_id);
|
|
110
109
|
}
|
|
111
110
|
/** Path B: waitFor signal escalation — signal via YAML engine or Durable handle. */
|
|
@@ -129,12 +128,7 @@ async function resolveViaSignalRouting(escalation, resolverPayload) {
|
|
|
129
128
|
if (signalRouting.engine !== 'yaml') {
|
|
130
129
|
await escalationService.resolveEscalation(escalation.id, resolverPayload);
|
|
131
130
|
}
|
|
132
|
-
|
|
133
|
-
workflowId: escalation.workflow_id || signalRouting.workflowId,
|
|
134
|
-
workflowName: escalation.workflow_type || signalRouting.workflowType,
|
|
135
|
-
taskQueue: escalation.task_queue || signalRouting.taskQueue || signalRouting.appId,
|
|
136
|
-
status: signalRouting.engine === 'yaml' ? 'signaled' : 'resolved',
|
|
137
|
-
});
|
|
131
|
+
// Event published by service layer (services/escalation/crud.ts)
|
|
138
132
|
return signaledResult(escalation, signalRouting.workflowId || signalRouting.appId);
|
|
139
133
|
}
|
|
140
134
|
/** Path C: escalation strategy directed triage — start a triage workflow. */
|
|
@@ -165,7 +159,7 @@ async function resolveViaTriage(escalation, resolverPayload, triageEnvelope) {
|
|
|
165
159
|
...resolverPayload,
|
|
166
160
|
_lt: { ...resolverPayload._lt, triaged: true, triageWorkflowId },
|
|
167
161
|
});
|
|
168
|
-
|
|
162
|
+
// Event published by service layer (services/escalation/crud.ts)
|
|
169
163
|
return {
|
|
170
164
|
status: 200,
|
|
171
165
|
data: { started: true, escalationId: escalation.id, workflowId: triageWorkflowId, triage: true },
|
|
@@ -184,26 +178,13 @@ async function resolveViaRerun(escalation, envelope, resolverPayload) {
|
|
|
184
178
|
workflowId: newWorkflowId,
|
|
185
179
|
expire: 180,
|
|
186
180
|
});
|
|
187
|
-
|
|
181
|
+
// Event published by service layer (services/escalation/crud.ts)
|
|
188
182
|
return {
|
|
189
183
|
status: 200,
|
|
190
184
|
data: { started: true, escalationId: escalation.id, workflowId: newWorkflowId },
|
|
191
185
|
};
|
|
192
186
|
}
|
|
193
187
|
// ── Shared helpers ───────────────────────────────────────────────────────
|
|
194
|
-
function publishResolvedEvent(escalation, overrides) {
|
|
195
|
-
(0, publish_1.publishEscalationEvent)({
|
|
196
|
-
type: 'escalation.resolved',
|
|
197
|
-
source: 'api',
|
|
198
|
-
workflowId: overrides?.workflowId || escalation.workflow_id || '',
|
|
199
|
-
workflowName: overrides?.workflowName || escalation.workflow_type || '',
|
|
200
|
-
taskQueue: overrides?.taskQueue || escalation.task_queue || '',
|
|
201
|
-
taskId: escalation.task_id,
|
|
202
|
-
escalationId: escalation.id,
|
|
203
|
-
originId: escalation.origin_id ?? undefined,
|
|
204
|
-
status: overrides?.status || 'resolved',
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
188
|
function signaledResult(escalation, workflowId) {
|
|
208
189
|
return {
|
|
209
190
|
status: 200,
|
package/build/bin/ltc.js
CHANGED
|
@@ -134,6 +134,25 @@ escCmd.command('release <id>')
|
|
|
134
134
|
escCmd.command('resolve <id>')
|
|
135
135
|
.requiredOption('--data <json>', 'Resolver payload (JSON string)')
|
|
136
136
|
.action(wrap(esc.resolveEscalation));
|
|
137
|
+
escCmd.command('find-by-meta <key> <value>')
|
|
138
|
+
.description('Find escalations by metadata key-value pair')
|
|
139
|
+
.option('--status <status>', 'Filter by status')
|
|
140
|
+
.option('--limit <n>', 'Max results')
|
|
141
|
+
.option('--json', 'JSON output')
|
|
142
|
+
.option('-q, --quiet', 'IDs only')
|
|
143
|
+
.action(wrap(esc.findByMetadata));
|
|
144
|
+
escCmd.command('claim-by-meta <key> <value>')
|
|
145
|
+
.description('Claim an escalation by metadata key-value pair')
|
|
146
|
+
.option('--duration <minutes>', 'Claim duration in minutes')
|
|
147
|
+
.option('--assignee <external_id>', 'Claim on behalf of user (external_id)')
|
|
148
|
+
.option('--meta <json>', 'Merge metadata (JSON object, e.g. \'{"claimedBy":"jimbo"}\')')
|
|
149
|
+
.action(wrap(esc.claimByMetadata));
|
|
150
|
+
escCmd.command('resolve-by-meta <key> <value>')
|
|
151
|
+
.description('Resolve an escalation by metadata key-value pair')
|
|
152
|
+
.option('--data <json>', 'Resolver payload (JSON string)')
|
|
153
|
+
.option('--assignee <external_id>', 'Resolve on behalf of user (external_id)')
|
|
154
|
+
.option('--meta <json>', 'Merge metadata (JSON object)')
|
|
155
|
+
.action(wrap(esc.resolveByMetadata));
|
|
137
156
|
// ── Workflows ────────────────────────────────────────────────────────────
|
|
138
157
|
const wfCmd = commander_1.program.command('workflows').alias('wf').description('Manage durable workflows');
|
|
139
158
|
wfCmd.command('list')
|
|
@@ -16,4 +16,15 @@ export declare function releaseEscalation(id: string): Promise<void>;
|
|
|
16
16
|
export declare function resolveEscalation(id: string, opts: {
|
|
17
17
|
data?: string;
|
|
18
18
|
}): Promise<void>;
|
|
19
|
+
export declare function findByMetadata(key: string, value: string, opts: ListOptions): Promise<void>;
|
|
20
|
+
export declare function claimByMetadata(key: string, value: string, opts: {
|
|
21
|
+
duration?: string;
|
|
22
|
+
assignee?: string;
|
|
23
|
+
meta?: string;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
export declare function resolveByMetadata(key: string, value: string, opts: {
|
|
26
|
+
data?: string;
|
|
27
|
+
assignee?: string;
|
|
28
|
+
meta?: string;
|
|
29
|
+
}): Promise<void>;
|
|
19
30
|
export {};
|
|
@@ -8,6 +8,9 @@ exports.getEscalation = getEscalation;
|
|
|
8
8
|
exports.claimEscalation = claimEscalation;
|
|
9
9
|
exports.releaseEscalation = releaseEscalation;
|
|
10
10
|
exports.resolveEscalation = resolveEscalation;
|
|
11
|
+
exports.findByMetadata = findByMetadata;
|
|
12
|
+
exports.claimByMetadata = claimByMetadata;
|
|
13
|
+
exports.resolveByMetadata = resolveByMetadata;
|
|
11
14
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
12
15
|
const client_1 = require("../client");
|
|
13
16
|
const format_1 = require("../format");
|
|
@@ -67,3 +70,40 @@ async function resolveEscalation(id, opts) {
|
|
|
67
70
|
});
|
|
68
71
|
console.log(`\n ${picocolors_1.default.green('✓')} Resolved ${picocolors_1.default.dim(id)}\n`);
|
|
69
72
|
}
|
|
73
|
+
// --- Metadata candidate key commands ----------------------------------------
|
|
74
|
+
async function findByMetadata(key, value, opts) {
|
|
75
|
+
const params = new URLSearchParams({ key, value });
|
|
76
|
+
if (opts.status)
|
|
77
|
+
params.set('status', opts.status);
|
|
78
|
+
if (opts.limit)
|
|
79
|
+
params.set('limit', opts.limit);
|
|
80
|
+
const data = await (0, client_1.apiFetch)(`/escalations/by-metadata?${params}`);
|
|
81
|
+
(0, format_1.output)(data, data.escalations || [], COLUMNS, opts);
|
|
82
|
+
}
|
|
83
|
+
async function claimByMetadata(key, value, opts) {
|
|
84
|
+
const body = { key, value };
|
|
85
|
+
if (opts.duration)
|
|
86
|
+
body.durationMinutes = parseInt(opts.duration, 10);
|
|
87
|
+
if (opts.assignee)
|
|
88
|
+
body.assignee = opts.assignee;
|
|
89
|
+
if (opts.meta)
|
|
90
|
+
body.metadata = JSON.parse(opts.meta);
|
|
91
|
+
const data = await (0, client_1.apiFetch)('/escalations/claim-by-metadata', {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
body: JSON.stringify(body),
|
|
94
|
+
});
|
|
95
|
+
console.log(`\n ${picocolors_1.default.green('✓')} Claimed ${picocolors_1.default.dim(data.escalation?.id || '')} by ${key}=${value}\n`);
|
|
96
|
+
}
|
|
97
|
+
async function resolveByMetadata(key, value, opts) {
|
|
98
|
+
const resolverPayload = opts.data ? JSON.parse(opts.data) : {};
|
|
99
|
+
const body = { key, value, resolverPayload };
|
|
100
|
+
if (opts.assignee)
|
|
101
|
+
body.assignee = opts.assignee;
|
|
102
|
+
if (opts.meta)
|
|
103
|
+
body.metadata = JSON.parse(opts.meta);
|
|
104
|
+
await (0, client_1.apiFetch)('/escalations/resolve-by-metadata', {
|
|
105
|
+
method: 'POST',
|
|
106
|
+
body: JSON.stringify(body),
|
|
107
|
+
});
|
|
108
|
+
console.log(`\n ${picocolors_1.default.green('✓')} Resolved by ${key}=${value}\n`);
|
|
109
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- GIN index for JSONB containment queries on lt_escalations.metadata.
|
|
2
|
+
-- Enables efficient lookups like: WHERE metadata @> '{"orderId":"order-123"}'::jsonb
|
|
3
|
+
-- Uses jsonb_path_ops (smaller, faster for @> queries).
|
|
4
|
+
CREATE INDEX IF NOT EXISTS idx_lt_escalations_metadata
|
|
5
|
+
ON lt_escalations USING GIN (metadata jsonb_path_ops);
|
|
@@ -9,12 +9,14 @@ exports.publishFileEvent = publishFileEvent;
|
|
|
9
9
|
exports.publishAgentEvent = publishAgentEvent;
|
|
10
10
|
exports.publishWorkflowEvent = publishWorkflowEvent;
|
|
11
11
|
const index_1 = require("./index");
|
|
12
|
+
const logger_1 = require("../logger");
|
|
12
13
|
/**
|
|
13
14
|
* Fire-and-forget publish helper. Swallows errors (best-effort).
|
|
14
15
|
*/
|
|
15
16
|
function fireAndForget(event) {
|
|
16
17
|
if (!index_1.eventRegistry.hasAdapters)
|
|
17
18
|
return Promise.resolve();
|
|
19
|
+
logger_1.loggerRegistry.info(`[lt-pub] ${event.type} ${event.workflowId || ''} ${event.escalationId || event.taskId || ''}`);
|
|
18
20
|
return index_1.eventRegistry.publish(event).catch(() => { });
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const express_1 = require("express");
|
|
4
4
|
const list_1 = require("./list");
|
|
5
5
|
const bulk_1 = require("./bulk");
|
|
6
|
+
const metadata_1 = require("./metadata");
|
|
6
7
|
const single_1 = require("./single");
|
|
7
8
|
const resolve_1 = require("./resolve");
|
|
8
9
|
const router = (0, express_1.Router)();
|
|
@@ -12,6 +13,8 @@ const router = (0, express_1.Router)();
|
|
|
12
13
|
// POST /release-expired, PATCH /priority, POST /bulk-claim,
|
|
13
14
|
// POST /bulk-assign, PATCH /bulk-escalate, POST /bulk-triage
|
|
14
15
|
(0, bulk_1.registerBulkRoutes)(router);
|
|
16
|
+
// GET /by-metadata, POST /claim-by-metadata, POST /resolve-by-metadata
|
|
17
|
+
(0, metadata_1.registerMetadataRoutes)(router);
|
|
15
18
|
// PATCH /:id/escalate, GET /by-workflow/:workflowId,
|
|
16
19
|
// GET /:id, POST /:id/claim, POST /:id/release
|
|
17
20
|
(0, single_1.registerSingleRoutes)(router);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerMetadataRoutes = registerMetadataRoutes;
|
|
37
|
+
const api = __importStar(require("../../api/escalations"));
|
|
38
|
+
/**
|
|
39
|
+
* Register metadata-based escalation lookup routes.
|
|
40
|
+
* Must be registered BEFORE parameterized /:id routes.
|
|
41
|
+
*/
|
|
42
|
+
function registerMetadataRoutes(router) {
|
|
43
|
+
/**
|
|
44
|
+
* GET /api/escalations/by-metadata
|
|
45
|
+
* Find escalations by a metadata key-value pair.
|
|
46
|
+
* Query: key, value, status?, limit?, offset?
|
|
47
|
+
*/
|
|
48
|
+
router.get('/by-metadata', async (req, res) => {
|
|
49
|
+
const result = await api.findByMetadata({
|
|
50
|
+
key: req.query.key,
|
|
51
|
+
value: req.query.value,
|
|
52
|
+
status: req.query.status,
|
|
53
|
+
limit: req.query.limit ? parseInt(req.query.limit, 10) : undefined,
|
|
54
|
+
offset: req.query.offset ? parseInt(req.query.offset, 10) : undefined,
|
|
55
|
+
}, req.auth);
|
|
56
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* POST /api/escalations/claim-by-metadata
|
|
60
|
+
* Find and claim an escalation by metadata key-value pair.
|
|
61
|
+
* Body: { key, value, durationMinutes?, assignee?, metadata? }
|
|
62
|
+
*/
|
|
63
|
+
router.post('/claim-by-metadata', async (req, res) => {
|
|
64
|
+
const result = await api.claimByMetadata({
|
|
65
|
+
key: req.body?.key,
|
|
66
|
+
value: req.body?.value,
|
|
67
|
+
durationMinutes: req.body?.durationMinutes,
|
|
68
|
+
assignee: req.body?.assignee,
|
|
69
|
+
metadata: req.body?.metadata,
|
|
70
|
+
}, req.auth);
|
|
71
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
72
|
+
});
|
|
73
|
+
/**
|
|
74
|
+
* POST /api/escalations/resolve-by-metadata
|
|
75
|
+
* Find and resolve an escalation by metadata key-value pair.
|
|
76
|
+
* Body: { key, value, resolverPayload, assignee?, metadata? }
|
|
77
|
+
*/
|
|
78
|
+
router.post('/resolve-by-metadata', async (req, res) => {
|
|
79
|
+
const result = await api.resolveByMetadata({
|
|
80
|
+
key: req.body?.key,
|
|
81
|
+
value: req.body?.value,
|
|
82
|
+
resolverPayload: req.body?.resolverPayload,
|
|
83
|
+
assignee: req.body?.assignee,
|
|
84
|
+
metadata: req.body?.metadata,
|
|
85
|
+
}, req.auth);
|
|
86
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
87
|
+
});
|
|
88
|
+
}
|