mirror of
https://github.com/dadosfera/maestro.git
synced 2026-11-14 22:29:08 +00:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c98a5ff896 | ||
|
|
d68e436a8b | ||
|
|
c18a7baa37 | ||
|
|
d638d518f8 | ||
|
|
bdd371ffe8 | ||
|
|
d478f32760 | ||
|
|
606bae016b | ||
|
|
6910a2f04c | ||
|
|
8bee1788c1 | ||
|
|
b10459cb15 |
+114
@@ -969,6 +969,41 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/users/download": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "UsersController_downloadUsersInCsv",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "dadosfera-lang",
|
||||||
|
"in": "header",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"enum": [
|
||||||
|
"pt-br",
|
||||||
|
"en-us"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"Users"
|
||||||
|
],
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"access-token": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"access-token": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/users/hierarchies": {
|
"/users/hierarchies": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "UsersController_getAllHierarchies",
|
"operationId": "UsersController_getAllHierarchies",
|
||||||
@@ -3874,6 +3909,85 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/catalog/download": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "CatalogController_dowloadAsserts",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "dadosfera-lang",
|
||||||
|
"in": "header",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"enum": [
|
||||||
|
"pt-br",
|
||||||
|
"en-us"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "size",
|
||||||
|
"required": false,
|
||||||
|
"in": "query",
|
||||||
|
"description": "Número de registros a ser retornado",
|
||||||
|
"schema": {
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 10000,
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "page",
|
||||||
|
"required": false,
|
||||||
|
"in": "query",
|
||||||
|
"description": "Usado para paginação, em conjunto com `size`",
|
||||||
|
"schema": {
|
||||||
|
"minimum": 1,
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sort_by",
|
||||||
|
"required": false,
|
||||||
|
"in": "query",
|
||||||
|
"description": "Campo do data asset para usar na ordenação. Padrão: `created_at` ",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "order",
|
||||||
|
"required": false,
|
||||||
|
"in": "query",
|
||||||
|
"description": "Tipo de ordenação - `asc`: crescente; `desc`: decrescente ",
|
||||||
|
"schema": {
|
||||||
|
"default": "asc",
|
||||||
|
"enum": [
|
||||||
|
"asc",
|
||||||
|
"desc"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"Catalog"
|
||||||
|
],
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"access-token": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"access-token": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/catalog/data-asset": {
|
"/catalog/data-asset": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "CatalogController_findByPipelineAndObject",
|
"operationId": "CatalogController_findByPipelineAndObject",
|
||||||
|
|||||||
+4
-4
@@ -23,7 +23,7 @@ charts:
|
|||||||
- name: replicaCount
|
- name: replicaCount
|
||||||
value: 2
|
value: 2
|
||||||
|
|
||||||
- name: unimed
|
- name: unimed-maestro
|
||||||
chart: ../maestro
|
chart: ../maestro
|
||||||
values:
|
values:
|
||||||
- ../maestro/values.yaml
|
- ../maestro/values.yaml
|
||||||
@@ -33,7 +33,7 @@ charts:
|
|||||||
- name: maestro.duc_url
|
- name: maestro.duc_url
|
||||||
value: duc.dadosfera.ai
|
value: duc.dadosfera.ai
|
||||||
- name: hostname
|
- name: hostname
|
||||||
value: maestro.dadosfera.ai
|
value: maestro-unimed.dadosfera.ai
|
||||||
- name: maestro.pi_factory_url
|
- name: maestro.pi_factory_url
|
||||||
value: pi-factory.dadosfera.ai
|
value: pi-factory.dadosfera.ai
|
||||||
- name: maestro.in_factory_url
|
- name: maestro.in_factory_url
|
||||||
@@ -49,5 +49,5 @@ charts:
|
|||||||
value: dea2c27f-0973-4588-a2e0-9e31b64c7ffd
|
value: dea2c27f-0973-4588-a2e0-9e31b64c7ffd
|
||||||
- name: replicaCount
|
- name: replicaCount
|
||||||
value: 1
|
value: 1
|
||||||
- name: restricted-ip
|
- name: maestro.restricted_ip
|
||||||
value: "177.52.172.0/24"
|
value: "177.52.172.0/24,57.151.113.140/30"
|
||||||
|
|||||||
@@ -117,6 +117,52 @@ export class CatalogController {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('/download')
|
||||||
|
@RequireSomePermission(
|
||||||
|
PERMISSIONS_GROUPS.CATALOG.permissions.GET,
|
||||||
|
PERMISSIONS_GROUPS.CATALOG.permissions.DATA_MANAGER,
|
||||||
|
)
|
||||||
|
async dowloadAsserts(
|
||||||
|
@User() user: RequestUser,
|
||||||
|
@Query() query: ICatalogAllRequest,
|
||||||
|
@Res() res: Response
|
||||||
|
) {
|
||||||
|
const { user_id, customer_name, customer_id, username, permissions } = user;
|
||||||
|
this.logger.info(`/catalog/download - searchCatalog`, {
|
||||||
|
user_id,
|
||||||
|
customer_name,
|
||||||
|
});
|
||||||
|
|
||||||
|
const is_data_manager = permissions.includes(
|
||||||
|
PERMISSIONS_GROUPS.CATALOG.permissions.DATA_MANAGER.seqid,
|
||||||
|
);
|
||||||
|
|
||||||
|
const roles = await this.catalogService.getUserRolesIds(user_id);
|
||||||
|
|
||||||
|
const metadata = PackTheMetadata({
|
||||||
|
user_id,
|
||||||
|
customer_id,
|
||||||
|
customer_name,
|
||||||
|
username,
|
||||||
|
roles,
|
||||||
|
is_data_manager,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
file,
|
||||||
|
filename
|
||||||
|
} = await this.catalogService.downloadAssets(
|
||||||
|
query,
|
||||||
|
metadata,
|
||||||
|
customer_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
|
||||||
|
res.setHeader('Content-Type', 'text/csv');
|
||||||
|
|
||||||
|
res.end(file);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiInternalOnlyEndpoint()
|
@ApiInternalOnlyEndpoint()
|
||||||
@Get('data-asset')
|
@Get('data-asset')
|
||||||
async findByPipelineAndObject(@User() user: RequestUser, @Query() query) {
|
async findByPipelineAndObject(@User() user: RequestUser, @Query() query) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { UsersService } from '../users/users.service';
|
|||||||
import { RolesService } from '../roles/roles.service';
|
import { RolesService } from '../roles/roles.service';
|
||||||
import { Metadata } from '@grpc/grpc-js';
|
import { Metadata } from '@grpc/grpc-js';
|
||||||
import {
|
import {
|
||||||
|
AssetReporter,
|
||||||
BatchRemoveRlsRulesRequest,
|
BatchRemoveRlsRulesRequest,
|
||||||
IUpdateDataRequest,
|
IUpdateDataRequest,
|
||||||
TriggerCatalogReq,
|
TriggerCatalogReq,
|
||||||
@@ -240,6 +241,34 @@ class CatalogService implements OnModuleInit {
|
|||||||
return { data_assets: response, total };
|
return { data_assets: response, total };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async downloadAssets(
|
||||||
|
query: Record<string, any>,
|
||||||
|
metadata: Metadata,
|
||||||
|
customer_id: string,
|
||||||
|
) {
|
||||||
|
const data = await this.searchDataAssets(query, metadata, customer_id);
|
||||||
|
|
||||||
|
const formatData = data.data_assets.map(asset => ({
|
||||||
|
id: asset.id,
|
||||||
|
display_name: asset.display_name,
|
||||||
|
data_asset_type: asset.data_asset_type,
|
||||||
|
created_at: asset.created_at,
|
||||||
|
tags: '[' + asset.tags.join(', ') + ']'
|
||||||
|
}))
|
||||||
|
|
||||||
|
const parser = ParserBuilder.build<AssetReporter>('csv');
|
||||||
|
|
||||||
|
const file = await parser.parse(formatData);
|
||||||
|
|
||||||
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||||
|
const filename = `dadosfera_assets_${timestamp}.csv`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
file,
|
||||||
|
filename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getOneDataAsset(data: {
|
async getOneDataAsset(data: {
|
||||||
id: string;
|
id: string;
|
||||||
customer_id: string;
|
customer_id: string;
|
||||||
|
|||||||
@@ -320,3 +320,11 @@ export class BatchRemoveRlsRulesRequest {
|
|||||||
@ApiPropertyOptional()
|
@ApiPropertyOptional()
|
||||||
id_rls?: string;
|
id_rls?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AssetReporter = {
|
||||||
|
id: string;
|
||||||
|
display_name: string;
|
||||||
|
data_asset_type: string;
|
||||||
|
created_at: string;
|
||||||
|
tags: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -174,3 +174,14 @@ export class GetAllDepartmentsRes {
|
|||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
departments: string[];
|
departments: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface UserReporter {
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
mfaStatus: string;
|
||||||
|
status: string;
|
||||||
|
lastLogin: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
Put,
|
Put,
|
||||||
Query,
|
Query,
|
||||||
|
Res,
|
||||||
UseFilters,
|
UseFilters,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import {
|
import {
|
||||||
@@ -24,6 +25,7 @@ import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum';
|
|||||||
import {
|
import {
|
||||||
Authenticated,
|
Authenticated,
|
||||||
RequireAllPermissions,
|
RequireAllPermissions,
|
||||||
|
RequireSomePermission,
|
||||||
} from 'src/decorators/authentication.decorator';
|
} from 'src/decorators/authentication.decorator';
|
||||||
import { Language } from 'src/decorators/language.decorator';
|
import { Language } from 'src/decorators/language.decorator';
|
||||||
import { ApiInternalOnlyController } from 'src/decorators/swagger.decorator';
|
import { ApiInternalOnlyController } from 'src/decorators/swagger.decorator';
|
||||||
@@ -52,6 +54,7 @@ import {
|
|||||||
UpdateUserRes,
|
UpdateUserRes,
|
||||||
} from './dtos/entities';
|
} from './dtos/entities';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
|
import { Response } from 'express';
|
||||||
|
|
||||||
@ApiInternalOnlyController()
|
@ApiInternalOnlyController()
|
||||||
@ApiTags('Users')
|
@ApiTags('Users')
|
||||||
@@ -80,6 +83,26 @@ export class UsersController {
|
|||||||
return await this.userService.findAllUsersByCustomerId(user.customer_id);
|
return await this.userService.findAllUsersByCustomerId(user.customer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('/download')
|
||||||
|
@RequireSomePermission(PERMISSIONS_GROUPS.USERS.permissions.ADMIN)
|
||||||
|
async downloadUsersInCsv(
|
||||||
|
@User() user: RequestUser,
|
||||||
|
@Language() language: LanguageEnum,
|
||||||
|
@Res() res: Response
|
||||||
|
) {
|
||||||
|
this.logger.info('downloadUsersInCsv');
|
||||||
|
this.userService.setLanguage(language);
|
||||||
|
const {
|
||||||
|
file,
|
||||||
|
filename
|
||||||
|
} = await this.userService.downloadUsersInCsv(user.customer_id);
|
||||||
|
|
||||||
|
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
|
||||||
|
res.setHeader('Content-Type', 'text/csv');
|
||||||
|
|
||||||
|
res.end(file);
|
||||||
|
}
|
||||||
|
|
||||||
@Get('hierarchies')
|
@Get('hierarchies')
|
||||||
@RequireAllPermissions(PERMISSIONS_GROUPS.USERS.permissions.ADMIN)
|
@RequireAllPermissions(PERMISSIONS_GROUPS.USERS.permissions.ADMIN)
|
||||||
@ApiOkResponse({ type: GetAllHierarchiesRes })
|
@ApiOkResponse({ type: GetAllHierarchiesRes })
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
IUserByCustomer,
|
IUserByCustomer,
|
||||||
SetUserRolesReq,
|
SetUserRolesReq,
|
||||||
UpdateUserReq,
|
UpdateUserReq,
|
||||||
|
UserReporter,
|
||||||
} from './dtos/entities';
|
} from './dtos/entities';
|
||||||
import { RolesService } from '../roles/roles.service';
|
import { RolesService } from '../roles/roles.service';
|
||||||
import { HIERARCHIES } from './hierarchies';
|
import { HIERARCHIES } from './hierarchies';
|
||||||
@@ -29,6 +30,7 @@ import { UserByCustomer } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces
|
|||||||
import { EnrichErrorCode } from 'src/utils/ErrorBuilder';
|
import { EnrichErrorCode } from 'src/utils/ErrorBuilder';
|
||||||
import { DucClient } from '../duc/client.config';
|
import { DucClient } from '../duc/client.config';
|
||||||
import { Metadata } from '@grpc/grpc-js';
|
import { Metadata } from '@grpc/grpc-js';
|
||||||
|
import { ParserBuilder } from 'src/utils/FileParser/parser.builder';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsersService implements OnModuleInit {
|
export class UsersService implements OnModuleInit {
|
||||||
@@ -78,6 +80,34 @@ export class UsersService implements OnModuleInit {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async downloadUsersInCsv(customerId: string) {
|
||||||
|
const { users } = await lastValueFrom(
|
||||||
|
this.usersClientService.UserFindAllByCustomerId({ customerId }),
|
||||||
|
);
|
||||||
|
|
||||||
|
const formatUsers: UserReporter[] = users.map(user => ({
|
||||||
|
createdAt: user.createdAt,
|
||||||
|
email: user.email,
|
||||||
|
lastLogin: user.lastLogin,
|
||||||
|
mfaStatus: user.mfaStatus,
|
||||||
|
name: user.name,
|
||||||
|
status: user.status,
|
||||||
|
updatedAt: user.updatedAt
|
||||||
|
}))
|
||||||
|
|
||||||
|
const parser = ParserBuilder.build<UserReporter>('csv');
|
||||||
|
|
||||||
|
const file = await parser.parse(formatUsers);
|
||||||
|
|
||||||
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||||
|
const filename = `dadosfera_users_${timestamp}.csv`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
file,
|
||||||
|
filename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async findOneById(id: string): Promise<{ user: IUserByCustomer }> {
|
async findOneById(id: string): Promise<{ user: IUserByCustomer }> {
|
||||||
const { user } = await lastValueFrom(
|
const { user } = await lastValueFrom(
|
||||||
this.usersClientService.UserFindOneById({ id }),
|
this.usersClientService.UserFindOneById({ id }),
|
||||||
|
|||||||
Reference in New Issue
Block a user