@aglyn/plugins-workflows 1.0.0-beta.229 → 1.0.0-beta.230
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/package.json +12 -12
- package/src/lib/components/host-actions-card.component.js +20 -3
- package/src/lib/components/host-actions-card.component.js.map +1 -1
- package/src/lib/components/host-workflows-card.component.d.ts +7 -0
- package/src/lib/components/host-workflows-card.component.js +35 -5
- package/src/lib/components/host-workflows-card.component.js.map +1 -1
- package/src/lib/components/org-automation-editor.component.d.ts +9 -0
- package/src/lib/components/org-automation-editor.component.js +32 -1
- package/src/lib/components/org-automation-editor.component.js.map +1 -1
- package/src/lib/components/org-automations-card.component.js +41 -9
- package/src/lib/components/org-automations-card.component.js.map +1 -1
- package/src/lib/components/workflow-zones.d.ts +53 -1
- package/src/lib/components/workflow-zones.js +14 -0
- package/src/lib/components/workflow-zones.js.map +1 -1
- package/src/lib/components/workflows-console-page.js +5 -3
- package/src/lib/components/workflows-console-page.js.map +1 -1
- package/src/lib/plugin.js +12 -3
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/automation-run-figures.d.ts +38 -0
- package/src/lib/server/automation-run-figures.js +182 -0
- package/src/lib/server/automation-run-figures.js.map +1 -0
- package/src/lib/server-console.js +5 -0
- package/src/lib/server-console.js.map +1 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { PLUGIN_FIGURE_MAX_ROWS, pluginFigureChange, pluginFigureWindows, registerPluginFigureReader } from "@aglyn/aglyn/plugin-manager/plugin-figures";
|
|
17
|
+
import { BUNDLE_ID } from "../constants/bundle-common.js";
|
|
18
|
+
/** Runs of one result one window reads for the per-automation split. */ export const AUTOMATION_RUN_FIGURES_WINDOW_CEILING = 500;
|
|
19
|
+
const WINDOWS = [
|
|
20
|
+
7,
|
|
21
|
+
14,
|
|
22
|
+
30,
|
|
23
|
+
90
|
|
24
|
+
];
|
|
25
|
+
function runsOf(firestore, hostId, result, startMs, endMs) {
|
|
26
|
+
return firestore.collection('hosts').doc(hostId).collection('activity').where('result', '==', result).where('createdAt', '>=', new Date(startMs)).where('createdAt', '<', new Date(endMs));
|
|
27
|
+
}
|
|
28
|
+
async function countOf(query) {
|
|
29
|
+
const snapshot = await query.count().get();
|
|
30
|
+
return Number(snapshot.data().count) || 0;
|
|
31
|
+
}
|
|
32
|
+
/** Runs of one result in the window, by the automation they belong to, read to the ceiling. */ async function byAutomation(query) {
|
|
33
|
+
const snapshot = await query.orderBy('createdAt', 'desc').select('target').limit(AUTOMATION_RUN_FIGURES_WINDOW_CEILING + 1).get();
|
|
34
|
+
const names = new Map();
|
|
35
|
+
for (const doc of snapshot.docs.slice(0, AUTOMATION_RUN_FIGURES_WINDOW_CEILING)){
|
|
36
|
+
var _doc_get, _names_get;
|
|
37
|
+
const target = (_doc_get = doc.get('target')) != null ? _doc_get : {};
|
|
38
|
+
const name = typeof target.name === 'string' && target.name.trim() || 'An automation with no name';
|
|
39
|
+
names.set(name, ((_names_get = names.get(name)) != null ? _names_get : 0) + 1);
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
names,
|
|
43
|
+
truncated: snapshot.docs.length > AUTOMATION_RUN_FIGURES_WINDOW_CEILING
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const failureRate = (counts)=>{
|
|
47
|
+
const total = counts.succeeded + counts.failed;
|
|
48
|
+
return total > 0 ? Math.round(counts.failed / total * 1000) / 10 : null;
|
|
49
|
+
};
|
|
50
|
+
export function automationRunFigureReader(firestore) {
|
|
51
|
+
return {
|
|
52
|
+
id: 'automations.runs',
|
|
53
|
+
label: 'Automation runs',
|
|
54
|
+
description: 'Runs of the site’s automations — actions, workflows and organization automations — over the window: how many succeeded and failed, the failure rate, and the change in runs from the window before, in total and by automation.',
|
|
55
|
+
scope: 'site',
|
|
56
|
+
windows: WINDOWS,
|
|
57
|
+
read: async (request)=>{
|
|
58
|
+
if (!request.hostId) return {
|
|
59
|
+
ok: false,
|
|
60
|
+
status: 400,
|
|
61
|
+
error: 'Open a site to read its automation runs'
|
|
62
|
+
};
|
|
63
|
+
if (!WINDOWS.includes(request.days)) {
|
|
64
|
+
return {
|
|
65
|
+
ok: false,
|
|
66
|
+
status: 400,
|
|
67
|
+
error: 'That window is not one automation runs are read over'
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const db = firestore();
|
|
71
|
+
const hostId = request.hostId;
|
|
72
|
+
const { current, previous } = pluginFigureWindows(request.now, request.days);
|
|
73
|
+
const [succeeded, failed, before, okRuns, failedRuns] = await Promise.all([
|
|
74
|
+
countOf(runsOf(db, hostId, 'succeeded', current.startMs, current.endMs)),
|
|
75
|
+
countOf(runsOf(db, hostId, 'failed', current.startMs, current.endMs)),
|
|
76
|
+
Promise.all([
|
|
77
|
+
countOf(runsOf(db, hostId, 'succeeded', previous.startMs, previous.endMs)),
|
|
78
|
+
countOf(runsOf(db, hostId, 'failed', previous.startMs, previous.endMs))
|
|
79
|
+
]).then(([a, b])=>a + b),
|
|
80
|
+
byAutomation(runsOf(db, hostId, 'succeeded', current.startMs, current.endMs)),
|
|
81
|
+
byAutomation(runsOf(db, hostId, 'failed', current.startMs, current.endMs))
|
|
82
|
+
]);
|
|
83
|
+
const automations = new Map();
|
|
84
|
+
for (const [name, count] of okRuns.names){
|
|
85
|
+
var _ref;
|
|
86
|
+
var _automations_get;
|
|
87
|
+
automations.set(name, {
|
|
88
|
+
succeeded: count,
|
|
89
|
+
failed: (_ref = (_automations_get = automations.get(name)) == null ? void 0 : _automations_get.failed) != null ? _ref : 0
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
for (const [name, count] of failedRuns.names){
|
|
93
|
+
var _ref1;
|
|
94
|
+
var _automations_get1;
|
|
95
|
+
automations.set(name, {
|
|
96
|
+
succeeded: (_ref1 = (_automations_get1 = automations.get(name)) == null ? void 0 : _automations_get1.succeeded) != null ? _ref1 : 0,
|
|
97
|
+
failed: count
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// The most failures first: that is the question a person asks of runs.
|
|
101
|
+
const ranked = [
|
|
102
|
+
...automations.entries()
|
|
103
|
+
].sort((a, b)=>b[1].failed - a[1].failed || b[1].succeeded - a[1].succeeded || a[0].localeCompare(b[0]));
|
|
104
|
+
const totals = {
|
|
105
|
+
succeeded,
|
|
106
|
+
failed
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
ok: true,
|
|
110
|
+
table: {
|
|
111
|
+
title: 'Automation runs',
|
|
112
|
+
source: {
|
|
113
|
+
label: 'Automation',
|
|
114
|
+
path: 'automation'
|
|
115
|
+
},
|
|
116
|
+
period: {
|
|
117
|
+
from: current.from,
|
|
118
|
+
to: current.to,
|
|
119
|
+
days: request.days
|
|
120
|
+
},
|
|
121
|
+
columns: [
|
|
122
|
+
{
|
|
123
|
+
key: 'automation',
|
|
124
|
+
label: 'Automation',
|
|
125
|
+
kind: 'text'
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
key: 'succeeded',
|
|
129
|
+
label: 'Succeeded',
|
|
130
|
+
kind: 'count'
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
key: 'failed',
|
|
134
|
+
label: 'Failed',
|
|
135
|
+
kind: 'count'
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
key: 'failureRate',
|
|
139
|
+
label: 'Failure rate',
|
|
140
|
+
kind: 'percent'
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
key: 'change',
|
|
144
|
+
label: 'Change in runs',
|
|
145
|
+
kind: 'change'
|
|
146
|
+
}
|
|
147
|
+
],
|
|
148
|
+
rows: [
|
|
149
|
+
{
|
|
150
|
+
automation: 'All automations',
|
|
151
|
+
succeeded,
|
|
152
|
+
failed,
|
|
153
|
+
failureRate: failureRate(totals),
|
|
154
|
+
change: pluginFigureChange(succeeded + failed, before)
|
|
155
|
+
},
|
|
156
|
+
...ranked.slice(0, PLUGIN_FIGURE_MAX_ROWS - 1).map(([automation, counts])=>({
|
|
157
|
+
automation,
|
|
158
|
+
succeeded: counts.succeeded,
|
|
159
|
+
failed: counts.failed,
|
|
160
|
+
failureRate: failureRate(counts),
|
|
161
|
+
change: null
|
|
162
|
+
}))
|
|
163
|
+
],
|
|
164
|
+
omitted: Math.max(0, ranked.length - (PLUGIN_FIGURE_MAX_ROWS - 1)),
|
|
165
|
+
notes: [
|
|
166
|
+
'A run is counted on the day it ran. A run waiting on a later step counts as succeeded so far.',
|
|
167
|
+
...okRuns.truncated || failedRuns.truncated ? [
|
|
168
|
+
`The split by automation counts the most recent ${AUTOMATION_RUN_FIGURES_WINDOW_CEILING.toLocaleString('en-US')} runs of each result; the All automations row counts every run.`
|
|
169
|
+
] : []
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/** Registers the automation runs reader from the console surface, where insight jobs run. */ export function registerAutomationRunFigureReader(firestore) {
|
|
177
|
+
registerPluginFigureReader(automationRunFigureReader(firestore), {
|
|
178
|
+
pluginId: BUNDLE_ID
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
//# sourceMappingURL=automation-run-figures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/server/automation-run-figures.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n PLUGIN_FIGURE_MAX_ROWS,\n pluginFigureChange,\n pluginFigureWindows,\n registerPluginFigureReader,\n type PluginFigureReader,\n} from '@aglyn/aglyn/plugin-manager/plugin-figures'\nimport { BUNDLE_ID } from '../constants/bundle-common'\n\n/**\n * A site's automation runs as a figure table another plugin reads by id\n * (AGL-3603) — the AI plugin's insights answer \"which automations failed?\"\n * from it.\n *\n * Every run an action, a workflow or an organization automation makes is a\n * row in the site's activity log carrying `result` (`succeeded` or `failed`)\n * and `target` — the same rows the run history lists. The totals are COUNT\n * aggregates over `result` in the window (the `activity` composite on\n * `result` + `createdAt`), so they are exact however busy the site is; the\n * per-automation split reads at most `AUTOMATION_RUN_FIGURES_WINDOW_CEILING`\n * runs of each result, projected to `target`, and says so when that read\n * low. A run's event payload names a person and is never read.\n */\n\ntype Firestore = FirebaseFirestore.Firestore\n\n/** Runs of one result one window reads for the per-automation split. */\nexport const AUTOMATION_RUN_FIGURES_WINDOW_CEILING = 500\n\nconst WINDOWS: readonly number[] = [7, 14, 30, 90]\n\ninterface AutomationCounts {\n succeeded: number\n failed: number\n}\n\nfunction runsOf(\n firestore: Firestore,\n hostId: string,\n result: 'succeeded' | 'failed',\n startMs: number,\n endMs: number,\n): FirebaseFirestore.Query {\n return firestore\n .collection('hosts')\n .doc(hostId)\n .collection('activity')\n .where('result', '==', result)\n .where('createdAt', '>=', new Date(startMs))\n .where('createdAt', '<', new Date(endMs))\n}\n\nasync function countOf(query: FirebaseFirestore.Query): Promise<number> {\n const snapshot = await query.count().get()\n return Number(snapshot.data().count) || 0\n}\n\n/** Runs of one result in the window, by the automation they belong to, read to the ceiling. */\nasync function byAutomation(\n query: FirebaseFirestore.Query,\n): Promise<{ names: Map<string, number>; truncated: boolean }> {\n const snapshot = await query\n .orderBy('createdAt', 'desc')\n .select('target')\n .limit(AUTOMATION_RUN_FIGURES_WINDOW_CEILING + 1)\n .get()\n const names = new Map<string, number>()\n for (const doc of snapshot.docs.slice(0, AUTOMATION_RUN_FIGURES_WINDOW_CEILING)) {\n const target = (doc.get('target') ?? {}) as { name?: unknown; id?: unknown }\n const name =\n (typeof target.name === 'string' && target.name.trim()) || 'An automation with no name'\n names.set(name, (names.get(name) ?? 0) + 1)\n }\n return { names, truncated: snapshot.docs.length > AUTOMATION_RUN_FIGURES_WINDOW_CEILING }\n}\n\nconst failureRate = (counts: AutomationCounts): number | null => {\n const total = counts.succeeded + counts.failed\n return total > 0 ? Math.round((counts.failed / total) * 1_000) / 10 : null\n}\n\nexport function automationRunFigureReader(firestore: () => Firestore): PluginFigureReader {\n return {\n id: 'automations.runs',\n label: 'Automation runs',\n description:\n 'Runs of the site’s automations — actions, workflows and organization automations — over the window: how many succeeded and failed, the failure rate, and the change in runs from the window before, in total and by automation.',\n scope: 'site',\n windows: WINDOWS,\n read: async (request) => {\n if (!request.hostId) return { ok: false, status: 400, error: 'Open a site to read its automation runs' }\n if (!WINDOWS.includes(request.days)) {\n return { ok: false, status: 400, error: 'That window is not one automation runs are read over' }\n }\n const db = firestore()\n const hostId = request.hostId\n const { current, previous } = pluginFigureWindows(request.now, request.days)\n const [succeeded, failed, before, okRuns, failedRuns] = await Promise.all([\n countOf(runsOf(db, hostId, 'succeeded', current.startMs, current.endMs)),\n countOf(runsOf(db, hostId, 'failed', current.startMs, current.endMs)),\n Promise.all([\n countOf(runsOf(db, hostId, 'succeeded', previous.startMs, previous.endMs)),\n countOf(runsOf(db, hostId, 'failed', previous.startMs, previous.endMs)),\n ]).then(([a, b]) => a + b),\n byAutomation(runsOf(db, hostId, 'succeeded', current.startMs, current.endMs)),\n byAutomation(runsOf(db, hostId, 'failed', current.startMs, current.endMs)),\n ])\n const automations = new Map<string, AutomationCounts>()\n for (const [name, count] of okRuns.names) {\n automations.set(name, { succeeded: count, failed: automations.get(name)?.failed ?? 0 })\n }\n for (const [name, count] of failedRuns.names) {\n automations.set(name, { succeeded: automations.get(name)?.succeeded ?? 0, failed: count })\n }\n // The most failures first: that is the question a person asks of runs.\n const ranked = [...automations.entries()].sort(\n (a, b) => b[1].failed - a[1].failed || b[1].succeeded - a[1].succeeded || a[0].localeCompare(b[0]),\n )\n const totals = { succeeded, failed }\n return {\n ok: true,\n table: {\n title: 'Automation runs',\n source: { label: 'Automation', path: 'automation' },\n period: { from: current.from, to: current.to, days: request.days },\n columns: [\n { key: 'automation', label: 'Automation', kind: 'text' },\n { key: 'succeeded', label: 'Succeeded', kind: 'count' },\n { key: 'failed', label: 'Failed', kind: 'count' },\n { key: 'failureRate', label: 'Failure rate', kind: 'percent' },\n { key: 'change', label: 'Change in runs', kind: 'change' },\n ],\n rows: [\n {\n automation: 'All automations',\n succeeded,\n failed,\n failureRate: failureRate(totals),\n change: pluginFigureChange(succeeded + failed, before),\n },\n ...ranked.slice(0, PLUGIN_FIGURE_MAX_ROWS - 1).map(([automation, counts]) => ({\n automation,\n succeeded: counts.succeeded,\n failed: counts.failed,\n failureRate: failureRate(counts),\n change: null,\n })),\n ],\n omitted: Math.max(0, ranked.length - (PLUGIN_FIGURE_MAX_ROWS - 1)),\n notes: [\n 'A run is counted on the day it ran. A run waiting on a later step counts as succeeded so far.',\n ...(okRuns.truncated || failedRuns.truncated\n ? [\n `The split by automation counts the most recent ${AUTOMATION_RUN_FIGURES_WINDOW_CEILING.toLocaleString('en-US')} runs of each result; the All automations row counts every run.`,\n ]\n : []),\n ],\n },\n }\n },\n }\n}\n\n/** Registers the automation runs reader from the console surface, where insight jobs run. */\nexport function registerAutomationRunFigureReader(firestore: () => Firestore): void {\n registerPluginFigureReader(automationRunFigureReader(firestore), { pluginId: BUNDLE_ID })\n}\n"],"names":["PLUGIN_FIGURE_MAX_ROWS","pluginFigureChange","pluginFigureWindows","registerPluginFigureReader","BUNDLE_ID","AUTOMATION_RUN_FIGURES_WINDOW_CEILING","WINDOWS","runsOf","firestore","hostId","result","startMs","endMs","collection","doc","where","Date","countOf","query","snapshot","count","get","Number","data","byAutomation","orderBy","select","limit","names","Map","docs","slice","target","name","trim","set","truncated","length","failureRate","counts","total","succeeded","failed","Math","round","automationRunFigureReader","id","label","description","scope","windows","read","request","ok","status","error","includes","days","db","current","previous","now","before","okRuns","failedRuns","Promise","all","then","a","b","automations","ranked","entries","sort","localeCompare","totals","table","title","source","path","period","from","to","columns","key","kind","rows","automation","change","map","omitted","max","notes","toLocaleString","registerAutomationRunFigureReader","pluginId"],"mappings":"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"}
|
|
@@ -14,10 +14,12 @@
|
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/ import { registerPluginApiRoute } from "@aglyn/aglyn/server";
|
|
17
|
+
import { firebaseAdmin } from "@aglyn/tenant-data-admin/server/firebase-admin";
|
|
17
18
|
import { registerWorkflowsServerDeclarations } from "./declarations.server.js";
|
|
18
19
|
import { registerAutomationDraftWriter } from "./server-automation-drafts.js";
|
|
19
20
|
import { ACTION_TEST_RUN_API_ROUTE, actionTestRunHandler } from "./server/action-test-run-route.js";
|
|
20
21
|
import { ORG_AUTOMATION_API_ROUTES, orgAutomationPauseHandler, orgAutomationsManageHandler, orgAutomationsManageSubject } from "./server/org-automations-routes.js";
|
|
22
|
+
import { registerAutomationRunFigureReader } from "./server/automation-run-figures.js";
|
|
21
23
|
/**
|
|
22
24
|
* The workflows plugin's console server surface (AGL-2919).
|
|
23
25
|
*
|
|
@@ -43,6 +45,9 @@ import { ORG_AUTOMATION_API_ROUTES, orgAutomationPauseHandler, orgAutomationsMan
|
|
|
43
45
|
registerPluginApiRoute(ORG_AUTOMATION_API_ROUTES.pause, orgAutomationPauseHandler);
|
|
44
46
|
// So does a test run: a site with Automation switched off has no such door.
|
|
45
47
|
registerPluginApiRoute(ACTION_TEST_RUN_API_ROUTE, actionTestRunHandler);
|
|
48
|
+
// Automation runs as a figure table (AGL-3603), for the AI plugin's
|
|
49
|
+
// insights to read by id; the console runs insight jobs.
|
|
50
|
+
registerAutomationRunFigureReader(()=>firebaseAdmin.app().firestore());
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
//# sourceMappingURL=server-console.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/plugins/workflows/src/lib/server-console.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerPluginApiRoute } from '@aglyn/aglyn/server'\nimport { registerWorkflowsServerDeclarations } from './declarations.server'\nimport { registerAutomationDraftWriter } from './server-automation-drafts'\nimport {\n ACTION_TEST_RUN_API_ROUTE,\n actionTestRunHandler,\n} from './server/action-test-run-route'\nimport {\n ORG_AUTOMATION_API_ROUTES,\n orgAutomationPauseHandler,\n orgAutomationsManageHandler,\n orgAutomationsManageSubject,\n} from './server/org-automations-routes'\n\n/**\n * The workflows plugin's console server surface (AGL-2919).\n *\n * The tenant surface (`registerWorkflowsApi`) serves the inbound webhook a\n * visitor-facing integration calls. This one serves what only the console\n * does: the automation draft writer another plugin reaches through the core's\n * resource-drafts seam, which the AI jobs that write through it — inline at a\n * door and on the beat — find registered in the console process alone\n * (AGL-3026); the doors that write the organization's automations\n * (AGL-3302); and the Actions card's test run (AGL-3309).\n */\nexport function registerWorkflowsConsoleApi(): void {\n // The console raises host events too — a CRM stage moved, a deal won, a\n // task completed — so the engine's listener is registered here as well as\n // at boot (see `declarations.server.ts`).\n registerWorkflowsServerDeclarations()\n registerAutomationDraftWriter()\n // The organization hub names its org and no site, so the route names that\n // org as its subject for the release gate.\n registerPluginApiRoute(\n ORG_AUTOMATION_API_ROUTES.manage,\n orgAutomationsManageHandler,\n { subject: orgAutomationsManageSubject },\n )\n // A site's own pause names the site, and is gated by that site's switch.\n registerPluginApiRoute(ORG_AUTOMATION_API_ROUTES.pause, orgAutomationPauseHandler)\n // So does a test run: a site with Automation switched off has no such door.\n registerPluginApiRoute(ACTION_TEST_RUN_API_ROUTE, actionTestRunHandler)\n}\n"],"names":["registerPluginApiRoute","registerWorkflowsServerDeclarations","registerAutomationDraftWriter","ACTION_TEST_RUN_API_ROUTE","actionTestRunHandler","ORG_AUTOMATION_API_ROUTES","orgAutomationPauseHandler","orgAutomationsManageHandler","orgAutomationsManageSubject","registerWorkflowsConsoleApi","manage","subject","pause"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,sBAAsB,QAAQ,sBAAqB;AAC5D,SAASC,mCAAmC,QAAQ,2BAAuB;AAC3E,SAASC,6BAA6B,QAAQ,gCAA4B;AAC1E,SACEC,yBAAyB,EACzBC,oBAAoB,QACf,oCAAgC;AACvC,SACEC,yBAAyB,EACzBC,yBAAyB,EACzBC,2BAA2B,EAC3BC,2BAA2B,QACtB,qCAAiC;
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/plugins/workflows/src/lib/server-console.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerPluginApiRoute } from '@aglyn/aglyn/server'\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin/server/firebase-admin'\nimport { registerWorkflowsServerDeclarations } from './declarations.server'\nimport { registerAutomationDraftWriter } from './server-automation-drafts'\nimport {\n ACTION_TEST_RUN_API_ROUTE,\n actionTestRunHandler,\n} from './server/action-test-run-route'\nimport {\n ORG_AUTOMATION_API_ROUTES,\n orgAutomationPauseHandler,\n orgAutomationsManageHandler,\n orgAutomationsManageSubject,\n} from './server/org-automations-routes'\nimport { registerAutomationRunFigureReader } from './server/automation-run-figures'\n\n/**\n * The workflows plugin's console server surface (AGL-2919).\n *\n * The tenant surface (`registerWorkflowsApi`) serves the inbound webhook a\n * visitor-facing integration calls. This one serves what only the console\n * does: the automation draft writer another plugin reaches through the core's\n * resource-drafts seam, which the AI jobs that write through it — inline at a\n * door and on the beat — find registered in the console process alone\n * (AGL-3026); the doors that write the organization's automations\n * (AGL-3302); and the Actions card's test run (AGL-3309).\n */\nexport function registerWorkflowsConsoleApi(): void {\n // The console raises host events too — a CRM stage moved, a deal won, a\n // task completed — so the engine's listener is registered here as well as\n // at boot (see `declarations.server.ts`).\n registerWorkflowsServerDeclarations()\n registerAutomationDraftWriter()\n // The organization hub names its org and no site, so the route names that\n // org as its subject for the release gate.\n registerPluginApiRoute(\n ORG_AUTOMATION_API_ROUTES.manage,\n orgAutomationsManageHandler,\n { subject: orgAutomationsManageSubject },\n )\n // A site's own pause names the site, and is gated by that site's switch.\n registerPluginApiRoute(ORG_AUTOMATION_API_ROUTES.pause, orgAutomationPauseHandler)\n // So does a test run: a site with Automation switched off has no such door.\n registerPluginApiRoute(ACTION_TEST_RUN_API_ROUTE, actionTestRunHandler)\n // Automation runs as a figure table (AGL-3603), for the AI plugin's\n // insights to read by id; the console runs insight jobs.\n registerAutomationRunFigureReader(() => firebaseAdmin.app().firestore())\n}\n"],"names":["registerPluginApiRoute","firebaseAdmin","registerWorkflowsServerDeclarations","registerAutomationDraftWriter","ACTION_TEST_RUN_API_ROUTE","actionTestRunHandler","ORG_AUTOMATION_API_ROUTES","orgAutomationPauseHandler","orgAutomationsManageHandler","orgAutomationsManageSubject","registerAutomationRunFigureReader","registerWorkflowsConsoleApi","manage","subject","pause","app","firestore"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,sBAAsB,QAAQ,sBAAqB;AAC5D,SAASC,aAAa,QAAQ,iDAAgD;AAC9E,SAASC,mCAAmC,QAAQ,2BAAuB;AAC3E,SAASC,6BAA6B,QAAQ,gCAA4B;AAC1E,SACEC,yBAAyB,EACzBC,oBAAoB,QACf,oCAAgC;AACvC,SACEC,yBAAyB,EACzBC,yBAAyB,EACzBC,2BAA2B,EAC3BC,2BAA2B,QACtB,qCAAiC;AACxC,SAASC,iCAAiC,QAAQ,qCAAiC;AAEnF;;;;;;;;;;CAUC,GACD,OAAO,SAASC;IACd,wEAAwE;IACxE,0EAA0E;IAC1E,0CAA0C;IAC1CT;IACAC;IACA,0EAA0E;IAC1E,2CAA2C;IAC3CH,uBACEM,0BAA0BM,MAAM,EAChCJ,6BACA;QAAEK,SAASJ;IAA4B;IAEzC,yEAAyE;IACzET,uBAAuBM,0BAA0BQ,KAAK,EAAEP;IACxD,4EAA4E;IAC5EP,uBAAuBI,2BAA2BC;IAClD,oEAAoE;IACpE,yDAAyD;IACzDK,kCAAkC,IAAMT,cAAcc,GAAG,GAAGC,SAAS;AACvE"}
|