tychat-contracts 1.6.9 → 1.6.12
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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/panel-rbac/access-permission-item.dto.d.ts +6 -0
- package/dist/panel-rbac/access-permission-item.dto.d.ts.map +1 -0
- package/dist/panel-rbac/access-permission-item.dto.js +36 -0
- package/dist/panel-rbac/create-access-level.dto.d.ts +6 -0
- package/dist/panel-rbac/create-access-level.dto.d.ts.map +1 -0
- package/dist/panel-rbac/create-access-level.dto.js +39 -0
- package/dist/panel-rbac/dashboard-layout.dto.d.ts +27 -0
- package/dist/panel-rbac/dashboard-layout.dto.d.ts.map +1 -0
- package/dist/panel-rbac/dashboard-layout.dto.js +148 -0
- package/dist/panel-rbac/index.d.ts +8 -0
- package/dist/panel-rbac/index.d.ts.map +1 -0
- package/dist/panel-rbac/index.js +23 -0
- package/dist/panel-rbac/panel-context-response.dto.d.ts +12 -0
- package/dist/panel-rbac/panel-context-response.dto.d.ts.map +1 -0
- package/dist/panel-rbac/panel-context-response.dto.js +48 -0
- package/dist/panel-rbac/panel-permission-keys.d.ts +29 -0
- package/dist/panel-rbac/panel-permission-keys.d.ts.map +1 -0
- package/dist/panel-rbac/panel-permission-keys.js +48 -0
- package/dist/panel-rbac/panel-permission-keys.spec.d.ts +2 -0
- package/dist/panel-rbac/panel-permission-keys.spec.d.ts.map +1 -0
- package/dist/panel-rbac/panel-permission-keys.spec.js +16 -0
- package/dist/panel-rbac/replace-access-permissions.dto.d.ts +5 -0
- package/dist/panel-rbac/replace-access-permissions.dto.d.ts.map +1 -0
- package/dist/panel-rbac/replace-access-permissions.dto.js +28 -0
- package/dist/panel-rbac/update-access-level.dto.d.ts +8 -0
- package/dist/panel-rbac/update-access-level.dto.d.ts.map +1 -0
- package/dist/panel-rbac/update-access-level.dto.js +54 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/panel-rbac/access-permission-item.dto.ts +20 -0
- package/src/panel-rbac/create-access-level.dto.ts +20 -0
- package/src/panel-rbac/dashboard-layout.dto.ts +134 -0
- package/src/panel-rbac/index.ts +7 -0
- package/src/panel-rbac/panel-context-response.dto.ts +28 -0
- package/src/panel-rbac/panel-permission-keys.spec.ts +20 -0
- package/src/panel-rbac/panel-permission-keys.ts +57 -0
- package/src/panel-rbac/replace-access-permissions.dto.ts +13 -0
- package/src/panel-rbac/update-access-level.dto.ts +40 -0
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,MAAM,CAAC;AACrB,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,MAAM,CAAC;AACrB,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-permission-item.dto.d.ts","sourceRoot":"","sources":["../../src/panel-rbac/access-permission-item.dto.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAIrF,qBAAa,uBAAuB;IAIlC,QAAQ,EAAE,aAAa,CAAC;IAQxB,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
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.AccessPermissionItemDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const panel_permission_keys_1 = require("./panel-permission-keys");
|
|
16
|
+
const RESOURCES = Object.keys(panel_permission_keys_1.PANEL_RESOURCE_ACTIONS);
|
|
17
|
+
class AccessPermissionItemDto {
|
|
18
|
+
resource;
|
|
19
|
+
action;
|
|
20
|
+
}
|
|
21
|
+
exports.AccessPermissionItemDto = AccessPermissionItemDto;
|
|
22
|
+
__decorate([
|
|
23
|
+
(0, swagger_1.ApiProperty)({ enum: RESOURCES }),
|
|
24
|
+
(0, class_validator_1.IsString)(),
|
|
25
|
+
(0, class_validator_1.IsIn)(RESOURCES),
|
|
26
|
+
__metadata("design:type", String)
|
|
27
|
+
], AccessPermissionItemDto.prototype, "resource", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, swagger_1.ApiProperty)({
|
|
30
|
+
description: 'Ação permitida para o recurso',
|
|
31
|
+
example: 'view',
|
|
32
|
+
}),
|
|
33
|
+
(0, class_validator_1.IsString)(),
|
|
34
|
+
(0, class_validator_1.MaxLength)(80),
|
|
35
|
+
__metadata("design:type", String)
|
|
36
|
+
], AccessPermissionItemDto.prototype, "action", void 0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-access-level.dto.d.ts","sourceRoot":"","sources":["../../src/panel-rbac/create-access-level.dto.ts"],"names":[],"mappings":"AAGA,qBAAa,oBAAoB;IAI/B,IAAI,EAAE,MAAM,CAAC;IAMb,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
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.CreateAccessLevelDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
class CreateAccessLevelDto {
|
|
16
|
+
name;
|
|
17
|
+
description;
|
|
18
|
+
isActive;
|
|
19
|
+
}
|
|
20
|
+
exports.CreateAccessLevelDto = CreateAccessLevelDto;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, class_validator_1.IsString)(),
|
|
23
|
+
(0, class_validator_1.MinLength)(1),
|
|
24
|
+
(0, class_validator_1.MaxLength)(120),
|
|
25
|
+
__metadata("design:type", String)
|
|
26
|
+
], CreateAccessLevelDto.prototype, "name", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, swagger_1.ApiPropertyOptional)(),
|
|
29
|
+
(0, class_validator_1.IsOptional)(),
|
|
30
|
+
(0, class_validator_1.IsString)(),
|
|
31
|
+
(0, class_validator_1.MaxLength)(500),
|
|
32
|
+
__metadata("design:type", String)
|
|
33
|
+
], CreateAccessLevelDto.prototype, "description", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
(0, swagger_1.ApiPropertyOptional)({ default: true }),
|
|
36
|
+
(0, class_validator_1.IsOptional)(),
|
|
37
|
+
(0, class_validator_1.IsBoolean)(),
|
|
38
|
+
__metadata("design:type", Boolean)
|
|
39
|
+
], CreateAccessLevelDto.prototype, "isActive", void 0);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Tipos de visualização permitidos no painel (determinísticos). */
|
|
2
|
+
export declare const DASHBOARD_CHART_TYPES: readonly ["stat", "card", "bar", "line", "area", "pie", "radial", "table"];
|
|
3
|
+
export type DashboardChartType = (typeof DASHBOARD_CHART_TYPES)[number];
|
|
4
|
+
/**
|
|
5
|
+
* Módulos de dados agregados do dashboard (cada um mapeia a permissões e a fatia do summary).
|
|
6
|
+
* Manter alinhado ao `Frontend/.../lib/dashboard-data-modules.ts`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const DASHBOARD_DATA_MODULE_KEYS: readonly ["overview.clients_total", "overview.clients_active_inactive", "overview.units_total", "overview.revenue_totals", "overview.revenue_growth", "overview.invoice_counts", "billing.revenue_by_status", "billing.invoice_counts", "billing.recent_invoices", "billing.payment_links", "tenants.client_list", "tenants.plan_per_client", "tenants.legal_term_policy", "tenants.whatsapp_provider", "tenants.scheduled_deletion", "tenants.hostnames", "tenants.storage_usage", "limits.per_client", "limits.session_policy", "limits.extra_storage", "plans.stats", "plans.list", "ia.tokens_per_tenant", "ia.agents_per_tenant", "ia.tool_policies", "ia.models_availability", "evolution.configs_summary", "evolution.instances_totals", "evolution.connection_state", "global.platform_config", "team.panel_admins", "audit.recent_events", "audit.outcome_counts", "security.device_sessions", "security.totp_status"];
|
|
9
|
+
export type DashboardDataModuleKey = (typeof DASHBOARD_DATA_MODULE_KEYS)[number];
|
|
10
|
+
export declare function isDashboardDataModuleKey(v: string): v is DashboardDataModuleKey;
|
|
11
|
+
export declare class DashboardWidgetDto {
|
|
12
|
+
id: string;
|
|
13
|
+
dataModule: DashboardDataModuleKey;
|
|
14
|
+
chartType: DashboardChartType;
|
|
15
|
+
/** Coluna inicial (grelha 12 colunas). */
|
|
16
|
+
x: number;
|
|
17
|
+
/** Largura em colunas (1–12). */
|
|
18
|
+
w: number;
|
|
19
|
+
/** Ordem de leitura (menor = primeiro). */
|
|
20
|
+
order: number;
|
|
21
|
+
title?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare class DashboardLayoutDto {
|
|
24
|
+
version: number;
|
|
25
|
+
widgets: DashboardWidgetDto[];
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=dashboard-layout.dto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-layout.dto.d.ts","sourceRoot":"","sources":["../../src/panel-rbac/dashboard-layout.dto.ts"],"names":[],"mappings":"AAgBA,oEAAoE;AACpE,eAAO,MAAM,qBAAqB,4EASxB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,0BAA0B,i4BAoC7B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjF,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,sBAAsB,CAE/E;AAED,qBAAa,kBAAkB;IAG7B,EAAE,EAAE,MAAM,CAAC;IAKX,UAAU,EAAE,sBAAsB,CAAC;IAKnC,SAAS,EAAE,kBAAkB,CAAC;IAE9B,0CAA0C;IAK1C,CAAC,EAAE,MAAM,CAAC;IAEV,iCAAiC;IAKjC,CAAC,EAAE,MAAM,CAAC;IAEV,2CAA2C;IAI3C,KAAK,EAAE,MAAM,CAAC;IAMd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,kBAAkB;IAK7B,OAAO,EAAE,MAAM,CAAC;IAOhB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B"}
|
|
@@ -0,0 +1,148 @@
|
|
|
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.DashboardLayoutDto = exports.DashboardWidgetDto = exports.DASHBOARD_DATA_MODULE_KEYS = exports.DASHBOARD_CHART_TYPES = void 0;
|
|
13
|
+
exports.isDashboardDataModuleKey = isDashboardDataModuleKey;
|
|
14
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
15
|
+
const class_transformer_1 = require("class-transformer");
|
|
16
|
+
const class_validator_1 = require("class-validator");
|
|
17
|
+
/** Tipos de visualização permitidos no painel (determinísticos). */
|
|
18
|
+
exports.DASHBOARD_CHART_TYPES = [
|
|
19
|
+
'stat',
|
|
20
|
+
'card',
|
|
21
|
+
'bar',
|
|
22
|
+
'line',
|
|
23
|
+
'area',
|
|
24
|
+
'pie',
|
|
25
|
+
'radial',
|
|
26
|
+
'table',
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Módulos de dados agregados do dashboard (cada um mapeia a permissões e a fatia do summary).
|
|
30
|
+
* Manter alinhado ao `Frontend/.../lib/dashboard-data-modules.ts`.
|
|
31
|
+
*/
|
|
32
|
+
exports.DASHBOARD_DATA_MODULE_KEYS = [
|
|
33
|
+
'overview.clients_total',
|
|
34
|
+
'overview.clients_active_inactive',
|
|
35
|
+
'overview.units_total',
|
|
36
|
+
'overview.revenue_totals',
|
|
37
|
+
'overview.revenue_growth',
|
|
38
|
+
'overview.invoice_counts',
|
|
39
|
+
'billing.revenue_by_status',
|
|
40
|
+
'billing.invoice_counts',
|
|
41
|
+
'billing.recent_invoices',
|
|
42
|
+
'billing.payment_links',
|
|
43
|
+
'tenants.client_list',
|
|
44
|
+
'tenants.plan_per_client',
|
|
45
|
+
'tenants.legal_term_policy',
|
|
46
|
+
'tenants.whatsapp_provider',
|
|
47
|
+
'tenants.scheduled_deletion',
|
|
48
|
+
'tenants.hostnames',
|
|
49
|
+
'tenants.storage_usage',
|
|
50
|
+
'limits.per_client',
|
|
51
|
+
'limits.session_policy',
|
|
52
|
+
'limits.extra_storage',
|
|
53
|
+
'plans.stats',
|
|
54
|
+
'plans.list',
|
|
55
|
+
'ia.tokens_per_tenant',
|
|
56
|
+
'ia.agents_per_tenant',
|
|
57
|
+
'ia.tool_policies',
|
|
58
|
+
'ia.models_availability',
|
|
59
|
+
'evolution.configs_summary',
|
|
60
|
+
'evolution.instances_totals',
|
|
61
|
+
'evolution.connection_state',
|
|
62
|
+
'global.platform_config',
|
|
63
|
+
'team.panel_admins',
|
|
64
|
+
'audit.recent_events',
|
|
65
|
+
'audit.outcome_counts',
|
|
66
|
+
'security.device_sessions',
|
|
67
|
+
'security.totp_status',
|
|
68
|
+
];
|
|
69
|
+
function isDashboardDataModuleKey(v) {
|
|
70
|
+
return exports.DASHBOARD_DATA_MODULE_KEYS.includes(v);
|
|
71
|
+
}
|
|
72
|
+
class DashboardWidgetDto {
|
|
73
|
+
id;
|
|
74
|
+
dataModule;
|
|
75
|
+
chartType;
|
|
76
|
+
/** Coluna inicial (grelha 12 colunas). */
|
|
77
|
+
x;
|
|
78
|
+
/** Largura em colunas (1–12). */
|
|
79
|
+
w;
|
|
80
|
+
/** Ordem de leitura (menor = primeiro). */
|
|
81
|
+
order;
|
|
82
|
+
title;
|
|
83
|
+
}
|
|
84
|
+
exports.DashboardWidgetDto = DashboardWidgetDto;
|
|
85
|
+
__decorate([
|
|
86
|
+
(0, swagger_1.ApiProperty)({ format: 'uuid' }),
|
|
87
|
+
(0, class_validator_1.IsUUID)('4'),
|
|
88
|
+
__metadata("design:type", String)
|
|
89
|
+
], DashboardWidgetDto.prototype, "id", void 0);
|
|
90
|
+
__decorate([
|
|
91
|
+
(0, swagger_1.ApiProperty)({ enum: exports.DASHBOARD_DATA_MODULE_KEYS }),
|
|
92
|
+
(0, class_validator_1.IsString)(),
|
|
93
|
+
(0, class_validator_1.IsIn)([...exports.DASHBOARD_DATA_MODULE_KEYS]),
|
|
94
|
+
__metadata("design:type", String)
|
|
95
|
+
], DashboardWidgetDto.prototype, "dataModule", void 0);
|
|
96
|
+
__decorate([
|
|
97
|
+
(0, swagger_1.ApiProperty)({ enum: exports.DASHBOARD_CHART_TYPES }),
|
|
98
|
+
(0, class_validator_1.IsString)(),
|
|
99
|
+
(0, class_validator_1.IsIn)([...exports.DASHBOARD_CHART_TYPES]),
|
|
100
|
+
__metadata("design:type", String)
|
|
101
|
+
], DashboardWidgetDto.prototype, "chartType", void 0);
|
|
102
|
+
__decorate([
|
|
103
|
+
(0, swagger_1.ApiProperty)({ minimum: 0, maximum: 11 }),
|
|
104
|
+
(0, class_validator_1.IsInt)(),
|
|
105
|
+
(0, class_validator_1.Min)(0),
|
|
106
|
+
(0, class_validator_1.Max)(11),
|
|
107
|
+
__metadata("design:type", Number)
|
|
108
|
+
], DashboardWidgetDto.prototype, "x", void 0);
|
|
109
|
+
__decorate([
|
|
110
|
+
(0, swagger_1.ApiProperty)({ minimum: 1, maximum: 12 }),
|
|
111
|
+
(0, class_validator_1.IsInt)(),
|
|
112
|
+
(0, class_validator_1.Min)(1),
|
|
113
|
+
(0, class_validator_1.Max)(12),
|
|
114
|
+
__metadata("design:type", Number)
|
|
115
|
+
], DashboardWidgetDto.prototype, "w", void 0);
|
|
116
|
+
__decorate([
|
|
117
|
+
(0, swagger_1.ApiProperty)(),
|
|
118
|
+
(0, class_validator_1.IsInt)(),
|
|
119
|
+
(0, class_validator_1.Min)(0),
|
|
120
|
+
__metadata("design:type", Number)
|
|
121
|
+
], DashboardWidgetDto.prototype, "order", void 0);
|
|
122
|
+
__decorate([
|
|
123
|
+
(0, swagger_1.ApiPropertyOptional)({ description: 'Título opcional no painel' }),
|
|
124
|
+
(0, class_validator_1.IsOptional)(),
|
|
125
|
+
(0, class_validator_1.IsString)(),
|
|
126
|
+
(0, class_validator_1.MaxLength)(120),
|
|
127
|
+
__metadata("design:type", String)
|
|
128
|
+
], DashboardWidgetDto.prototype, "title", void 0);
|
|
129
|
+
class DashboardLayoutDto {
|
|
130
|
+
version;
|
|
131
|
+
widgets;
|
|
132
|
+
}
|
|
133
|
+
exports.DashboardLayoutDto = DashboardLayoutDto;
|
|
134
|
+
__decorate([
|
|
135
|
+
(0, swagger_1.ApiProperty)({ default: 1 }),
|
|
136
|
+
(0, class_validator_1.IsInt)(),
|
|
137
|
+
(0, class_validator_1.Min)(1),
|
|
138
|
+
(0, class_validator_1.Max)(1),
|
|
139
|
+
__metadata("design:type", Number)
|
|
140
|
+
], DashboardLayoutDto.prototype, "version", void 0);
|
|
141
|
+
__decorate([
|
|
142
|
+
(0, swagger_1.ApiProperty)({ type: [DashboardWidgetDto] }),
|
|
143
|
+
(0, class_validator_1.IsArray)(),
|
|
144
|
+
(0, class_validator_1.ArrayMaxSize)(80),
|
|
145
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
146
|
+
(0, class_transformer_1.Type)(() => DashboardWidgetDto),
|
|
147
|
+
__metadata("design:type", Array)
|
|
148
|
+
], DashboardLayoutDto.prototype, "widgets", void 0);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './panel-permission-keys';
|
|
2
|
+
export * from './create-access-level.dto';
|
|
3
|
+
export * from './update-access-level.dto';
|
|
4
|
+
export * from './access-permission-item.dto';
|
|
5
|
+
export * from './replace-access-permissions.dto';
|
|
6
|
+
export * from './panel-context-response.dto';
|
|
7
|
+
export * from './dashboard-layout.dto';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/panel-rbac/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./panel-permission-keys"), exports);
|
|
18
|
+
__exportStar(require("./create-access-level.dto"), exports);
|
|
19
|
+
__exportStar(require("./update-access-level.dto"), exports);
|
|
20
|
+
__exportStar(require("./access-permission-item.dto"), exports);
|
|
21
|
+
__exportStar(require("./replace-access-permissions.dto"), exports);
|
|
22
|
+
__exportStar(require("./panel-context-response.dto"), exports);
|
|
23
|
+
__exportStar(require("./dashboard-layout.dto"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PanelPermissionKey } from './panel-permission-keys';
|
|
2
|
+
import { DashboardLayoutDto } from './dashboard-layout.dto';
|
|
3
|
+
/**
|
|
4
|
+
* Resposta de GET /auth/me/panel-context (tenant-service).
|
|
5
|
+
*/
|
|
6
|
+
export declare class PanelContextResponseDto {
|
|
7
|
+
is_master: boolean;
|
|
8
|
+
access_level_id: string | null;
|
|
9
|
+
permissions: PanelPermissionKey[] | null;
|
|
10
|
+
dashboard_layout: DashboardLayoutDto | null;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=panel-context-response.dto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-context-response.dto.d.ts","sourceRoot":"","sources":["../../src/panel-rbac/panel-context-response.dto.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D;;GAEG;AACH,qBAAa,uBAAuB;IAElC,SAAS,EAAE,OAAO,CAAC;IAGnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAO/B,WAAW,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAC;IAOzC,gBAAgB,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC7C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
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.PanelContextResponseDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const dashboard_layout_dto_1 = require("./dashboard-layout.dto");
|
|
15
|
+
/**
|
|
16
|
+
* Resposta de GET /auth/me/panel-context (tenant-service).
|
|
17
|
+
*/
|
|
18
|
+
class PanelContextResponseDto {
|
|
19
|
+
is_master;
|
|
20
|
+
access_level_id;
|
|
21
|
+
permissions;
|
|
22
|
+
dashboard_layout;
|
|
23
|
+
}
|
|
24
|
+
exports.PanelContextResponseDto = PanelContextResponseDto;
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, swagger_1.ApiProperty)(),
|
|
27
|
+
__metadata("design:type", Boolean)
|
|
28
|
+
], PanelContextResponseDto.prototype, "is_master", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, swagger_1.ApiPropertyOptional)({ nullable: true }),
|
|
31
|
+
__metadata("design:type", Object)
|
|
32
|
+
], PanelContextResponseDto.prototype, "access_level_id", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
35
|
+
nullable: true,
|
|
36
|
+
description: 'null = master (todas as permissões); array = chaves canônicas',
|
|
37
|
+
type: [String],
|
|
38
|
+
}),
|
|
39
|
+
__metadata("design:type", Object)
|
|
40
|
+
], PanelContextResponseDto.prototype, "permissions", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
43
|
+
nullable: true,
|
|
44
|
+
description: 'Layout guardado para o nível; null no master ou sem layout.',
|
|
45
|
+
type: dashboard_layout_dto_1.DashboardLayoutDto,
|
|
46
|
+
}),
|
|
47
|
+
__metadata("design:type", Object)
|
|
48
|
+
], PanelContextResponseDto.prototype, "dashboard_layout", void 0);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chaves canônicas de permissão do painel administrativo (resource.action).
|
|
3
|
+
*/
|
|
4
|
+
export declare const PANEL_RESOURCE_ACTIONS: {
|
|
5
|
+
readonly dashboard: readonly ["view"];
|
|
6
|
+
readonly tenants: readonly ["view", "create", "update", "delete"];
|
|
7
|
+
readonly tenant_users: readonly ["view", "create", "update", "delete", "device_sessions_view", "device_sessions_revoke", "totp_clear"];
|
|
8
|
+
readonly tenant_units: readonly ["view", "create", "update", "delete"];
|
|
9
|
+
readonly tenant_billings: readonly ["view", "create", "update", "delete"];
|
|
10
|
+
readonly tenant_connections: readonly ["view", "update"];
|
|
11
|
+
readonly tenant_ai_tokens: readonly ["view", "update"];
|
|
12
|
+
readonly audit_logs: readonly ["view"];
|
|
13
|
+
readonly plans: readonly ["view", "create", "update"];
|
|
14
|
+
readonly configurations: readonly ["view", "update"];
|
|
15
|
+
readonly evogo_configs: readonly ["view", "create"];
|
|
16
|
+
readonly app_modules: readonly ["view", "update"];
|
|
17
|
+
readonly ai_tools: readonly ["view", "update"];
|
|
18
|
+
readonly admin_notifications: readonly ["push"];
|
|
19
|
+
readonly admin_users: readonly ["view", "create", "update", "delete"];
|
|
20
|
+
readonly access_levels: readonly ["view", "create", "update", "delete"];
|
|
21
|
+
readonly conversation: readonly ["execute"];
|
|
22
|
+
};
|
|
23
|
+
export type PanelResource = keyof typeof PANEL_RESOURCE_ACTIONS;
|
|
24
|
+
export type PanelAction<R extends PanelResource> = (typeof PANEL_RESOURCE_ACTIONS)[R][number];
|
|
25
|
+
export declare const PANEL_PERMISSION_KEYS: readonly string[];
|
|
26
|
+
export type PanelPermissionKey = (typeof PANEL_PERMISSION_KEYS)[number];
|
|
27
|
+
export declare function isPanelPermissionKey(value: string): value is PanelPermissionKey;
|
|
28
|
+
export declare function panelPermissionKey(resource: PanelResource, action: PanelAction<PanelResource>): PanelPermissionKey;
|
|
29
|
+
//# sourceMappingURL=panel-permission-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-permission-keys.d.ts","sourceRoot":"","sources":["../../src/panel-rbac/panel-permission-keys.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;CA0BzB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,sBAAsB,CAAC;AAEhE,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,aAAa,IAC7C,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAS7C,eAAO,MAAM,qBAAqB,EAAW,SAAS,MAAM,EAAE,CAAC;AAE/D,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,kBAAkB,CAE/E;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,WAAW,CAAC,aAAa,CAAC,GACjC,kBAAkB,CAEpB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PANEL_PERMISSION_KEYS = exports.PANEL_RESOURCE_ACTIONS = void 0;
|
|
4
|
+
exports.isPanelPermissionKey = isPanelPermissionKey;
|
|
5
|
+
exports.panelPermissionKey = panelPermissionKey;
|
|
6
|
+
/**
|
|
7
|
+
* Chaves canônicas de permissão do painel administrativo (resource.action).
|
|
8
|
+
*/
|
|
9
|
+
exports.PANEL_RESOURCE_ACTIONS = {
|
|
10
|
+
dashboard: ['view'],
|
|
11
|
+
tenants: ['view', 'create', 'update', 'delete'],
|
|
12
|
+
tenant_users: [
|
|
13
|
+
'view',
|
|
14
|
+
'create',
|
|
15
|
+
'update',
|
|
16
|
+
'delete',
|
|
17
|
+
'device_sessions_view',
|
|
18
|
+
'device_sessions_revoke',
|
|
19
|
+
'totp_clear',
|
|
20
|
+
],
|
|
21
|
+
tenant_units: ['view', 'create', 'update', 'delete'],
|
|
22
|
+
tenant_billings: ['view', 'create', 'update', 'delete'],
|
|
23
|
+
tenant_connections: ['view', 'update'],
|
|
24
|
+
tenant_ai_tokens: ['view', 'update'],
|
|
25
|
+
audit_logs: ['view'],
|
|
26
|
+
plans: ['view', 'create', 'update'],
|
|
27
|
+
configurations: ['view', 'update'],
|
|
28
|
+
evogo_configs: ['view', 'create'],
|
|
29
|
+
app_modules: ['view', 'update'],
|
|
30
|
+
ai_tools: ['view', 'update'],
|
|
31
|
+
admin_notifications: ['push'],
|
|
32
|
+
admin_users: ['view', 'create', 'update', 'delete'],
|
|
33
|
+
access_levels: ['view', 'create', 'update', 'delete'],
|
|
34
|
+
conversation: ['execute'],
|
|
35
|
+
};
|
|
36
|
+
const keys = [];
|
|
37
|
+
for (const [resource, actions] of Object.entries(exports.PANEL_RESOURCE_ACTIONS)) {
|
|
38
|
+
for (const action of actions) {
|
|
39
|
+
keys.push(`${resource}.${action}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.PANEL_PERMISSION_KEYS = keys;
|
|
43
|
+
function isPanelPermissionKey(value) {
|
|
44
|
+
return exports.PANEL_PERMISSION_KEYS.includes(value);
|
|
45
|
+
}
|
|
46
|
+
function panelPermissionKey(resource, action) {
|
|
47
|
+
return `${resource}.${action}`;
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-permission-keys.spec.d.ts","sourceRoot":"","sources":["../../src/panel-rbac/panel-permission-keys.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const panel_permission_keys_1 = require("./panel-permission-keys");
|
|
4
|
+
describe("panel-permission-keys", () => {
|
|
5
|
+
it("expõe chaves estáveis para cada recurso/ação", () => {
|
|
6
|
+
let expected = 0;
|
|
7
|
+
for (const [, actions] of Object.entries(panel_permission_keys_1.PANEL_RESOURCE_ACTIONS)) {
|
|
8
|
+
expected += actions.length;
|
|
9
|
+
}
|
|
10
|
+
expect(panel_permission_keys_1.PANEL_PERMISSION_KEYS.length).toBe(expected);
|
|
11
|
+
});
|
|
12
|
+
it("isPanelPermissionKey valida chaves canónicas", () => {
|
|
13
|
+
expect((0, panel_permission_keys_1.isPanelPermissionKey)("tenants.view")).toBe(true);
|
|
14
|
+
expect((0, panel_permission_keys_1.isPanelPermissionKey)("invalid.key")).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replace-access-permissions.dto.d.ts","sourceRoot":"","sources":["../../src/panel-rbac/replace-access-permissions.dto.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,qBAAa,2BAA2B;IAMtC,KAAK,EAAE,uBAAuB,EAAE,CAAC;CAClC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
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.ReplaceAccessPermissionsDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const class_transformer_1 = require("class-transformer");
|
|
15
|
+
const class_validator_1 = require("class-validator");
|
|
16
|
+
const access_permission_item_dto_1 = require("./access-permission-item.dto");
|
|
17
|
+
class ReplaceAccessPermissionsDto {
|
|
18
|
+
items;
|
|
19
|
+
}
|
|
20
|
+
exports.ReplaceAccessPermissionsDto = ReplaceAccessPermissionsDto;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, swagger_1.ApiProperty)({ type: [access_permission_item_dto_1.AccessPermissionItemDto] }),
|
|
23
|
+
(0, class_validator_1.IsArray)(),
|
|
24
|
+
(0, class_validator_1.ArrayMinSize)(0),
|
|
25
|
+
(0, class_validator_1.ValidateNested)({ each: true }),
|
|
26
|
+
(0, class_transformer_1.Type)(() => access_permission_item_dto_1.AccessPermissionItemDto),
|
|
27
|
+
__metadata("design:type", Array)
|
|
28
|
+
], ReplaceAccessPermissionsDto.prototype, "items", void 0);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DashboardLayoutDto } from './dashboard-layout.dto';
|
|
2
|
+
export declare class UpdateAccessLevelDto {
|
|
3
|
+
name?: string;
|
|
4
|
+
description?: string | null;
|
|
5
|
+
isActive?: boolean;
|
|
6
|
+
dashboardLayout?: DashboardLayoutDto | null;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=update-access-level.dto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-access-level.dto.d.ts","sourceRoot":"","sources":["../../src/panel-rbac/update-access-level.dto.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,qBAAa,oBAAoB;IAM/B,IAAI,CAAC,EAAE,MAAM,CAAC;IAMd,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAK5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IASnB,eAAe,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC7C"}
|
|
@@ -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.UpdateAccessLevelDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const class_transformer_1 = require("class-transformer");
|
|
15
|
+
const class_validator_1 = require("class-validator");
|
|
16
|
+
const dashboard_layout_dto_1 = require("./dashboard-layout.dto");
|
|
17
|
+
class UpdateAccessLevelDto {
|
|
18
|
+
name;
|
|
19
|
+
description;
|
|
20
|
+
isActive;
|
|
21
|
+
dashboardLayout;
|
|
22
|
+
}
|
|
23
|
+
exports.UpdateAccessLevelDto = UpdateAccessLevelDto;
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, swagger_1.ApiPropertyOptional)(),
|
|
26
|
+
(0, class_validator_1.IsOptional)(),
|
|
27
|
+
(0, class_validator_1.IsString)(),
|
|
28
|
+
(0, class_validator_1.MinLength)(1),
|
|
29
|
+
(0, class_validator_1.MaxLength)(120),
|
|
30
|
+
__metadata("design:type", String)
|
|
31
|
+
], UpdateAccessLevelDto.prototype, "name", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, swagger_1.ApiPropertyOptional)(),
|
|
34
|
+
(0, class_validator_1.IsOptional)(),
|
|
35
|
+
(0, class_validator_1.IsString)(),
|
|
36
|
+
(0, class_validator_1.MaxLength)(500),
|
|
37
|
+
__metadata("design:type", Object)
|
|
38
|
+
], UpdateAccessLevelDto.prototype, "description", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, swagger_1.ApiPropertyOptional)(),
|
|
41
|
+
(0, class_validator_1.IsOptional)(),
|
|
42
|
+
(0, class_validator_1.IsBoolean)(),
|
|
43
|
+
__metadata("design:type", Boolean)
|
|
44
|
+
], UpdateAccessLevelDto.prototype, "isActive", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
47
|
+
description: 'Layout do dashboard para utilizadores deste nível (master).',
|
|
48
|
+
type: dashboard_layout_dto_1.DashboardLayoutDto,
|
|
49
|
+
}),
|
|
50
|
+
(0, class_validator_1.IsOptional)(),
|
|
51
|
+
(0, class_validator_1.ValidateNested)(),
|
|
52
|
+
(0, class_transformer_1.Type)(() => dashboard_layout_dto_1.DashboardLayoutDto),
|
|
53
|
+
__metadata("design:type", Object)
|
|
54
|
+
], UpdateAccessLevelDto.prototype, "dashboardLayout", void 0);
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ApiProperty } from '@nestjs/swagger';
|
|
2
|
+
import { IsIn, IsString, MaxLength } from 'class-validator';
|
|
3
|
+
import { PANEL_RESOURCE_ACTIONS, type PanelResource } from './panel-permission-keys';
|
|
4
|
+
|
|
5
|
+
const RESOURCES = Object.keys(PANEL_RESOURCE_ACTIONS) as PanelResource[];
|
|
6
|
+
|
|
7
|
+
export class AccessPermissionItemDto {
|
|
8
|
+
@ApiProperty({ enum: RESOURCES })
|
|
9
|
+
@IsString()
|
|
10
|
+
@IsIn(RESOURCES)
|
|
11
|
+
resource: PanelResource;
|
|
12
|
+
|
|
13
|
+
@ApiProperty({
|
|
14
|
+
description: 'Ação permitida para o recurso',
|
|
15
|
+
example: 'view',
|
|
16
|
+
})
|
|
17
|
+
@IsString()
|
|
18
|
+
@MaxLength(80)
|
|
19
|
+
action: string;
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
|
+
import { IsBoolean, IsOptional, IsString, MaxLength, MinLength } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
export class CreateAccessLevelDto {
|
|
5
|
+
@IsString()
|
|
6
|
+
@MinLength(1)
|
|
7
|
+
@MaxLength(120)
|
|
8
|
+
name: string;
|
|
9
|
+
|
|
10
|
+
@ApiPropertyOptional()
|
|
11
|
+
@IsOptional()
|
|
12
|
+
@IsString()
|
|
13
|
+
@MaxLength(500)
|
|
14
|
+
description?: string;
|
|
15
|
+
|
|
16
|
+
@ApiPropertyOptional({ default: true })
|
|
17
|
+
@IsOptional()
|
|
18
|
+
@IsBoolean()
|
|
19
|
+
isActive?: boolean;
|
|
20
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
|
+
import { Type } from 'class-transformer';
|
|
3
|
+
import {
|
|
4
|
+
ArrayMaxSize,
|
|
5
|
+
IsArray,
|
|
6
|
+
IsIn,
|
|
7
|
+
IsInt,
|
|
8
|
+
IsOptional,
|
|
9
|
+
IsString,
|
|
10
|
+
IsUUID,
|
|
11
|
+
Max,
|
|
12
|
+
MaxLength,
|
|
13
|
+
Min,
|
|
14
|
+
ValidateNested,
|
|
15
|
+
} from 'class-validator';
|
|
16
|
+
|
|
17
|
+
/** Tipos de visualização permitidos no painel (determinísticos). */
|
|
18
|
+
export const DASHBOARD_CHART_TYPES = [
|
|
19
|
+
'stat',
|
|
20
|
+
'card',
|
|
21
|
+
'bar',
|
|
22
|
+
'line',
|
|
23
|
+
'area',
|
|
24
|
+
'pie',
|
|
25
|
+
'radial',
|
|
26
|
+
'table',
|
|
27
|
+
] as const;
|
|
28
|
+
|
|
29
|
+
export type DashboardChartType = (typeof DASHBOARD_CHART_TYPES)[number];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Módulos de dados agregados do dashboard (cada um mapeia a permissões e a fatia do summary).
|
|
33
|
+
* Manter alinhado ao `Frontend/.../lib/dashboard-data-modules.ts`.
|
|
34
|
+
*/
|
|
35
|
+
export const DASHBOARD_DATA_MODULE_KEYS = [
|
|
36
|
+
'overview.clients_total',
|
|
37
|
+
'overview.clients_active_inactive',
|
|
38
|
+
'overview.units_total',
|
|
39
|
+
'overview.revenue_totals',
|
|
40
|
+
'overview.revenue_growth',
|
|
41
|
+
'overview.invoice_counts',
|
|
42
|
+
'billing.revenue_by_status',
|
|
43
|
+
'billing.invoice_counts',
|
|
44
|
+
'billing.recent_invoices',
|
|
45
|
+
'billing.payment_links',
|
|
46
|
+
'tenants.client_list',
|
|
47
|
+
'tenants.plan_per_client',
|
|
48
|
+
'tenants.legal_term_policy',
|
|
49
|
+
'tenants.whatsapp_provider',
|
|
50
|
+
'tenants.scheduled_deletion',
|
|
51
|
+
'tenants.hostnames',
|
|
52
|
+
'tenants.storage_usage',
|
|
53
|
+
'limits.per_client',
|
|
54
|
+
'limits.session_policy',
|
|
55
|
+
'limits.extra_storage',
|
|
56
|
+
'plans.stats',
|
|
57
|
+
'plans.list',
|
|
58
|
+
'ia.tokens_per_tenant',
|
|
59
|
+
'ia.agents_per_tenant',
|
|
60
|
+
'ia.tool_policies',
|
|
61
|
+
'ia.models_availability',
|
|
62
|
+
'evolution.configs_summary',
|
|
63
|
+
'evolution.instances_totals',
|
|
64
|
+
'evolution.connection_state',
|
|
65
|
+
'global.platform_config',
|
|
66
|
+
'team.panel_admins',
|
|
67
|
+
'audit.recent_events',
|
|
68
|
+
'audit.outcome_counts',
|
|
69
|
+
'security.device_sessions',
|
|
70
|
+
'security.totp_status',
|
|
71
|
+
] as const;
|
|
72
|
+
|
|
73
|
+
export type DashboardDataModuleKey = (typeof DASHBOARD_DATA_MODULE_KEYS)[number];
|
|
74
|
+
|
|
75
|
+
export function isDashboardDataModuleKey(v: string): v is DashboardDataModuleKey {
|
|
76
|
+
return (DASHBOARD_DATA_MODULE_KEYS as readonly string[]).includes(v);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export class DashboardWidgetDto {
|
|
80
|
+
@ApiProperty({ format: 'uuid' })
|
|
81
|
+
@IsUUID('4')
|
|
82
|
+
id: string;
|
|
83
|
+
|
|
84
|
+
@ApiProperty({ enum: DASHBOARD_DATA_MODULE_KEYS })
|
|
85
|
+
@IsString()
|
|
86
|
+
@IsIn([...DASHBOARD_DATA_MODULE_KEYS])
|
|
87
|
+
dataModule: DashboardDataModuleKey;
|
|
88
|
+
|
|
89
|
+
@ApiProperty({ enum: DASHBOARD_CHART_TYPES })
|
|
90
|
+
@IsString()
|
|
91
|
+
@IsIn([...DASHBOARD_CHART_TYPES])
|
|
92
|
+
chartType: DashboardChartType;
|
|
93
|
+
|
|
94
|
+
/** Coluna inicial (grelha 12 colunas). */
|
|
95
|
+
@ApiProperty({ minimum: 0, maximum: 11 })
|
|
96
|
+
@IsInt()
|
|
97
|
+
@Min(0)
|
|
98
|
+
@Max(11)
|
|
99
|
+
x: number;
|
|
100
|
+
|
|
101
|
+
/** Largura em colunas (1–12). */
|
|
102
|
+
@ApiProperty({ minimum: 1, maximum: 12 })
|
|
103
|
+
@IsInt()
|
|
104
|
+
@Min(1)
|
|
105
|
+
@Max(12)
|
|
106
|
+
w: number;
|
|
107
|
+
|
|
108
|
+
/** Ordem de leitura (menor = primeiro). */
|
|
109
|
+
@ApiProperty()
|
|
110
|
+
@IsInt()
|
|
111
|
+
@Min(0)
|
|
112
|
+
order: number;
|
|
113
|
+
|
|
114
|
+
@ApiPropertyOptional({ description: 'Título opcional no painel' })
|
|
115
|
+
@IsOptional()
|
|
116
|
+
@IsString()
|
|
117
|
+
@MaxLength(120)
|
|
118
|
+
title?: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export class DashboardLayoutDto {
|
|
122
|
+
@ApiProperty({ default: 1 })
|
|
123
|
+
@IsInt()
|
|
124
|
+
@Min(1)
|
|
125
|
+
@Max(1)
|
|
126
|
+
version: number;
|
|
127
|
+
|
|
128
|
+
@ApiProperty({ type: [DashboardWidgetDto] })
|
|
129
|
+
@IsArray()
|
|
130
|
+
@ArrayMaxSize(80)
|
|
131
|
+
@ValidateNested({ each: true })
|
|
132
|
+
@Type(() => DashboardWidgetDto)
|
|
133
|
+
widgets: DashboardWidgetDto[];
|
|
134
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './panel-permission-keys';
|
|
2
|
+
export * from './create-access-level.dto';
|
|
3
|
+
export * from './update-access-level.dto';
|
|
4
|
+
export * from './access-permission-item.dto';
|
|
5
|
+
export * from './replace-access-permissions.dto';
|
|
6
|
+
export * from './panel-context-response.dto';
|
|
7
|
+
export * from './dashboard-layout.dto';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
|
+
import type { PanelPermissionKey } from './panel-permission-keys';
|
|
3
|
+
import { DashboardLayoutDto } from './dashboard-layout.dto';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resposta de GET /auth/me/panel-context (tenant-service).
|
|
7
|
+
*/
|
|
8
|
+
export class PanelContextResponseDto {
|
|
9
|
+
@ApiProperty()
|
|
10
|
+
is_master: boolean;
|
|
11
|
+
|
|
12
|
+
@ApiPropertyOptional({ nullable: true })
|
|
13
|
+
access_level_id: string | null;
|
|
14
|
+
|
|
15
|
+
@ApiPropertyOptional({
|
|
16
|
+
nullable: true,
|
|
17
|
+
description: 'null = master (todas as permissões); array = chaves canônicas',
|
|
18
|
+
type: [String],
|
|
19
|
+
})
|
|
20
|
+
permissions: PanelPermissionKey[] | null;
|
|
21
|
+
|
|
22
|
+
@ApiPropertyOptional({
|
|
23
|
+
nullable: true,
|
|
24
|
+
description: 'Layout guardado para o nível; null no master ou sem layout.',
|
|
25
|
+
type: DashboardLayoutDto,
|
|
26
|
+
})
|
|
27
|
+
dashboard_layout: DashboardLayoutDto | null;
|
|
28
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PANEL_PERMISSION_KEYS,
|
|
3
|
+
PANEL_RESOURCE_ACTIONS,
|
|
4
|
+
isPanelPermissionKey,
|
|
5
|
+
} from "./panel-permission-keys";
|
|
6
|
+
|
|
7
|
+
describe("panel-permission-keys", () => {
|
|
8
|
+
it("expõe chaves estáveis para cada recurso/ação", () => {
|
|
9
|
+
let expected = 0;
|
|
10
|
+
for (const [, actions] of Object.entries(PANEL_RESOURCE_ACTIONS)) {
|
|
11
|
+
expected += actions.length;
|
|
12
|
+
}
|
|
13
|
+
expect(PANEL_PERMISSION_KEYS.length).toBe(expected);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("isPanelPermissionKey valida chaves canónicas", () => {
|
|
17
|
+
expect(isPanelPermissionKey("tenants.view")).toBe(true);
|
|
18
|
+
expect(isPanelPermissionKey("invalid.key")).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chaves canônicas de permissão do painel administrativo (resource.action).
|
|
3
|
+
*/
|
|
4
|
+
export const PANEL_RESOURCE_ACTIONS = {
|
|
5
|
+
dashboard: ['view'] as const,
|
|
6
|
+
tenants: ['view', 'create', 'update', 'delete'] as const,
|
|
7
|
+
tenant_users: [
|
|
8
|
+
'view',
|
|
9
|
+
'create',
|
|
10
|
+
'update',
|
|
11
|
+
'delete',
|
|
12
|
+
'device_sessions_view',
|
|
13
|
+
'device_sessions_revoke',
|
|
14
|
+
'totp_clear',
|
|
15
|
+
] as const,
|
|
16
|
+
tenant_units: ['view', 'create', 'update', 'delete'] as const,
|
|
17
|
+
tenant_billings: ['view', 'create', 'update', 'delete'] as const,
|
|
18
|
+
tenant_connections: ['view', 'update'] as const,
|
|
19
|
+
tenant_ai_tokens: ['view', 'update'] as const,
|
|
20
|
+
audit_logs: ['view'] as const,
|
|
21
|
+
plans: ['view', 'create', 'update'] as const,
|
|
22
|
+
configurations: ['view', 'update'] as const,
|
|
23
|
+
evogo_configs: ['view', 'create'] as const,
|
|
24
|
+
app_modules: ['view', 'update'] as const,
|
|
25
|
+
ai_tools: ['view', 'update'] as const,
|
|
26
|
+
admin_notifications: ['push'] as const,
|
|
27
|
+
admin_users: ['view', 'create', 'update', 'delete'] as const,
|
|
28
|
+
access_levels: ['view', 'create', 'update', 'delete'] as const,
|
|
29
|
+
conversation: ['execute'] as const,
|
|
30
|
+
} as const;
|
|
31
|
+
|
|
32
|
+
export type PanelResource = keyof typeof PANEL_RESOURCE_ACTIONS;
|
|
33
|
+
|
|
34
|
+
export type PanelAction<R extends PanelResource> =
|
|
35
|
+
(typeof PANEL_RESOURCE_ACTIONS)[R][number];
|
|
36
|
+
|
|
37
|
+
const keys: string[] = [];
|
|
38
|
+
for (const [resource, actions] of Object.entries(PANEL_RESOURCE_ACTIONS)) {
|
|
39
|
+
for (const action of actions) {
|
|
40
|
+
keys.push(`${resource}.${action}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const PANEL_PERMISSION_KEYS = keys as readonly string[];
|
|
45
|
+
|
|
46
|
+
export type PanelPermissionKey = (typeof PANEL_PERMISSION_KEYS)[number];
|
|
47
|
+
|
|
48
|
+
export function isPanelPermissionKey(value: string): value is PanelPermissionKey {
|
|
49
|
+
return (PANEL_PERMISSION_KEYS as readonly string[]).includes(value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function panelPermissionKey(
|
|
53
|
+
resource: PanelResource,
|
|
54
|
+
action: PanelAction<PanelResource>,
|
|
55
|
+
): PanelPermissionKey {
|
|
56
|
+
return `${resource}.${action}` as PanelPermissionKey;
|
|
57
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ApiProperty } from '@nestjs/swagger';
|
|
2
|
+
import { Type } from 'class-transformer';
|
|
3
|
+
import { ArrayMinSize, IsArray, ValidateNested } from 'class-validator';
|
|
4
|
+
import { AccessPermissionItemDto } from './access-permission-item.dto';
|
|
5
|
+
|
|
6
|
+
export class ReplaceAccessPermissionsDto {
|
|
7
|
+
@ApiProperty({ type: [AccessPermissionItemDto] })
|
|
8
|
+
@IsArray()
|
|
9
|
+
@ArrayMinSize(0)
|
|
10
|
+
@ValidateNested({ each: true })
|
|
11
|
+
@Type(() => AccessPermissionItemDto)
|
|
12
|
+
items: AccessPermissionItemDto[];
|
|
13
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
|
+
import { Type } from 'class-transformer';
|
|
3
|
+
import {
|
|
4
|
+
IsBoolean,
|
|
5
|
+
IsOptional,
|
|
6
|
+
IsString,
|
|
7
|
+
MaxLength,
|
|
8
|
+
MinLength,
|
|
9
|
+
ValidateNested,
|
|
10
|
+
} from 'class-validator';
|
|
11
|
+
import { DashboardLayoutDto } from './dashboard-layout.dto';
|
|
12
|
+
|
|
13
|
+
export class UpdateAccessLevelDto {
|
|
14
|
+
@ApiPropertyOptional()
|
|
15
|
+
@IsOptional()
|
|
16
|
+
@IsString()
|
|
17
|
+
@MinLength(1)
|
|
18
|
+
@MaxLength(120)
|
|
19
|
+
name?: string;
|
|
20
|
+
|
|
21
|
+
@ApiPropertyOptional()
|
|
22
|
+
@IsOptional()
|
|
23
|
+
@IsString()
|
|
24
|
+
@MaxLength(500)
|
|
25
|
+
description?: string | null;
|
|
26
|
+
|
|
27
|
+
@ApiPropertyOptional()
|
|
28
|
+
@IsOptional()
|
|
29
|
+
@IsBoolean()
|
|
30
|
+
isActive?: boolean;
|
|
31
|
+
|
|
32
|
+
@ApiPropertyOptional({
|
|
33
|
+
description: 'Layout do dashboard para utilizadores deste nível (master).',
|
|
34
|
+
type: DashboardLayoutDto,
|
|
35
|
+
})
|
|
36
|
+
@IsOptional()
|
|
37
|
+
@ValidateNested()
|
|
38
|
+
@Type(() => DashboardLayoutDto)
|
|
39
|
+
dashboardLayout?: DashboardLayoutDto | null;
|
|
40
|
+
}
|