@fiado/type-kit 3.88.0 → 3.90.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.
@@ -1,6 +1,6 @@
1
1
  // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
2
 
3
- exports[`PERMISSION_BIT_ORDER PERMS_VERSION es número estable 1`] = `3492726697`;
3
+ exports[`PERMISSION_BIT_ORDER PERMS_VERSION es número estable 1`] = `2374504554`;
4
4
 
5
5
  exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe ante cualquier reorden/inserción) 1`] = `
6
6
  [
@@ -120,5 +120,7 @@ exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe an
120
120
  "agents.group.manage",
121
121
  "agents.group.user.manage",
122
122
  "agents.person.create",
123
+ "platform.tenant.userfields.manage",
124
+ "agents.app.access",
123
125
  ]
124
126
  `;
@@ -24,4 +24,10 @@ export interface AuthContext {
24
24
  permVer?: number;
25
25
  /** @deprecated DEC-RBAC-008: epoch de permisos. El authorizer ya no lo chequea. */
26
26
  permsEpoch?: number;
27
+ /**
28
+ * Metadata de negocio por-usuario inyectada por jwt-inyector (campos personalizados del tenant
29
+ * marcados injectToToken). NO es autorización: NUNCA usar en un guard/decisión de acceso (DEC-RBAC-020).
30
+ * El gateway-adapter (buildAuthContextFromToken) parsea el claim JSON a este objeto.
31
+ */
32
+ customAttributes?: Record<string, string>;
27
33
  }
@@ -0,0 +1,10 @@
1
+ import { UserFieldType } from '../enums/UserFieldType';
2
+ /** Body del POST /backoffice/tenants/{tenantId}/user-fields. La validación de `options` por `type` (no vacío si select) la hace el manager. */
3
+ export declare class CreateUserFieldRequest {
4
+ key: string;
5
+ label: string;
6
+ type: UserFieldType;
7
+ options?: string[];
8
+ required: boolean;
9
+ injectToToken: boolean;
10
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CreateUserFieldRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const UserFieldType_1 = require("../enums/UserFieldType");
16
+ /** Body del POST /backoffice/tenants/{tenantId}/user-fields. La validación de `options` por `type` (no vacío si select) la hace el manager. */
17
+ class CreateUserFieldRequest {
18
+ }
19
+ exports.CreateUserFieldRequest = CreateUserFieldRequest;
20
+ __decorate([
21
+ (0, class_transformer_1.Expose)(),
22
+ (0, class_validator_1.IsString)(),
23
+ (0, class_validator_1.Matches)(/^[a-z][a-zA-Z0-9_]*$/, { message: 'key debe ser slug ^[a-z][a-zA-Z0-9_]*$' }),
24
+ __metadata("design:type", String)
25
+ ], CreateUserFieldRequest.prototype, "key", void 0);
26
+ __decorate([
27
+ (0, class_transformer_1.Expose)(),
28
+ (0, class_validator_1.IsString)(),
29
+ (0, class_validator_1.MaxLength)(80),
30
+ __metadata("design:type", String)
31
+ ], CreateUserFieldRequest.prototype, "label", void 0);
32
+ __decorate([
33
+ (0, class_transformer_1.Expose)(),
34
+ (0, class_validator_1.IsEnum)(UserFieldType_1.UserFieldType),
35
+ __metadata("design:type", String)
36
+ ], CreateUserFieldRequest.prototype, "type", void 0);
37
+ __decorate([
38
+ (0, class_transformer_1.Expose)(),
39
+ (0, class_validator_1.IsOptional)(),
40
+ (0, class_validator_1.IsArray)(),
41
+ (0, class_validator_1.ArrayNotEmpty)(),
42
+ (0, class_validator_1.IsString)({ each: true }),
43
+ __metadata("design:type", Array)
44
+ ], CreateUserFieldRequest.prototype, "options", void 0);
45
+ __decorate([
46
+ (0, class_transformer_1.Expose)(),
47
+ (0, class_validator_1.IsBoolean)(),
48
+ __metadata("design:type", Boolean)
49
+ ], CreateUserFieldRequest.prototype, "required", void 0);
50
+ __decorate([
51
+ (0, class_transformer_1.Expose)(),
52
+ (0, class_validator_1.IsBoolean)(),
53
+ __metadata("design:type", Boolean)
54
+ ], CreateUserFieldRequest.prototype, "injectToToken", void 0);
@@ -0,0 +1,5 @@
1
+ /** Respuesta del GET /internal/users/{cognitoSub}/injectable-attributes (consumida por jwt-inyector). */
2
+ export interface InjectableUserAttributesResponse {
3
+ /** Solo los campos injectToToken && enabled del tenant que tengan valor en el usuario. */
4
+ customAttributes: Record<string, string>;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ /** Body del PATCH /backoffice/tenants/{tenantId}/user-fields/{key}. `key` y `type` NO son editables (inmutables, DEC-RBAC-016). */
2
+ export declare class UpdateUserFieldRequest {
3
+ label?: string;
4
+ options?: string[];
5
+ required?: boolean;
6
+ injectToToken?: boolean;
7
+ enabled?: boolean;
8
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.UpdateUserFieldRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ /** Body del PATCH /backoffice/tenants/{tenantId}/user-fields/{key}. `key` y `type` NO son editables (inmutables, DEC-RBAC-016). */
16
+ class UpdateUserFieldRequest {
17
+ }
18
+ exports.UpdateUserFieldRequest = UpdateUserFieldRequest;
19
+ __decorate([
20
+ (0, class_transformer_1.Expose)(),
21
+ (0, class_validator_1.IsOptional)(),
22
+ (0, class_validator_1.IsString)(),
23
+ (0, class_validator_1.MaxLength)(80),
24
+ __metadata("design:type", String)
25
+ ], UpdateUserFieldRequest.prototype, "label", void 0);
26
+ __decorate([
27
+ (0, class_transformer_1.Expose)(),
28
+ (0, class_validator_1.IsOptional)(),
29
+ (0, class_validator_1.IsArray)(),
30
+ (0, class_validator_1.ArrayNotEmpty)(),
31
+ (0, class_validator_1.IsString)({ each: true }),
32
+ __metadata("design:type", Array)
33
+ ], UpdateUserFieldRequest.prototype, "options", void 0);
34
+ __decorate([
35
+ (0, class_transformer_1.Expose)(),
36
+ (0, class_validator_1.IsOptional)(),
37
+ (0, class_validator_1.IsBoolean)(),
38
+ __metadata("design:type", Boolean)
39
+ ], UpdateUserFieldRequest.prototype, "required", void 0);
40
+ __decorate([
41
+ (0, class_transformer_1.Expose)(),
42
+ (0, class_validator_1.IsOptional)(),
43
+ (0, class_validator_1.IsBoolean)(),
44
+ __metadata("design:type", Boolean)
45
+ ], UpdateUserFieldRequest.prototype, "injectToToken", void 0);
46
+ __decorate([
47
+ (0, class_transformer_1.Expose)(),
48
+ (0, class_validator_1.IsOptional)(),
49
+ (0, class_validator_1.IsBoolean)(),
50
+ __metadata("design:type", Boolean)
51
+ ], UpdateUserFieldRequest.prototype, "enabled", void 0);
@@ -0,0 +1,19 @@
1
+ import type { UserFieldType } from '../enums/UserFieldType';
2
+ /**
3
+ * Definición de un campo personalizado de usuario, embebida en PlatformTenantConfig.userFieldDefs.
4
+ * El `key` es inmutable (clave en el map de valores y en el claim). `enabled:false` = soft-disable.
5
+ * Timestamps inline: los setea el manager a mano (Dynamoose no mantiene sub-objetos inline). DEC-RBAC-016.
6
+ */
7
+ export interface UserFieldDef {
8
+ key: string;
9
+ label: string;
10
+ type: UserFieldType;
11
+ options?: string[];
12
+ required: boolean;
13
+ injectToToken: boolean;
14
+ enabled: boolean;
15
+ createdAt: number;
16
+ updatedAt: number;
17
+ createdBy: string;
18
+ updatedBy: string;
19
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -51,6 +51,7 @@ export declare enum Permission {
51
51
  PLATFORM_ROLE_UPDATE = "platform.role.update",
52
52
  PLATFORM_ROLE_DELETE = "platform.role.delete",
53
53
  PLATFORM_AUDIT_VIEW = "platform.audit.view",
54
+ PLATFORM_TENANT_USERFIELDS_MANAGE = "platform.tenant.userfields.manage",
54
55
  TENANT_USER_CREATE = "tenant.user.create",
55
56
  TENANT_USER_CREATE_LATERAL = "tenant.user.create.lateral",
56
57
  TENANT_USER_READ = "tenant.user.read",
@@ -119,6 +120,7 @@ export declare enum Permission {
119
120
  MDM_OPERATION_LOG_VIEW = "mdm.operation_log.view",
120
121
  MDM_TEST = "mdm.test",
121
122
  PAY_TRANSACTION_VIEW = "pay.transaction.view",
123
+ AGENTS_APP_ACCESS = "agents.app.access",
122
124
  AGENTS_AGENT_LIST = "agents.agent.list",
123
125
  AGENTS_AGENT_CREATE = "agents.agent.create",
124
126
  AGENTS_AGENT_CREATE_BULK = "agents.agent.create_bulk",
@@ -63,6 +63,7 @@ var Permission;
63
63
  Permission["PLATFORM_ROLE_UPDATE"] = "platform.role.update";
64
64
  Permission["PLATFORM_ROLE_DELETE"] = "platform.role.delete";
65
65
  Permission["PLATFORM_AUDIT_VIEW"] = "platform.audit.view";
66
+ Permission["PLATFORM_TENANT_USERFIELDS_MANAGE"] = "platform.tenant.userfields.manage";
66
67
  // ====================================================
67
68
  // TENANT — operaciones dentro del silo de un tenant
68
69
  // ====================================================
@@ -160,6 +161,9 @@ var Permission;
160
161
  // (ver fiado-agents-webapp/docs/rbac/RBAC-agents.md §5.2). El aislamiento entre orgs lo da el
161
162
  // scope GROUP del roleAssignment (scopeRef = Group_GT.id), no un permiso aparte.
162
163
  // ====================================================
164
+ // Gate de ACCESO a la app web de Agents (gobernanza). Sin este permiso el usuario no
165
+ // entra a la app. Lo otorgan los 5 roles GROUP de agents (en su propio repo, no acá).
166
+ Permission["AGENTS_APP_ACCESS"] = "agents.app.access";
163
167
  Permission["AGENTS_AGENT_LIST"] = "agents.agent.list";
164
168
  Permission["AGENTS_AGENT_CREATE"] = "agents.agent.create";
165
169
  Permission["AGENTS_AGENT_CREATE_BULK"] = "agents.agent.create_bulk";
@@ -321,6 +325,13 @@ exports.PERMISSION_BIT_ORDER = [
321
325
  // Append-only: nuevo permiso agregado 2026-06-18 (DEC-A2-02). Va al FINAL para no correr los bits
322
326
  // existentes (PERMS_VERSION cambia, pero los índices previos se conservan).
323
327
  Permission.AGENTS_PERSON_CREATE,
328
+ // Append-only 2026-06-18 (DEC-RBAC-017): catálogo de campos personalizados por tenant. Al FINAL para
329
+ // no correr bits existentes. (El bitset está deprecado por token-flaco, pero el orden se mantiene
330
+ // sincronizado con el enum para que el test de bits no rompa.)
331
+ Permission.PLATFORM_TENANT_USERFIELDS_MANAGE,
332
+ // Append-only 2026-06-21: gate de acceso a la app web de Agents (gobernanza). Al FINAL para no
333
+ // correr bits existentes (PERMS_VERSION cambia, pero los índices previos se conservan).
334
+ Permission.AGENTS_APP_ACCESS,
324
335
  ];
325
336
  function djb2(input) {
326
337
  let h = 5381;
@@ -0,0 +1,5 @@
1
+ /** Tipo de un campo personalizado de usuario. text = texto libre; select = lista cerrada de opciones. */
2
+ export declare enum UserFieldType {
3
+ TEXT = "text",
4
+ SELECT = "select"
5
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserFieldType = void 0;
4
+ /** Tipo de un campo personalizado de usuario. text = texto libre; select = lista cerrada de opciones. */
5
+ var UserFieldType;
6
+ (function (UserFieldType) {
7
+ UserFieldType["TEXT"] = "text";
8
+ UserFieldType["SELECT"] = "select";
9
+ })(UserFieldType || (exports.UserFieldType = UserFieldType = {}));
@@ -29,3 +29,8 @@ export type { CreateTenantResponse } from './dtos/CreateTenantResponse';
29
29
  export * from './dtos/UpdateTenantSecurityPolicyRequest';
30
30
  export type { TenantSecurityPolicyResponse } from './dtos/TenantSecurityPolicyResponse';
31
31
  export { TenantType, TENANT_TYPES, levelsOf, tableSuffixForLevel, scopeRankOrder } from './tenantTypes';
32
+ export { UserFieldType } from './enums/UserFieldType';
33
+ export type { UserFieldDef } from './dtos/UserFieldDef';
34
+ export * from './dtos/CreateUserFieldRequest';
35
+ export * from './dtos/UpdateUserFieldRequest';
36
+ export type { InjectableUserAttributesResponse } from './dtos/InjectableUserAttributesResponse';
@@ -23,7 +23,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
23
23
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.scopeRankOrder = exports.tableSuffixForLevel = exports.levelsOf = exports.TENANT_TYPES = exports.TenantType = exports.AuthorizeDenyReason = exports.PermissionCategory = exports.PermissionScope = exports.bitsToPermissions = exports.permissionsToBits = exports.PERMS_VERSION = exports.PERMISSION_BIT_ORDER = exports.Permission = void 0;
26
+ exports.UserFieldType = exports.scopeRankOrder = exports.tableSuffixForLevel = exports.levelsOf = exports.TENANT_TYPES = exports.TenantType = exports.AuthorizeDenyReason = exports.PermissionCategory = exports.PermissionScope = exports.bitsToPermissions = exports.permissionsToBits = exports.PERMS_VERSION = exports.PERMISSION_BIT_ORDER = exports.Permission = void 0;
27
27
  var Permission_1 = require("./enums/Permission");
28
28
  Object.defineProperty(exports, "Permission", { enumerable: true, get: function () { return Permission_1.Permission; } });
29
29
  Object.defineProperty(exports, "PERMISSION_BIT_ORDER", { enumerable: true, get: function () { return Permission_1.PERMISSION_BIT_ORDER; } });
@@ -73,3 +73,11 @@ Object.defineProperty(exports, "TENANT_TYPES", { enumerable: true, get: function
73
73
  Object.defineProperty(exports, "levelsOf", { enumerable: true, get: function () { return tenantTypes_1.levelsOf; } });
74
74
  Object.defineProperty(exports, "tableSuffixForLevel", { enumerable: true, get: function () { return tenantTypes_1.tableSuffixForLevel; } });
75
75
  Object.defineProperty(exports, "scopeRankOrder", { enumerable: true, get: function () { return tenantTypes_1.scopeRankOrder; } });
76
+ // Campos personalizados de usuario por tenant — embebidos en PlatformTenantConfig.userFieldDefs.
77
+ // UserFieldType es enum (export de valor); UserFieldDef es interface plain (type-only).
78
+ var UserFieldType_1 = require("./enums/UserFieldType");
79
+ Object.defineProperty(exports, "UserFieldType", { enumerable: true, get: function () { return UserFieldType_1.UserFieldType; } });
80
+ // DTOs de endpoints user-fields. Create/Update Request llevan decoradores class-validator → export de valor.
81
+ // InjectableUserAttributesResponse es interface plain (consumida por jwt-inyector) → type-only.
82
+ __exportStar(require("./dtos/CreateUserFieldRequest"), exports);
83
+ __exportStar(require("./dtos/UpdateUserFieldRequest"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.88.0",
3
+ "version": "3.90.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -25,4 +25,10 @@ export interface AuthContext {
25
25
  permVer?: number;
26
26
  /** @deprecated DEC-RBAC-008: epoch de permisos. El authorizer ya no lo chequea. */
27
27
  permsEpoch?: number;
28
+ /**
29
+ * Metadata de negocio por-usuario inyectada por jwt-inyector (campos personalizados del tenant
30
+ * marcados injectToToken). NO es autorización: NUNCA usar en un guard/decisión de acceso (DEC-RBAC-020).
31
+ * El gateway-adapter (buildAuthContextFromToken) parsea el claim JSON a este objeto.
32
+ */
33
+ customAttributes?: Record<string, string>;
28
34
  }
@@ -0,0 +1,13 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { ArrayNotEmpty, IsArray, IsBoolean, IsEnum, IsOptional, IsString, Matches, MaxLength } from 'class-validator';
3
+ import { UserFieldType } from '../enums/UserFieldType';
4
+
5
+ /** Body del POST /backoffice/tenants/{tenantId}/user-fields. La validación de `options` por `type` (no vacío si select) la hace el manager. */
6
+ export class CreateUserFieldRequest {
7
+ @Expose() @IsString() @Matches(/^[a-z][a-zA-Z0-9_]*$/, { message: 'key debe ser slug ^[a-z][a-zA-Z0-9_]*$' }) key!: string;
8
+ @Expose() @IsString() @MaxLength(80) label!: string;
9
+ @Expose() @IsEnum(UserFieldType) type!: UserFieldType;
10
+ @Expose() @IsOptional() @IsArray() @ArrayNotEmpty() @IsString({ each: true }) options?: string[];
11
+ @Expose() @IsBoolean() required!: boolean;
12
+ @Expose() @IsBoolean() injectToToken!: boolean;
13
+ }
@@ -0,0 +1,5 @@
1
+ /** Respuesta del GET /internal/users/{cognitoSub}/injectable-attributes (consumida por jwt-inyector). */
2
+ export interface InjectableUserAttributesResponse {
3
+ /** Solo los campos injectToToken && enabled del tenant que tengan valor en el usuario. */
4
+ customAttributes: Record<string, string>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { ArrayNotEmpty, IsArray, IsBoolean, IsOptional, IsString, MaxLength } from 'class-validator';
3
+
4
+ /** Body del PATCH /backoffice/tenants/{tenantId}/user-fields/{key}. `key` y `type` NO son editables (inmutables, DEC-RBAC-016). */
5
+ export class UpdateUserFieldRequest {
6
+ @Expose() @IsOptional() @IsString() @MaxLength(80) label?: string;
7
+ @Expose() @IsOptional() @IsArray() @ArrayNotEmpty() @IsString({ each: true }) options?: string[];
8
+ @Expose() @IsOptional() @IsBoolean() required?: boolean;
9
+ @Expose() @IsOptional() @IsBoolean() injectToToken?: boolean;
10
+ @Expose() @IsOptional() @IsBoolean() enabled?: boolean;
11
+ }
@@ -0,0 +1,20 @@
1
+ import type { UserFieldType } from '../enums/UserFieldType';
2
+
3
+ /**
4
+ * Definición de un campo personalizado de usuario, embebida en PlatformTenantConfig.userFieldDefs.
5
+ * El `key` es inmutable (clave en el map de valores y en el claim). `enabled:false` = soft-disable.
6
+ * Timestamps inline: los setea el manager a mano (Dynamoose no mantiene sub-objetos inline). DEC-RBAC-016.
7
+ */
8
+ export interface UserFieldDef {
9
+ key: string;
10
+ label: string;
11
+ type: UserFieldType;
12
+ options?: string[];
13
+ required: boolean;
14
+ injectToToken: boolean;
15
+ enabled: boolean;
16
+ createdAt: number;
17
+ updatedAt: number;
18
+ createdBy: string;
19
+ updatedBy: string;
20
+ }
@@ -58,6 +58,7 @@ export enum Permission {
58
58
  PLATFORM_ROLE_UPDATE = 'platform.role.update',
59
59
  PLATFORM_ROLE_DELETE = 'platform.role.delete',
60
60
  PLATFORM_AUDIT_VIEW = 'platform.audit.view',
61
+ PLATFORM_TENANT_USERFIELDS_MANAGE = 'platform.tenant.userfields.manage',
61
62
 
62
63
  // ====================================================
63
64
  // TENANT — operaciones dentro del silo de un tenant
@@ -161,6 +162,9 @@ export enum Permission {
161
162
  // (ver fiado-agents-webapp/docs/rbac/RBAC-agents.md §5.2). El aislamiento entre orgs lo da el
162
163
  // scope GROUP del roleAssignment (scopeRef = Group_GT.id), no un permiso aparte.
163
164
  // ====================================================
165
+ // Gate de ACCESO a la app web de Agents (gobernanza). Sin este permiso el usuario no
166
+ // entra a la app. Lo otorgan los 5 roles GROUP de agents (en su propio repo, no acá).
167
+ AGENTS_APP_ACCESS = 'agents.app.access',
164
168
  AGENTS_AGENT_LIST = 'agents.agent.list',
165
169
  AGENTS_AGENT_CREATE = 'agents.agent.create',
166
170
  AGENTS_AGENT_CREATE_BULK = 'agents.agent.create_bulk',
@@ -323,6 +327,13 @@ export const PERMISSION_BIT_ORDER: readonly Permission[] = [
323
327
  // Append-only: nuevo permiso agregado 2026-06-18 (DEC-A2-02). Va al FINAL para no correr los bits
324
328
  // existentes (PERMS_VERSION cambia, pero los índices previos se conservan).
325
329
  Permission.AGENTS_PERSON_CREATE,
330
+ // Append-only 2026-06-18 (DEC-RBAC-017): catálogo de campos personalizados por tenant. Al FINAL para
331
+ // no correr bits existentes. (El bitset está deprecado por token-flaco, pero el orden se mantiene
332
+ // sincronizado con el enum para que el test de bits no rompa.)
333
+ Permission.PLATFORM_TENANT_USERFIELDS_MANAGE,
334
+ // Append-only 2026-06-21: gate de acceso a la app web de Agents (gobernanza). Al FINAL para no
335
+ // correr bits existentes (PERMS_VERSION cambia, pero los índices previos se conservan).
336
+ Permission.AGENTS_APP_ACCESS,
326
337
  ] as const;
327
338
 
328
339
  function djb2(input: string): number {
@@ -0,0 +1,5 @@
1
+ /** Tipo de un campo personalizado de usuario. text = texto libre; select = lista cerrada de opciones. */
2
+ export enum UserFieldType {
3
+ TEXT = 'text',
4
+ SELECT = 'select',
5
+ }
@@ -62,3 +62,14 @@ export type { TenantSecurityPolicyResponse } from './dtos/TenantSecurityPolicyRe
62
62
  // Consumido por ScopeValidationService._rank vía scopeRankOrder() y por los seeds.
63
63
  // Accesible bajo el namespace PlatformRbac (el index raíz hace export * as PlatformRbac).
64
64
  export { TenantType, TENANT_TYPES, levelsOf, tableSuffixForLevel, scopeRankOrder } from './tenantTypes';
65
+
66
+ // Campos personalizados de usuario por tenant — embebidos en PlatformTenantConfig.userFieldDefs.
67
+ // UserFieldType es enum (export de valor); UserFieldDef es interface plain (type-only).
68
+ export { UserFieldType } from './enums/UserFieldType';
69
+ export type { UserFieldDef } from './dtos/UserFieldDef';
70
+
71
+ // DTOs de endpoints user-fields. Create/Update Request llevan decoradores class-validator → export de valor.
72
+ // InjectableUserAttributesResponse es interface plain (consumida por jwt-inyector) → type-only.
73
+ export * from './dtos/CreateUserFieldRequest';
74
+ export * from './dtos/UpdateUserFieldRequest';
75
+ export type { InjectableUserAttributesResponse } from './dtos/InjectableUserAttributesResponse';