@neohm/nh-cli 1.4.0 → 1.4.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/README.md CHANGED
@@ -19,7 +19,7 @@ differ only where the two packages do:
19
19
  | ------------------------ | ------------------------------------------ | ----------------------------------------- |
20
20
  | Import specifier | `@neohm/nestend` | `@neohm/nestendx` |
21
21
  | What a row belongs to | a tenant (`tenant_id` + `TenantEntity`) | the user who created it (`created_by`) |
22
- | Access check | `validateAccess(scope, role)` | `validateAccess(scope)` — there are no roles |
22
+ | Access check | `validateRole(role)` (scope checked first) | `validateAccess(scope)` — there are no roles |
23
23
  | Generated migration | FK + index on `tenant_id` | no tenant column to key |
24
24
 
25
25
  Everything that does not write package-specific code — `sync`, `check`, `list`,
@@ -137,7 +137,7 @@ Generated controllers run under `@UsePipes(StrictValidationPipe)`, take ids
137
137
  with `ParseUUIDPipe`, and describe every route with `@ApiOperation`.
138
138
 
139
139
  Controllers hold no business logic. They authenticate with
140
- `AuthService.validateAccess()`, then delegate to the module's service — so the
140
+ `AuthService.validateRole()` (`validateAccess()` under nhx), then delegate to the module's service — so the
141
141
  same operation is reusable from a job, a subscriber or another service, and the
142
142
  HTTP surface stays readable.
143
143
 
@@ -191,14 +191,15 @@ export enum RoleEnum {
191
191
  }
192
192
  ```
193
193
 
194
- The controller gates each endpoint at the lowest role that should reach it — a
195
- senior role satisfies a junior one in nestend's scoped RBAC:
194
+ The controller gates each endpoint at the lowest role that should reach it. A role
195
+ carries its scope, so `validateRole()` first checks the organization holds the
196
+ role's scope, then that the caller holds the role or a more senior one:
196
197
 
197
198
  | Endpoint | Gate |
198
199
  | --- | --- |
199
- | `GET :id`, `POST list` | `validateAccess(ScopeEnum.BILLING, RoleEnum.BILLING_READER)` |
200
- | `POST` (upsert) | `validateAccess(ScopeEnum.BILLING, RoleEnum.BILLING_MANAGER)` |
201
- | `DELETE :id` | `validateAccess(ScopeEnum.BILLING, RoleEnum.BILLING_ADMIN)` |
200
+ | `GET :id`, `POST list` | `validateRole(RoleEnum.BILLING_READER)` |
201
+ | `POST` (upsert) | `validateRole(RoleEnum.BILLING_MANAGER)` |
202
+ | `DELETE :id` | `validateRole(RoleEnum.BILLING_ADMIN)` |
202
203
 
203
204
  Under `nhx` the gate is `validateAccess(ScopeEnum.BILLING)`. The enums name the
204
205
  identifiers only: create the `sys_scopes` row and the three `sys_roles` rows
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neohm/nh-cli",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "nh / nhx — Command Line Interface for neohm. NestJS projects",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -178,28 +178,24 @@ function controller(
178
178
  );
179
179
  }
180
180
 
181
- // Tenanted access takes the entity's scope and the lowest role that should
182
- // reach the endpoint (a senior role satisfies a junior one); the B2C model
183
- // has no roles, so the same call carries the scope alone.
181
+ // Tenanted access names the lowest role that should reach the endpoint: the
182
+ // role carries its scope, so validateRole() checks the organization holds the
183
+ // scope first, then the role (a senior role satisfies a junior one). The B2C
184
+ // model has no roles, so the check is the scope alone.
184
185
  const tenanted = current().tenantScoped;
185
186
  imports.push(
186
- `import { ${scopeEnum} } from '../../global/enums/scope.enum';`,
187
+ tenanted
188
+ ? `import { ${roleEnum} } from '../../global/enums/role.enum';`
189
+ : `import { ${scopeEnum} } from '../../global/enums/scope.enum';`,
187
190
  );
188
- if (tenanted)
189
- imports.push(`import { ${roleEnum} } from '../../global/enums/role.enum';`);
190
- const scopeRef = `${scopeEnum}.${a.scopeKey}`;
191
191
  const gate = (indent, level) => {
192
- if (!tenanted) {
193
- const call = `await this.authService.validateAccess(${scopeRef})`;
194
- return `${indent}const { user } = ${call};`.length <= 80
195
- ? call
196
- : `await this.authService.validateAccess(\n${indent} ${scopeRef},\n${indent})`;
197
- }
198
- const roleRef = `${roleEnum}.${a.roles[level].key}`;
199
- const call = `await this.authService.validateAccess(${scopeRef}, ${roleRef})`;
192
+ const [method, arg] = tenanted
193
+ ? ['validateRole', `${roleEnum}.${a.roles[level].key}`]
194
+ : ['validateAccess', `${scopeEnum}.${a.scopeKey}`];
195
+ const call = `await this.authService.${method}(${arg})`;
200
196
  return `${indent}const { user } = ${call};`.length <= 80
201
197
  ? call
202
- : `await this.authService.validateAccess(\n${indent} ${scopeRef},\n${indent} ${roleRef},\n${indent})`;
198
+ : `await this.authService.${method}(\n${indent} ${arg},\n${indent})`;
203
199
  };
204
200
 
205
201
  const methods = [