@rytass/bpm-core-nestjs-module 0.1.7 → 0.1.8

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +24 -8
  3. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -9,6 +9,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
  Releases are managed by [`nx release`](https://nx.dev/recipes/nx-release) with
10
10
  Conventional Commits — see `nx.json` for the release config.
11
11
 
12
+ ## 0.1.8 — 2026-05-28
13
+
14
+ ### Documentation
15
+
16
+ - **Casbin example BPMAuthContext shape corrected.** The 0.1.6/0.1.7
17
+ example returned `{ memberId, email, name, roles, permissions,
18
+ metadata }` — the actual `BPMAuthContext` interface is
19
+ `{ memberId, roles, permissions, metadata }` (no `email`, no `name`).
20
+ Example now stashes display data inside `metadata`, with an explicit
21
+ callout that name/email reach resolvers through `BPMMemberResolver`
22
+ instead.
23
+ - **`createPosition` / `updatePosition` / `createMembership` /
24
+ `updateMembership` / `createManagerResolution` exact signatures
25
+ added** to the org Worked Example section. The 0.1.7 README only
26
+ listed function names; downstream developers were guessing input
27
+ shapes (e.g. mandatory `level` and `metadataJson` on positions).
28
+ - **`metadataJson` write-only clarification.** The "host-FK stash"
29
+ rule was misleading: `metadataJson` is accepted by every mutation
30
+ but the records returned by `readOrganizationDashboard` do NOT
31
+ surface a `metadata` field. Updated to "always reconcile by `code`;
32
+ treat `metadataJson` as audit/debugging breadcrumb, not a live FK
33
+ pointer."
34
+
35
+ ### Why a patch
36
+
37
+ Documentation only. No source change.
38
+
12
39
  ## 0.1.7 — 2026-05-28
13
40
 
14
41
  ### Documentation
package/README.md CHANGED
@@ -353,16 +353,23 @@ export class BPMAuthContextFactory {
353
353
 
354
354
  return {
355
355
  memberId: member.id,
356
- email: member.email,
357
- name: member.name,
358
356
  roles: bpmRoles,
359
357
  permissions: [], // Host can also use `bpm:*` style permissions if preferred.
360
- metadata: {},
358
+ // The BPMAuthContext shape does NOT include name/email — those are
359
+ // surfaced through BPMMemberResolver instead. If you want them
360
+ // available to downstream resolvers without an extra resolver call,
361
+ // stash them in `metadata` (BPM passes it through unchanged).
362
+ metadata: { name: member.name, email: member.email },
361
363
  };
362
364
  }
363
365
  }
364
366
  ```
365
367
 
368
+ > **`BPMAuthContext` shape**: `{ memberId, roles, permissions, metadata }`
369
+ > — exactly four fields. The host's `name` / `email` are not part of the
370
+ > contract; resolvers call `BPMMemberResolver.resolve(memberId)` when
371
+ > they need display data.
372
+
366
373
  > The host owns the mapping table. Keep it in one place (a constant
367
374
  > module or a database table) so adding a new BPM tier in a future
368
375
  > BPMCore release becomes a one-line addition.
@@ -482,10 +489,15 @@ and observable:
482
489
  uniqueness; use your host's stable identifier here (e.g. an LDAP DN
483
490
  slug or a internal ERP code). On a re-sync, look up existing entities
484
491
  by `code` before deciding INSERT vs UPDATE.
485
- 2. **`metadata` is the host-FK stash.** Both `OrgUnit` and `Membership`
486
- carry an opaque `metadata` JSON object that BPM never introspects.
487
- Store your host's primary key here (e.g. `{ shuttleOrgUnitId: 12345 }`)
488
- so you can chase the back-pointer when reconciling.
492
+ 2. **`metadataJson` is write-only.** The mutations
493
+ (`createOrgUnit`/`updateOrgUnit`/`createPosition`/`updatePosition`)
494
+ accept a `metadataJson` string that BPM stores verbatim. **However**,
495
+ `OrgUnitRecord` and `PositionRecord` returned by
496
+ `readOrganizationDashboard` do NOT include the metadata field —
497
+ it's intentionally hidden so the JSON blob doesn't bloat every
498
+ pagination payload. **For reconciliation, always key on `code`**
499
+ (which IS returned). Treat `metadataJson` as a debugging/audit
500
+ stash, not a live FK pointer.
489
501
  3. **Soft delete via `deleteOrgUnit` / `deleteMembership` / `deleteManagerResolution`.** Deletes set
490
502
  `deletedAt` rather than removing rows. BPM's query layer hides
491
503
  soft-deleted rows automatically; reading `orgUnitCount()` will report
@@ -511,7 +523,11 @@ input shapes — no `{id, input: {...}}` wrapping):
511
523
  - `updateOrgUnit({ id, code, name, type, parentId, metadataJson })`
512
524
  - `deleteOrgUnit(id)` (soft-delete)
513
525
  - `commitOrgUnitTreeDraft({ moves: { id, parentId, baseUpdatedAt }[] })` (transactional batch moves — each entry's `baseUpdatedAt` is the row's last-known `updatedAt`, used by BPM for optimistic-locking conflict detection)
514
- - `createPosition` / `updatePosition` (key on `code`)
526
+ - `createPosition({ code, name, level, metadataJson })` `level` (1+) controls hierarchy weight (higher = more senior, used by manager-resolution priority sort); `metadataJson` is required (pass `'{}'` if unused)
527
+ - `updatePosition({ id, code, name, level, metadataJson })` — every field except `id` is `T | null`; pass `null` to leave a field unchanged
528
+ - `createMembership({ memberId, orgUnitId, positionId, isPrimary, effectiveFrom, effectiveTo })` — `positionId` and `effectiveTo` accept `null`; `effectiveFrom` is an ISO timestamp string. Uniqueness key is `(memberId, orgUnitId, positionId)`
529
+ - `updateMembership({ id, orgUnitId, positionId, isPrimary, effectiveFrom, effectiveTo })` — every field except `id` is `T | null`
530
+ - `createManagerResolution({ scopeType, scopeId, managerMemberId, priority, effectiveFrom, effectiveTo })` — `scopeType` is `'MEMBER' | 'ORG_UNIT' | 'POSITION'`; `priority` orders the resolver chain (lower number = checked first)
515
531
  - `createMembership` / `updateMembership` (unique by `(memberId, orgUnitId, positionId)`)
516
532
  - `createManagerResolution` / `updateManagerResolution`
517
533
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rytass/bpm-core-nestjs-module",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Embeddable NestJS BPM approval workflow module: workflow engine, approval templates, forms, organization/member contracts, attachments, signatures, notifications, delegation, and TypeORM migrations.",
5
5
  "keywords": [
6
6
  "bpm",
@@ -141,7 +141,7 @@
141
141
  "@nestjs/core": "^11.0.0",
142
142
  "@nestjs/graphql": "^13.4.0",
143
143
  "@nestjs/typeorm": "^11.0.1",
144
- "@rytass/bpm-core-shared": "^0.1.7",
144
+ "@rytass/bpm-core-shared": "^0.1.8",
145
145
  "@rytass/secret-adapter-vault-nestjs": "^0.4.5 || ^0.5.0",
146
146
  "express": "^4.0.0 || ^5.0.0",
147
147
  "graphql": "^16.0.0",