@rytass/bpm-core-nestjs-module 0.1.9 → 0.1.10

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 +24 -0
  2. package/README.md +64 -2
  3. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -9,6 +9,30 @@ 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.10 — 2026-05-28
13
+
14
+ ### Documentation
15
+
16
+ - **Pattern A response status contract table** added — explicit success
17
+ / auth-fail / validation-fail HTTP status codes for `/auth/login`,
18
+ `/auth/me`, `/auth/logout`. Also notes that `roles` and `permissions`
19
+ must be arrays (not `null`/`undefined`), and shows the
20
+ `projectMemberToApiMember` skeleton mapping `ApiMember.email: string`
21
+ (not `string | null`).
22
+ - **"Concrete wiring" snippet** for the recommended same-database
23
+ separate-schema option B: dual `TypeOrmModule.forRootAsync` with
24
+ `name: 'bpm'` so the host's existing connection and BPM's stay
25
+ isolated. Also shows handing `typeormConnectionName: 'bpm'` to
26
+ `BPMRootModule.forRootAsync`.
27
+ - **`createBPMMemberBaseResolverProvider<HostMember>` generic** added
28
+ to the README example with a callout about why omitting it causes
29
+ TS to infer `unknown`.
30
+ - "Current version" line refreshed to `0.1.10`.
31
+
32
+ ### Why a patch
33
+
34
+ Documentation only.
35
+
12
36
  ## 0.1.9 — 2026-05-28
13
37
 
14
38
  ### Documentation
package/README.md CHANGED
@@ -14,7 +14,7 @@ directory integration, storage adapters, and deployment.
14
14
 
15
15
  ## Package Status
16
16
 
17
- Current version: `0.1.7`
17
+ Current version: `0.1.10`
18
18
 
19
19
  The package is intended for NestJS backend hosts. It does not include the
20
20
  Next.js backoffice UI and does not provide a production auth system by itself.
@@ -273,6 +273,31 @@ member shape to BPM's expectations, project Casbin roles into the BPM
273
273
  role-literal strings (see "Mapping from a host RBAC system" below),
274
274
  and compute `expiresAt` from the token TTL.
275
275
 
276
+ ```ts
277
+ function projectMemberToApiMember(member: HostMember): ApiMember {
278
+ return {
279
+ memberId: member.id,
280
+ email: member.email ?? '', // ApiMember.email is `string`, not `string | null`
281
+ name: member.name,
282
+ roles: projectHostRolesToBPMRoles(member.roles), // [] if no admin/designer claim
283
+ permissions: [], // optional — return [] if not used
284
+ expiresAt: new Date(Date.now() + JWT_TTL_MS).toISOString(),
285
+ };
286
+ }
287
+ ```
288
+
289
+ Response status contract that BPM's React client expects:
290
+
291
+ | Endpoint | Success | Auth fail | Validation fail |
292
+ |---|---|---|---|
293
+ | `POST /auth/login` | `200` + `ApiMember` JSON, set HTTP-only cookie | `401` | `400` |
294
+ | `GET /auth/me` | `200` + `ApiMember` JSON | `401` (client treats as anonymous, **not error**) | n/a |
295
+ | `POST /auth/logout` | `204` (or `200` with empty body) | `401` ignored — client clears local state anyway | n/a |
296
+
297
+ `roles` and `permissions` MUST be arrays (use `[]` for no claim), not
298
+ `null` or `undefined` — the React client's `member.roles.includes(...)`
299
+ checks would crash otherwise.
300
+
276
301
  #### Pattern B — Run BPM on a separate auth host
277
302
 
278
303
  When BPM lives on its own subdomain (e.g. `bpm.example.com`) separate
@@ -531,7 +556,10 @@ export const hostMemberProviders: readonly Provider[] = [
531
556
  provide: HOST_MEMBER_DIRECTORY,
532
557
  useClass: HostMemberDirectory,
533
558
  },
534
- createBPMMemberBaseResolverProvider({
559
+ createBPMMemberBaseResolverProvider<HostMember>({
560
+ // ^^^^^^^^^^^^ explicit generic is recommended — without it,
561
+ // TS infers `unknown` for the adapter callbacks below and you get
562
+ // "Parameter 'member' implicitly has an 'any' type" errors.
535
563
  adapterOptions: {
536
564
  readEmail: (member): string => member.email,
537
565
  readMemberId: (member): string => member.id,
@@ -910,6 +938,40 @@ BPM's `buildTypeOrmModuleOptions` create **two distinct connections**
910
938
  to the same Postgres cluster with different `schema:` settings — that
911
939
  is the cleanest separation Nest's TypeORM module supports.
912
940
 
941
+ Concrete wiring:
942
+
943
+ ```ts
944
+ // apps/api/src/app/app.module.ts
945
+ @Module({
946
+ imports: [
947
+ // Host's existing TypeORM connection (default name, host's schema).
948
+ TypeOrmModule.forRootAsync({
949
+ imports: [HostVaultModule],
950
+ inject: [HostVaultService],
951
+ useFactory: (vault) => buildHostDataSourceOptions(vault), // schema: 'public'
952
+ }),
953
+ // BPM's own connection (named, separate schema, separate Vault path).
954
+ TypeOrmModule.forRootAsync({
955
+ name: 'bpm', // <-- distinct connection name
956
+ imports: [BPMVaultModule],
957
+ inject: [BPMVaultService],
958
+ useFactory: buildTypeOrmModuleOptions, // reads DB_SCHEMA=bpm_core from Vault
959
+ }),
960
+ // Hand BPM the connection name so its repositories bind to the right pool.
961
+ BPMRootModule.forRootAsync({
962
+ typeormConnectionName: 'bpm',
963
+ // ...
964
+ }),
965
+ ],
966
+ })
967
+ ```
968
+
969
+ If the host runs only one Vault path (e.g. `shuttle/develop`) and you
970
+ want to keep secrets there, expose `bpm_core/*` keys under the host
971
+ path with a prefix and provide a custom factory that reads them — BPM
972
+ doesn't require its own Vault path, only that the secrets are
973
+ available to `buildTypeOrmModuleOptions`.
974
+
913
975
  Vault paths can be split independently: keep `shuttle/develop` for the
914
976
  host and create `bpm_core/develop` for BPM secrets. BPM's helper reads
915
977
  its own path; the host's auth module reads its own. They do not
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rytass/bpm-core-nestjs-module",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
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.9",
144
+ "@rytass/bpm-core-shared": "^0.1.10",
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",