@objectstack/plugin-approvals 17.0.0-rc.0 → 17.0.0-rc.1
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/CHANGELOG.md +439 -0
- package/dist/index.d.mts +2304 -3491
- package/dist/index.d.ts +2304 -3491
- package/dist/index.js +116 -43
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +114 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -9
- package/.turbo/turbo-build.log +0 -22
- package/scripts/i18n-extract.config.ts +0 -38
- package/src/action-link-pages.ts +0 -102
- package/src/approval-actor-impersonation.test.ts +0 -330
- package/src/approval-node.test.ts +0 -356
- package/src/approval-node.ts +0 -196
- package/src/approval-revise.test.ts +0 -418
- package/src/approval-service.test.ts +0 -2858
- package/src/approval-service.ts +0 -3617
- package/src/approvals-plugin.ts +0 -294
- package/src/approver-cross-org.integration.test.ts +0 -206
- package/src/approver-org-scope.test.ts +0 -201
- package/src/approver-org-scope.ts +0 -261
- package/src/index.ts +0 -42
- package/src/lifecycle-hooks.ts +0 -201
- package/src/nav-contribution.test.ts +0 -50
- package/src/record-lock-schedule-run.integration.test.ts +0 -206
- package/src/status-mirror-cascade.integration.test.ts +0 -224
- package/src/sys-approval-action.object.ts +0 -149
- package/src/sys-approval-approver.object.ts +0 -85
- package/src/sys-approval-delegation.object.test.ts +0 -42
- package/src/sys-approval-delegation.object.ts +0 -142
- package/src/sys-approval-request.object.test.ts +0 -116
- package/src/sys-approval-request.object.ts +0 -413
- package/src/sys-approval-token.object.ts +0 -101
- package/src/translations/bundle-ownership.test.ts +0 -48
- package/src/translations/en.objects.generated.ts +0 -311
- package/src/translations/es-ES.objects.generated.ts +0 -311
- package/src/translations/index.ts +0 -23
- package/src/translations/ja-JP.objects.generated.ts +0 -311
- package/src/translations/zh-CN.objects.generated.ts +0 -311
- package/tsconfig.json +0 -10
package/dist/index.js
CHANGED
|
@@ -257,6 +257,14 @@ var init_en_objects_generated = __esm({
|
|
|
257
257
|
comment: {
|
|
258
258
|
label: "Comment"
|
|
259
259
|
},
|
|
260
|
+
reassign_from: {
|
|
261
|
+
label: "Reassigned From",
|
|
262
|
+
help: "User whose pending-approver slot was handed over (reassign actions only)"
|
|
263
|
+
},
|
|
264
|
+
reassign_to: {
|
|
265
|
+
label: "Reassigned To",
|
|
266
|
+
help: "User who received the pending-approver slot (reassign actions only)"
|
|
267
|
+
},
|
|
260
268
|
attachments: {
|
|
261
269
|
label: "Attachments",
|
|
262
270
|
help: "Files supporting this action \u2014 e.g. a signed contract or evidence (#3266)."
|
|
@@ -566,6 +574,14 @@ var init_zh_CN_objects_generated = __esm({
|
|
|
566
574
|
comment: {
|
|
567
575
|
label: "\u8BC4\u8BBA"
|
|
568
576
|
},
|
|
577
|
+
reassign_from: {
|
|
578
|
+
label: "\u8F6C\u51FA\u4EBA",
|
|
579
|
+
help: "\u88AB\u79FB\u4EA4\u5F85\u5BA1\u6279\u69FD\u4F4D\u7684\u7528\u6237\uFF08\u4EC5\u8F6C\u7B7E\u64CD\u4F5C\uFF09"
|
|
580
|
+
},
|
|
581
|
+
reassign_to: {
|
|
582
|
+
label: "\u8F6C\u5165\u4EBA",
|
|
583
|
+
help: "\u63A5\u6536\u5F85\u5BA1\u6279\u69FD\u4F4D\u7684\u7528\u6237\uFF08\u4EC5\u8F6C\u7B7E\u64CD\u4F5C\uFF09"
|
|
584
|
+
},
|
|
569
585
|
attachments: {
|
|
570
586
|
label: "\u9644\u4EF6",
|
|
571
587
|
help: "\u652F\u6301\u8BE5\u64CD\u4F5C\u7684\u6587\u4EF6\u2014\u2014\u4F8B\u5982\u5DF2\u7B7E\u7F72\u7684\u5408\u540C\u6216\u8BC1\u660E\u6750\u6599\uFF08#3266\uFF09\u3002"
|
|
@@ -875,6 +891,14 @@ var init_ja_JP_objects_generated = __esm({
|
|
|
875
891
|
comment: {
|
|
876
892
|
label: "\u30B3\u30E1\u30F3\u30C8"
|
|
877
893
|
},
|
|
894
|
+
reassign_from: {
|
|
895
|
+
label: "\u5F15\u304D\u7D99\u304E\u5143",
|
|
896
|
+
help: "\u627F\u8A8D\u5F85\u3061\u30B9\u30ED\u30C3\u30C8\u3092\u5F15\u304D\u6E21\u3057\u305F\u30E6\u30FC\u30B6\u30FC\uFF08\u5F15\u304D\u7D99\u304E\u64CD\u4F5C\u306E\u307F\uFF09"
|
|
897
|
+
},
|
|
898
|
+
reassign_to: {
|
|
899
|
+
label: "\u5F15\u304D\u7D99\u304E\u5148",
|
|
900
|
+
help: "\u627F\u8A8D\u5F85\u3061\u30B9\u30ED\u30C3\u30C8\u3092\u53D7\u3051\u53D6\u3063\u305F\u30E6\u30FC\u30B6\u30FC\uFF08\u5F15\u304D\u7D99\u304E\u64CD\u4F5C\u306E\u307F\uFF09"
|
|
901
|
+
},
|
|
878
902
|
attachments: {
|
|
879
903
|
label: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB",
|
|
880
904
|
help: "\u3053\u306E\u64CD\u4F5C\u3092\u88CF\u4ED8\u3051\u308B\u30D5\u30A1\u30A4\u30EB\u2014\u2014\u7F72\u540D\u6E08\u307F\u5951\u7D04\u66F8\u3084\u8A3C\u6191\u306A\u3069\uFF08#3266\uFF09\u3002"
|
|
@@ -1184,6 +1208,14 @@ var init_es_ES_objects_generated = __esm({
|
|
|
1184
1208
|
comment: {
|
|
1185
1209
|
label: "Comentario"
|
|
1186
1210
|
},
|
|
1211
|
+
reassign_from: {
|
|
1212
|
+
label: "Reasignado de",
|
|
1213
|
+
help: "Usuario cuyo turno de aprobaci\xF3n pendiente fue traspasado (solo acciones de reasignaci\xF3n)"
|
|
1214
|
+
},
|
|
1215
|
+
reassign_to: {
|
|
1216
|
+
label: "Reasignado a",
|
|
1217
|
+
help: "Usuario que recibi\xF3 el turno de aprobaci\xF3n pendiente (solo acciones de reasignaci\xF3n)"
|
|
1218
|
+
},
|
|
1187
1219
|
attachments: {
|
|
1188
1220
|
label: "Adjuntos",
|
|
1189
1221
|
help: "Archivos que respaldan esta acci\xF3n, p. ej. un contrato firmado o pruebas (#3266)."
|
|
@@ -1298,6 +1330,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
1298
1330
|
|
|
1299
1331
|
// src/sys-approval-request.object.ts
|
|
1300
1332
|
var import_data = require("@objectstack/spec/data");
|
|
1333
|
+
var import_contracts = require("@objectstack/spec/contracts");
|
|
1301
1334
|
var SysApprovalRequest = import_data.ObjectSchema.create({
|
|
1302
1335
|
name: "sys_approval_request",
|
|
1303
1336
|
label: "Approval Request",
|
|
@@ -1396,9 +1429,10 @@ var SysApprovalRequest = import_data.ObjectSchema.create({
|
|
|
1396
1429
|
group: "Target"
|
|
1397
1430
|
}),
|
|
1398
1431
|
status: import_data.Field.select(
|
|
1399
|
-
//
|
|
1400
|
-
//
|
|
1401
|
-
|
|
1432
|
+
// Spread from the contract, not re-typed (#3786). `APPROVAL_STATUSES` is
|
|
1433
|
+
// where the list and the reason for each entry live; `ApprovalStatus` is
|
|
1434
|
+
// derived from it, so this column and the contract cannot disagree.
|
|
1435
|
+
[...import_contracts.APPROVAL_STATUSES],
|
|
1402
1436
|
{
|
|
1403
1437
|
label: "Status",
|
|
1404
1438
|
required: true,
|
|
@@ -1667,6 +1701,7 @@ var SysApprovalRequest = import_data.ObjectSchema.create({
|
|
|
1667
1701
|
|
|
1668
1702
|
// src/sys-approval-action.object.ts
|
|
1669
1703
|
var import_data2 = require("@objectstack/spec/data");
|
|
1704
|
+
var import_contracts2 = require("@objectstack/spec/contracts");
|
|
1670
1705
|
var SysApprovalAction = import_data2.ObjectSchema.create({
|
|
1671
1706
|
name: "sys_approval_action",
|
|
1672
1707
|
label: "Approval Action",
|
|
@@ -1745,12 +1780,11 @@ var SysApprovalAction = import_data2.ObjectSchema.create({
|
|
|
1745
1780
|
group: "Target"
|
|
1746
1781
|
}),
|
|
1747
1782
|
action: import_data2.Field.select(
|
|
1748
|
-
//
|
|
1749
|
-
//
|
|
1750
|
-
//
|
|
1751
|
-
//
|
|
1752
|
-
|
|
1753
|
-
["submit", "approve", "reject", "recall", "escalate", "reassign", "remind", "request_info", "comment", "revise", "resubmit", "ooo_substitute"],
|
|
1783
|
+
// Spread from the contract, not re-typed (#3786). `APPROVAL_ACTION_KINDS`
|
|
1784
|
+
// is where the list and the per-kind notes live (which kinds move the flow
|
|
1785
|
+
// and which are thread-only); `ApprovalActionKind` is derived from it, so
|
|
1786
|
+
// this column and the contract cannot disagree.
|
|
1787
|
+
[...import_contracts2.APPROVAL_ACTION_KINDS],
|
|
1754
1788
|
{
|
|
1755
1789
|
label: "Action",
|
|
1756
1790
|
required: true,
|
|
@@ -1763,6 +1797,23 @@ var SysApprovalAction = import_data2.ObjectSchema.create({
|
|
|
1763
1797
|
group: "Action"
|
|
1764
1798
|
}),
|
|
1765
1799
|
comment: import_data2.Field.textarea({ label: "Comment", required: false, group: "Action" }),
|
|
1800
|
+
// Structured hand-off parties for `action: 'reassign'` (#4365). Before
|
|
1801
|
+
// these existed the pair lived only inside a default free-text comment
|
|
1802
|
+
// ("<from_id> → <to_id>"), which no client could parse or render readably.
|
|
1803
|
+
// `comment` is pure user input again; timelines render "from A to B" from
|
|
1804
|
+
// these fields.
|
|
1805
|
+
reassign_from: import_data2.Field.lookup("sys_user", {
|
|
1806
|
+
label: "Reassigned From",
|
|
1807
|
+
required: false,
|
|
1808
|
+
group: "Action",
|
|
1809
|
+
description: "User whose pending-approver slot was handed over (reassign actions only)"
|
|
1810
|
+
}),
|
|
1811
|
+
reassign_to: import_data2.Field.lookup("sys_user", {
|
|
1812
|
+
label: "Reassigned To",
|
|
1813
|
+
required: false,
|
|
1814
|
+
group: "Action",
|
|
1815
|
+
description: "User who received the pending-approver slot (reassign actions only)"
|
|
1816
|
+
}),
|
|
1766
1817
|
attachments: import_data2.Field.file({
|
|
1767
1818
|
label: "Attachments",
|
|
1768
1819
|
required: false,
|
|
@@ -1949,8 +2000,9 @@ var SysApprovalDelegation = import_data4.ObjectSchema.create({
|
|
|
1949
2000
|
var import_node_crypto = require("crypto");
|
|
1950
2001
|
var import_automation = require("@objectstack/spec/automation");
|
|
1951
2002
|
var import_formula = require("@objectstack/formula");
|
|
2003
|
+
var import_types = require("@objectstack/types");
|
|
1952
2004
|
var import_identity = require("@objectstack/spec/identity");
|
|
1953
|
-
var
|
|
2005
|
+
var import_contracts3 = require("@objectstack/spec/contracts");
|
|
1954
2006
|
var import_data5 = require("@objectstack/spec/data");
|
|
1955
2007
|
var import_core = require("@objectstack/core");
|
|
1956
2008
|
|
|
@@ -1963,7 +2015,7 @@ function fail(message) {
|
|
|
1963
2015
|
async function findOrg(engine, where) {
|
|
1964
2016
|
try {
|
|
1965
2017
|
const rows = await engine.find("sys_organization", {
|
|
1966
|
-
|
|
2018
|
+
where,
|
|
1967
2019
|
fields: ["id", "slug", "parent_organization_id"],
|
|
1968
2020
|
limit: 1,
|
|
1969
2021
|
context: SYSTEM_CTX
|
|
@@ -2050,7 +2102,7 @@ async function filterApproversWhoCanRead(deps, userIds, requestOrgId, context) {
|
|
|
2050
2102
|
let members = [];
|
|
2051
2103
|
try {
|
|
2052
2104
|
members = await deps.engine.find("sys_member", {
|
|
2053
|
-
|
|
2105
|
+
where: { organization_id: requestOrg, user_id: { $in: userIds } },
|
|
2054
2106
|
fields: ["user_id"],
|
|
2055
2107
|
limit: 1e4,
|
|
2056
2108
|
context: SYSTEM_CTX
|
|
@@ -2120,6 +2172,12 @@ function csvSplit(raw) {
|
|
|
2120
2172
|
if (Array.isArray(raw)) return raw.map(String).filter(Boolean);
|
|
2121
2173
|
return String(raw).split(",").map((s) => s.trim()).filter(Boolean);
|
|
2122
2174
|
}
|
|
2175
|
+
function isBlankDecisionOutput(value) {
|
|
2176
|
+
if (value === void 0 || value === null) return true;
|
|
2177
|
+
if (typeof value === "string") return value.trim() === "";
|
|
2178
|
+
if (Array.isArray(value)) return value.filter((v) => v !== null && v !== void 0 && String(v).trim() !== "").length === 0;
|
|
2179
|
+
return false;
|
|
2180
|
+
}
|
|
2123
2181
|
function prettifyMachineName(raw) {
|
|
2124
2182
|
if (!raw) return void 0;
|
|
2125
2183
|
const base = String(raw).replace(/^flow:/, "").trim();
|
|
@@ -2212,6 +2270,9 @@ function rowFromAction(row) {
|
|
|
2212
2270
|
action: row.action,
|
|
2213
2271
|
actor_id: row.actor_id ?? void 0,
|
|
2214
2272
|
comment: row.comment ?? void 0,
|
|
2273
|
+
// Structured reassign hand-off parties (#4365).
|
|
2274
|
+
reassign_from: row.reassign_from ?? void 0,
|
|
2275
|
+
reassign_to: row.reassign_to ?? void 0,
|
|
2215
2276
|
// Decision attachments (#3266): rich descriptors carrying the display name +
|
|
2216
2277
|
// download URL, so consumers label/open them without reading `sys_file`.
|
|
2217
2278
|
attachments: attachments.length ? attachments : void 0,
|
|
@@ -2351,9 +2412,10 @@ var _ApprovalService = class _ApprovalService {
|
|
|
2351
2412
|
* (having also put them on the context). Those are the only two callers that
|
|
2352
2413
|
* hold a trustworthy actor with no session behind them.
|
|
2353
2414
|
*
|
|
2354
|
-
* A caller with NO identity at all cannot act.
|
|
2355
|
-
*
|
|
2356
|
-
*
|
|
2415
|
+
* A caller with NO identity at all cannot act. Belt-and-suspenders: the REST
|
|
2416
|
+
* anonymous-deny now denies every anonymous request (#3963), but this service
|
|
2417
|
+
* must not rely on a caller upstream — an anonymous actor could otherwise
|
|
2418
|
+
* decide approvals outright by naming one.
|
|
2357
2419
|
*/
|
|
2358
2420
|
async resolveActor(actorId, context) {
|
|
2359
2421
|
if (context?.isSystem) {
|
|
@@ -2639,7 +2701,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
2639
2701
|
let rows = [];
|
|
2640
2702
|
try {
|
|
2641
2703
|
rows = await this.engine.find("sys_team_member", {
|
|
2642
|
-
|
|
2704
|
+
where: { team_id: teamId },
|
|
2643
2705
|
fields: ["user_id"],
|
|
2644
2706
|
limit: 1e4,
|
|
2645
2707
|
context: SYSTEM_CTX2
|
|
@@ -2678,7 +2740,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
2678
2740
|
if (!businessUnitId) return [];
|
|
2679
2741
|
try {
|
|
2680
2742
|
const seed = await this.engine.find("sys_business_unit", {
|
|
2681
|
-
|
|
2743
|
+
where: this.businessUnitOrgScope({ id: businessUnitId }, organizationId),
|
|
2682
2744
|
fields: ["id", "active"],
|
|
2683
2745
|
limit: 1,
|
|
2684
2746
|
context: SYSTEM_CTX2
|
|
@@ -2713,7 +2775,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
2713
2775
|
let rows = [];
|
|
2714
2776
|
try {
|
|
2715
2777
|
rows = await this.engine.find("sys_business_unit_member", {
|
|
2716
|
-
|
|
2778
|
+
where: { business_unit_id: { $in: Array.from(seen) } },
|
|
2717
2779
|
fields: ["user_id"],
|
|
2718
2780
|
limit: 1e4,
|
|
2719
2781
|
context: SYSTEM_CTX2
|
|
@@ -2773,7 +2835,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
2773
2835
|
async lookupManager(userId) {
|
|
2774
2836
|
try {
|
|
2775
2837
|
const rows = await this.engine.find("sys_user", {
|
|
2776
|
-
|
|
2838
|
+
where: { id: userId },
|
|
2777
2839
|
fields: ["id", "manager_id"],
|
|
2778
2840
|
limit: 1,
|
|
2779
2841
|
context: SYSTEM_CTX2
|
|
@@ -2823,7 +2885,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
2823
2885
|
let rows = [];
|
|
2824
2886
|
try {
|
|
2825
2887
|
rows = await this.engine.find("sys_approval_delegation", {
|
|
2826
|
-
|
|
2888
|
+
where: { delegator_id: delegatorId },
|
|
2827
2889
|
fields: ["id", "delegator_id", "delegate_id", "valid_from", "valid_until", "reason", "organization_id"],
|
|
2828
2890
|
limit: 50,
|
|
2829
2891
|
context: SYSTEM_CTX2
|
|
@@ -3149,8 +3211,9 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3149
3211
|
const now = this.clock.now().toISOString();
|
|
3150
3212
|
const outputKeys = input.outputs ? Object.keys(input.outputs) : [];
|
|
3151
3213
|
let acceptedOutputs;
|
|
3214
|
+
const declaredDefs = (0, import_automation.normalizeDecisionOutputs)(config.decisionOutputs);
|
|
3152
3215
|
if (outputKeys.length) {
|
|
3153
|
-
const declared =
|
|
3216
|
+
const declared = declaredDefs.map((d) => d.key);
|
|
3154
3217
|
if (!declared.length) {
|
|
3155
3218
|
throw new Error(
|
|
3156
3219
|
`VALIDATION_FAILED: this approval node declares no decisionOutputs \u2014 outputs are not accepted. Declare the keys on the node config (decisionOutputs: [${outputKeys.map((k) => `'${k}'`).join(", ")}]) to let approvers hand them to the flow.`
|
|
@@ -3170,6 +3233,14 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3170
3233
|
}
|
|
3171
3234
|
acceptedOutputs = { ...input.outputs };
|
|
3172
3235
|
}
|
|
3236
|
+
if (input.decision === "approve") {
|
|
3237
|
+
const missing = declaredDefs.filter((d) => d.required === true && isBlankDecisionOutput(input.outputs?.[d.key])).map((d) => d.key);
|
|
3238
|
+
if (missing.length) {
|
|
3239
|
+
throw new Error(
|
|
3240
|
+
`VALIDATION_FAILED: decision output(s) \`${missing.join("`, `")}\` are required to approve this request \u2014 open the approval and fill them in before approving.`
|
|
3241
|
+
);
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3173
3244
|
await this.engine.insert("sys_approval_action", {
|
|
3174
3245
|
id: uid("aact"),
|
|
3175
3246
|
request_id: requestId,
|
|
@@ -3267,7 +3338,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3267
3338
|
* try/catch, because what a failed resume means differs per path.
|
|
3268
3339
|
*/
|
|
3269
3340
|
async serviceResume(runId, signal) {
|
|
3270
|
-
await this.automation.resume(runId, { ...signal, [
|
|
3341
|
+
await this.automation.resume(runId, { ...signal, [import_contracts3.RESUME_AUTHORITY_SERVICE]: true });
|
|
3271
3342
|
}
|
|
3272
3343
|
/**
|
|
3273
3344
|
* Public contract entrypoint (ADR-0019). Records a decision on a node-driven
|
|
@@ -3704,8 +3775,13 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3704
3775
|
step_name: raw.flow_node_id ?? raw.current_step ?? null,
|
|
3705
3776
|
step_index: 0,
|
|
3706
3777
|
action: "reassign",
|
|
3778
|
+
// The hand-off parties are STRUCTURED fields (#4365) — the old default
|
|
3779
|
+
// comment (`"<from> → <to>"`) baked raw user ids into user-facing text.
|
|
3780
|
+
// `comment` is pure user input: absent unless the actor wrote one.
|
|
3707
3781
|
actor_id: actorId,
|
|
3708
|
-
|
|
3782
|
+
reassign_from: from,
|
|
3783
|
+
reassign_to: to,
|
|
3784
|
+
comment: input.comment ?? null,
|
|
3709
3785
|
created_at: now
|
|
3710
3786
|
}, { context: SYSTEM_CTX2 });
|
|
3711
3787
|
let configPatch = {};
|
|
@@ -4513,35 +4589,28 @@ var _ApprovalService = class _ApprovalService {
|
|
|
4513
4589
|
async rebuildApproverIndex() {
|
|
4514
4590
|
const desired = /* @__PURE__ */ new Map();
|
|
4515
4591
|
const PAGE = 500;
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4592
|
+
const requests = (0, import_types.keysetWalk)(
|
|
4593
|
+
(q) => this.engine.find("sys_approval_request", {
|
|
4594
|
+
...q,
|
|
4519
4595
|
fields: ["id", "pending_approvers", "organization_id"],
|
|
4520
|
-
limit: PAGE,
|
|
4521
|
-
offset,
|
|
4522
4596
|
context: SYSTEM_CTX2
|
|
4523
|
-
})
|
|
4524
|
-
|
|
4597
|
+
}),
|
|
4598
|
+
{ where: { status: "pending" }, pageSize: PAGE }
|
|
4599
|
+
);
|
|
4600
|
+
for await (const rows of requests.pages()) {
|
|
4525
4601
|
for (const r of rows) {
|
|
4526
4602
|
desired.set(String(r.id), {
|
|
4527
4603
|
approvers: new Set(csvSplit(r.pending_approvers)),
|
|
4528
4604
|
org: r.organization_id ?? null
|
|
4529
4605
|
});
|
|
4530
4606
|
}
|
|
4531
|
-
if (rows.length < PAGE) break;
|
|
4532
4607
|
}
|
|
4533
4608
|
const indexRows = [];
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
context: SYSTEM_CTX2
|
|
4540
|
-
});
|
|
4541
|
-
const rows = Array.isArray(batch) ? batch : [];
|
|
4542
|
-
indexRows.push(...rows);
|
|
4543
|
-
if (rows.length < PAGE) break;
|
|
4544
|
-
}
|
|
4609
|
+
const index = (0, import_types.keysetWalk)(
|
|
4610
|
+
(q) => this.engine.find("sys_approval_approver", { ...q, context: SYSTEM_CTX2 }),
|
|
4611
|
+
{ pageSize: PAGE }
|
|
4612
|
+
);
|
|
4613
|
+
for await (const rows of index.pages()) indexRows.push(...rows);
|
|
4545
4614
|
let inserted = 0;
|
|
4546
4615
|
let deleted = 0;
|
|
4547
4616
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -4925,11 +4994,15 @@ var _ApprovalService = class _ApprovalService {
|
|
|
4925
4994
|
});
|
|
4926
4995
|
const actions = Array.isArray(rows) ? rows.map(rowFromAction) : [];
|
|
4927
4996
|
const names = await this.resolveUserNames(
|
|
4928
|
-
actions.
|
|
4997
|
+
actions.flatMap((a) => [a.actor_id, a.reassign_from, a.reassign_to]).filter((id) => id && !id.includes(":"))
|
|
4929
4998
|
);
|
|
4930
4999
|
for (const a of actions) {
|
|
4931
5000
|
const n = a.actor_id ? names.get(String(a.actor_id)) : void 0;
|
|
4932
5001
|
if (n) a.actor_name = n;
|
|
5002
|
+
const fromName = a.reassign_from ? names.get(String(a.reassign_from)) : void 0;
|
|
5003
|
+
if (fromName) a.reassign_from_name = fromName;
|
|
5004
|
+
const toName = a.reassign_to ? names.get(String(a.reassign_to)) : void 0;
|
|
5005
|
+
if (toName) a.reassign_to_name = toName;
|
|
4933
5006
|
}
|
|
4934
5007
|
return actions;
|
|
4935
5008
|
}
|