@objectstack/plugin-approvals 9.11.0 → 10.2.0
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +75 -0
- package/dist/index.d.mts +702 -10
- package/dist/index.d.ts +702 -10
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +15 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
- package/src/approval-service.ts +16 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/plugin-approvals",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.2.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Multi-step approval engine for ObjectStack — sys_approval_process + sys_approval_request + sys_approval_action + IApprovalService.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -13,17 +13,17 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@objectstack/core": "
|
|
17
|
-
"@objectstack/formula": "
|
|
18
|
-
"@objectstack/metadata-core": "
|
|
19
|
-
"@objectstack/platform-objects": "
|
|
20
|
-
"@objectstack/spec": "
|
|
16
|
+
"@objectstack/core": "10.2.0",
|
|
17
|
+
"@objectstack/formula": "10.2.0",
|
|
18
|
+
"@objectstack/metadata-core": "10.2.0",
|
|
19
|
+
"@objectstack/platform-objects": "10.2.0",
|
|
20
|
+
"@objectstack/spec": "10.2.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@types/node": "^
|
|
23
|
+
"@types/node": "^26.0.0",
|
|
24
24
|
"typescript": "^6.0.3",
|
|
25
25
|
"vitest": "^4.1.9",
|
|
26
|
-
"@objectstack/service-automation": "
|
|
26
|
+
"@objectstack/service-automation": "10.2.0"
|
|
27
27
|
},
|
|
28
28
|
"keywords": [
|
|
29
29
|
"objectstack",
|
package/src/approval-service.ts
CHANGED
|
@@ -281,8 +281,8 @@ export class ApprovalService implements IApprovalService {
|
|
|
281
281
|
*
|
|
282
282
|
* **Graph semantics:**
|
|
283
283
|
* - `team` → flat members of `sys_team` (better-auth; no BFS)
|
|
284
|
-
* - `department` → recursive BFS of `
|
|
285
|
-
* → members of every descendant via `
|
|
284
|
+
* - `department` → recursive BFS of `sys_business_unit.parent_business_unit_id`
|
|
285
|
+
* → members of every descendant via `sys_business_unit_member`
|
|
286
286
|
* - `role` → users with `sys_member.role = value` in tenant
|
|
287
287
|
* - `manager` → `sys_user.manager_id` of `record[value] ?? record.owner_id`
|
|
288
288
|
* - `field` → literal user id stored in `record[value]`
|
|
@@ -299,8 +299,8 @@ export class ApprovalService implements IApprovalService {
|
|
|
299
299
|
if (a.type === 'team') {
|
|
300
300
|
const users = await this.expandTeamUsers(String(a.value));
|
|
301
301
|
if (users.length) { for (const u of users) out.push(u); continue; }
|
|
302
|
-
} else if (a.type === '
|
|
303
|
-
const users = await this.
|
|
302
|
+
} else if (a.type === 'business_unit' || a.type === 'bu') {
|
|
303
|
+
const users = await this.expandBusinessUnitUsers(String(a.value), organizationId);
|
|
304
304
|
if (users.length) { for (const u of users) out.push(u); continue; }
|
|
305
305
|
} else if (a.type === 'role') {
|
|
306
306
|
const users = await this.expandRoleUsers(String(a.value), organizationId);
|
|
@@ -333,15 +333,15 @@ export class ApprovalService implements IApprovalService {
|
|
|
333
333
|
return Array.from(new Set((rows ?? []).map((r: any) => String(r.user_id ?? '')).filter(Boolean)));
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
-
/** Recursive department — walks `
|
|
337
|
-
private async
|
|
338
|
-
if (!
|
|
336
|
+
/** Recursive department — walks `sys_business_unit.parent_business_unit_id`. */
|
|
337
|
+
private async expandBusinessUnitUsers(businessUnitId: string, organizationId?: string | null): Promise<string[]> {
|
|
338
|
+
if (!businessUnitId) return [];
|
|
339
339
|
// Seed sanity check: skip if dept doesn't exist or is inactive within tenant.
|
|
340
340
|
try {
|
|
341
|
-
const seed = await this.engine.find('
|
|
341
|
+
const seed = await this.engine.find('sys_business_unit', {
|
|
342
342
|
filter: organizationId
|
|
343
|
-
? { id:
|
|
344
|
-
: { id:
|
|
343
|
+
? { id: businessUnitId, organization_id: organizationId }
|
|
344
|
+
: { id: businessUnitId },
|
|
345
345
|
fields: ['id', 'active'],
|
|
346
346
|
limit: 1,
|
|
347
347
|
context: SYSTEM_CTX,
|
|
@@ -350,15 +350,15 @@ export class ApprovalService implements IApprovalService {
|
|
|
350
350
|
if (!seedRow || seedRow.active === false) return [];
|
|
351
351
|
} catch { return []; }
|
|
352
352
|
|
|
353
|
-
const seen = new Set<string>([
|
|
354
|
-
const queue: string[] = [
|
|
353
|
+
const seen = new Set<string>([businessUnitId]);
|
|
354
|
+
const queue: string[] = [businessUnitId];
|
|
355
355
|
while (queue.length) {
|
|
356
356
|
const parent = queue.shift()!;
|
|
357
357
|
let kids: any[] = [];
|
|
358
358
|
try {
|
|
359
|
-
const filter: any = {
|
|
359
|
+
const filter: any = { parent_business_unit_id: parent, active: { $ne: false } };
|
|
360
360
|
if (organizationId) filter.organization_id = organizationId;
|
|
361
|
-
kids = await this.engine.find('
|
|
361
|
+
kids = await this.engine.find('sys_business_unit', { filter, fields: ['id'], limit: 1000, context: SYSTEM_CTX } as any);
|
|
362
362
|
} catch { kids = []; }
|
|
363
363
|
for (const k of kids ?? []) {
|
|
364
364
|
const kid = String((k as any).id ?? '');
|
|
@@ -367,8 +367,8 @@ export class ApprovalService implements IApprovalService {
|
|
|
367
367
|
}
|
|
368
368
|
let rows: any[] = [];
|
|
369
369
|
try {
|
|
370
|
-
rows = await this.engine.find('
|
|
371
|
-
filter: {
|
|
370
|
+
rows = await this.engine.find('sys_business_unit_member', {
|
|
371
|
+
filter: { business_unit_id: { $in: Array.from(seen) } },
|
|
372
372
|
fields: ['user_id'],
|
|
373
373
|
limit: 10000,
|
|
374
374
|
context: SYSTEM_CTX,
|