diff --git a/.github/workflows/deploy-k8s.yml b/.github/workflows/deploy-k8s.yml new file mode 100644 index 0000000..f547ac4 --- /dev/null +++ b/.github/workflows/deploy-k8s.yml @@ -0,0 +1,73 @@ +name: Deploy K8S Modifications + +on: + push: + branches: + - main + - beta + +jobs: + extract_environment: + runs-on: ubuntu-22.04 + outputs: + environment: ${{ steps.extract_environment.outputs.environment }} + steps: + - name: Extract Environment + run: | + if [ ${GITHUB_REF} == "refs/heads/main" ]; then + echo "environment=prd" >> $GITHUB_OUTPUT + elif [ ${GITHUB_REF} == "refs/heads/beta" ]; then + echo "environment=stg" >> $GITHUB_OUTPUT + fi + id: extract_environment + + helmfile-deploy: + needs: [extract_environment] + runs-on: [self-hosted, "prd-azure"] + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Helm + uses: azure/setup-helm@v1 + with: + version: 'v3.9.0' + + - name: Install Azure ClI + run: | + curl -sL https://aka.ms/InstallAzureCLIDeb | bash + + - uses: azure/login@v2 + with: + creds: '{"clientId":"${{ secrets.ARM_CLIENT_ID }}","clientSecret":"${{ secrets.ARM_CLIENT_SECRET }}","subscriptionId":"${{ secrets.ARM_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.ARM_TENANT_ID }}"}' + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.8' + + - name: Install Helmfile + run: | + wget https://github.com/helmfile/helmfile/releases/download/v0.148.0/helmfile_0.148.0_linux_amd64.tar.gz + tar -xzf helmfile_0.148.0_linux_amd64.tar.gz + mv helmfile /usr/local/bin/ + helmfile --version + + - name: Install Helm Diff Plugin + run: helm plugin install https://github.com/databus23/helm-diff || true + + - name: Setup kubectl + uses: azure/setup-kubectl@v1 + with: + version: 'v1.30.1' + + - name: Authenticate with cluster + env: + CLUSTER_NAME: platform-${{ needs.extract_environment.outputs.environment }} + run: az aks get-credentials --resource-group dadosfera-prd --name ${CLUSTER_NAME} --overwrite-existing + + - name: Run Helmfile Apply + env: + ENV: ${{ needs.extract_environment.outputs.environment }} + run: helmfile -f helmfiles/${ENV}.yaml sync diff --git a/README.md b/README.md index bb50d3a..028ca81 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@

- # Maestro Maestro é a API principal da Dadosfera. É responsável pela comunicação do Frontend com nossos microsserviços. diff --git a/docsfera.json b/docsfera.json index 33988d7..0922da4 100644 --- a/docsfera.json +++ b/docsfera.json @@ -5431,117 +5431,6 @@ ] } }, - "/open-data/sharing-ocean-data": { - "post": { - "operationId": "OpenDataController_createUser", - "parameters": [ - { - "name": "dadosfera-lang", - "in": "header", - "required": false, - "schema": { - "enum": [ - "pt-br", - "en-us" - ], - "type": "string" - } - }, - { - "name": "language", - "required": true, - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "" - } - }, - "tags": [ - "OpenData" - ] - } - }, - "/customers/{id}/theme": { - "post": { - "operationId": "ThemeController_saveCustomertheme", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CustomerThemeRequest" - } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CustomerThemeResponse" - } - } - } - } - }, - "tags": [ - "Theme" - ], - "security": [ - { - "access-token": [] - }, - { - "access-token": [] - } - ] - }, - "get": { - "operationId": "ThemeController_getCustomerTheme", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CustomerThemeResponse" - } - } - } - } - }, - "tags": [ - "Theme" - ] - } - }, "/health": { "get": { "operationId": "HealthController_check", @@ -5619,9 +5508,6 @@ "items": { "type": "string" } - }, - "themeEnabled": { - "type": "boolean" } }, "required": [ @@ -5630,8 +5516,7 @@ "name", "tier", "scheduleLimit", - "links", - "themeEnabled" + "links" ] }, "AuthUser": { @@ -8349,61 +8234,8 @@ "required": [ "links" ] - }, - "CustomerThemeRequest": { - "type": "object", - "properties": { - "displayName": { - "type": "string" - }, - "backgroundColor": { - "type": "string" - }, - "textColor": { - "type": "string" - } - }, - "required": [ - "displayName", - "backgroundColor", - "textColor" - ] - }, - "CustomerTheme": { - "type": "object", - "properties": { - "backgroundColor": { - "type": "string" - }, - "textColor": { - "type": "string" - }, - "logo": { - "type": "string" - }, - "logoLogin": { - "type": "string" - } - }, - "required": [ - "backgroundColor", - "textColor", - "logo", - "logoLogin" - ] - }, - "CustomerThemeResponse": { - "type": "object", - "properties": { - "theme": { - "$ref": "#/components/schemas/CustomerTheme" - } - }, - "required": [ - "theme" - ] } } } } -} \ No newline at end of file +} diff --git a/environment.d.ts b/environment.d.ts index c910516..727c484 100644 --- a/environment.d.ts +++ b/environment.d.ts @@ -12,8 +12,6 @@ declare global { INTERNAL_SWAGGER: 'true' | 'false'; AWS_REGION: string; - OPEN_GROUP_ID: string; - OPEN_CUSTOMER_ID: string; } } } diff --git a/helmfiles/prd.yaml b/helmfiles/prd.yaml index 344cb88..8076b3b 100644 --- a/helmfiles/prd.yaml +++ b/helmfiles/prd.yaml @@ -13,8 +13,4 @@ charts: - name: maestro.in_factory_url value: in-factory.dadosfera.ai - name: maestro.tr_factory_url - value: in-factory.dadosfera.ai - - name: maestro.open_customer_id - value: f239718a-a271-4ef9-ae7e-02a2f0f3aa6e - - name: maestro.open_group_id - value: 401573bb-334f-44b2-b30e-88d4cea31ae9 \ No newline at end of file + value: in-factory.dadosfera.ai \ No newline at end of file diff --git a/helmfiles/stg.yaml b/helmfiles/stg.yaml index 263570f..eb1fc69 100644 --- a/helmfiles/stg.yaml +++ b/helmfiles/stg.yaml @@ -5,18 +5,12 @@ charts: - ../maestro/values.yaml set: - name: maestro.duc_url - value: duc.stg.dadosfera.ai + value: duc-temp.dadosfera.ai - name: hostname - value: maestro.stg.dadosfera.ai + value: maestro-temp.dadosfera.ai - name: maestro.pi_factory_url - value: pi-factory.dadosfera.ai + value: pi-factory-temp.dadosfera.ai - name: maestro.in_factory_url - value: in-factory.dadosfera.ai + value: in-factory-temp.dadosfera.ai - name: maestro.tr_factory_url - value: in-factory.dadosfera.ai - - name: maestro.open_customer_id - value: b3e3dfe5-b992-4586-a73c-c0b0c00f615d - - name: maestro.open_group_id - value: e3f98a2f-7748-4981-8505-7695c8ca8218 - - name: replicaCount - value: 1 \ No newline at end of file + value: in-factory-temp.dadosfera.ai \ No newline at end of file diff --git a/maestro/templates/deployment.yaml b/maestro/templates/deployment.yaml index 74a7a5c..18fad50 100644 --- a/maestro/templates/deployment.yaml +++ b/maestro/templates/deployment.yaml @@ -36,11 +36,6 @@ spec: operator: In values: - backend - tolerations: - - key: "kubernetes.azure.com/scalesetpriority" - operator: "Equal" - value: "spot" - effect: "NoSchedule" containers: - name: maestro @@ -95,10 +90,6 @@ spec: value: {{ .Values.maestro.tr_factory_url }} - name: UPLOAD_FILE_AGENT_CONNECTION value: {{ .Values.maestro.upload_file_agent_connection }} - - name: OPEN_CUSTOMER_ID - value: {{ .Values.maestro.open_customer_id }} - - name: OPEN_GROUP_ID - value: {{ .Values.maestro.open_group_id }} - name: JWT_PRIVATE_KEY valueFrom: secretKeyRef: diff --git a/maestro/values.yaml b/maestro/values.yaml index 070c533..a8d745c 100644 --- a/maestro/values.yaml +++ b/maestro/values.yaml @@ -40,8 +40,7 @@ maestro: sm_oauth_path: prd/root/oauth_applications tr_factory_url: in-factory.dadosfera.ai upload_file_agent_connection: cbc2f881-58c4-4d60-8003-0979b0b5b911 - open_customer_id: f239718a-a271-4ef9-ae7e-02a2f0f3aa6e - open_group_id: 401573bb-334f-44b2-b30e-88d4cea31ae9 + autoscaling: enabled: false minReplicas: 1 diff --git a/package-lock.json b/package-lock.json index 9539649..61c7a9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@aws-sdk/client-secrets-manager": "^3.414.0", "@dadosfera/dadosfera-logs": "^1.0.0-beta.4", "@dadosfera/protospack": "2.5.3", - "@dadosfera/protospack-v2": "3.37.0-beta.5", + "@dadosfera/protospack-v2": "3.34.0", "@grpc/grpc-js": "^1.9.3", "@grpc/proto-loader": "^0.7.9", "@nestjs/cli": "^9.5.0", @@ -53,7 +53,7 @@ "@types/jest": "27.0.2", "@types/jsonwebtoken": "^8.5.9", "@types/jwk-to-pem": "^2.0.1", - "@types/multer": "^1.4.12", + "@types/multer": "^1.4.7", "@types/node": "^16.18.52", "@types/passport-facebook": "^2.1.11", "@types/passport-google-oauth20": "^2.0.11", @@ -1403,10 +1403,9 @@ } }, "node_modules/@dadosfera/protospack-v2": { - "version": "3.37.0-beta.5", - "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.37.0-beta.5.tgz", - "integrity": "sha512-dtHMzMU2Qa9c6DpygWr7fib19l1zqbYgBi2wGkiJ6uMAvl1CGu9V0p+JA1FwGTQ0QRy7EkkRVi6X6sH5u/ICpA==", - "license": "ISC", + "version": "3.34.0", + "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com/npm/dadosfera-npm/@dadosfera/protospack-v2/-/protospack-v2-3.34.0.tgz", + "integrity": "sha512-VUjpoHg5/uNNkg1cTxWbUv+20t5CTAf1tB4dhBmGSYjgb+Efo5gi3aO/p3ajYuzOOMOxF+EhjQVouU6BD3E+Xg==", "dependencies": { "@grpc/grpc-js": "^1.9.3", "rxjs": "^7.5.5" @@ -3527,11 +3526,10 @@ "dev": true }, "node_modules/@types/multer": { - "version": "1.4.12", - "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.12.tgz", - "integrity": "sha512-pQ2hoqvXiJt2FP9WQVLPRO+AmiIm/ZYkavPlIQnx282u4ZrVdztx0pkh3jjpQt0Kz+YI0YhSG264y08UJKoUQg==", + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", + "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", "dev": true, - "license": "MIT", "dependencies": { "@types/express": "*" } diff --git a/package.json b/package.json index 072bfb6..fbe7eea 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@aws-sdk/client-secrets-manager": "^3.414.0", "@dadosfera/dadosfera-logs": "^1.0.0-beta.4", "@dadosfera/protospack": "2.5.3", - "@dadosfera/protospack-v2": "3.37.0-beta.5", + "@dadosfera/protospack-v2": "3.34.0", "@grpc/grpc-js": "^1.9.3", "@grpc/proto-loader": "^0.7.9", "@nestjs/cli": "^9.5.0", @@ -74,7 +74,7 @@ "@types/jest": "27.0.2", "@types/jsonwebtoken": "^8.5.9", "@types/jwk-to-pem": "^2.0.1", - "@types/multer": "^1.4.12", + "@types/multer": "^1.4.7", "@types/node": "^16.18.52", "@types/passport-facebook": "^2.1.11", "@types/passport-google-oauth20": "^2.0.11", diff --git a/src/app.module.ts b/src/app.module.ts index 3e54fde..fa831fd 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -26,10 +26,9 @@ import { PipelinesV2Module } from './modules/pipelinesV2/pipelines.module'; import { ProductboardModule } from './modules/productboard/productboard.module'; import { MixpanelModule } from './modules/mixpanel/mixpanel.module'; import { CustomersModule } from './modules/customers/customers.module'; -import { OpenDataModule } from './modules/open-data/open-data.module'; -import { ThemeModule } from './modules/theme/theme.module'; @Module({ + controllers: [], providers: [ DadosferaLogger, { @@ -59,10 +58,8 @@ import { ThemeModule } from './modules/theme/theme.module'; ProductboardModule, MixpanelModule, CustomersModule, - OpenDataModule, - ThemeModule, //Always leave HealthModule last, so it is on the bottom of swagger - HealthModule + HealthModule, ], }) export class AppModule {} diff --git a/src/modules/auth/dtos/login.ts b/src/modules/auth/dtos/login.ts index 6e87606..33a779b 100644 --- a/src/modules/auth/dtos/login.ts +++ b/src/modules/auth/dtos/login.ts @@ -77,8 +77,6 @@ export class AuthCustomer { scheduleLimit: string; @ApiProperty() links: Link[]; - @ApiProperty() - themeEnabled: boolean; } export class AuthSignInReq implements AuthSignInRequest { diff --git a/src/modules/customers/customers.controller.ts b/src/modules/customers/customers.controller.ts index 1bd9835..04073ec 100644 --- a/src/modules/customers/customers.controller.ts +++ b/src/modules/customers/customers.controller.ts @@ -1,4 +1,5 @@ import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; +import { IdResponse } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages'; import { Body, Controller, @@ -17,6 +18,7 @@ import { Authenticated, RequireAllPermissions, } from 'src/decorators/authentication.decorator'; +import { ApiInternalOnlyEndpoint } from 'src/decorators/swagger.decorator'; import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; import { CustomersService } from './customers.service'; import { CustomerLinkRequest, CustomerLinksResponse } from './dtos/customers'; @@ -26,6 +28,7 @@ import { PackTheMetadata } from 'src/utils/ PackTheMetadata'; @ApiTags('Customers') @Controller('customers') +@Authenticated() @UseFilters(GrpcToHttpExceptionFilter) export class CustomersController { logger: DadosferaLogger; @@ -39,7 +42,6 @@ export class CustomersController { } @Get(':id/links') - @Authenticated() @ApiOkResponse({ type: CustomerLinksResponse }) async getCustomerLinks(@Param('id') id: string) { this.logger.info('getCustomerLinks', { id }); @@ -48,7 +50,6 @@ export class CustomersController { } @Put(':id/links') - @Authenticated() @RequireAllPermissions(PERMISSIONS_GROUPS.USERS.permissions.ADMIN) @ApiOkResponse() @HttpCode(HttpStatus.OK) @@ -62,7 +63,6 @@ export class CustomersController { } @Get('token') - @Authenticated() @RequireAllPermissions(PERMISSIONS_GROUPS.AUTH.permissions.GENERATE_TOKEN) @ApiProduces('text/plain') async getCustomerToken( @@ -79,7 +79,6 @@ export class CustomersController { } @Get('monitoring-dashboard') - @Authenticated() @RequireAllPermissions( PERMISSIONS_GROUPS.CUSTOMER.permissions.MONITORING_DASHBOARD, ) diff --git a/src/modules/customers/customers.service.ts b/src/modules/customers/customers.service.ts index cd7f472..5102db5 100644 --- a/src/modules/customers/customers.service.ts +++ b/src/modules/customers/customers.service.ts @@ -28,24 +28,19 @@ import { } from '@dadosfera/protospack-v2/dist/lib/PipelineV2'; import { Metadata } from '@grpc/grpc-js'; import { PipelinesClientConfiguration } from '../pipelinesV2/pipelines-client'; -import DadosferaLogger from '@dadosfera/dadosfera-logs'; // This function will accept any string, which may result in a bug. @Injectable() export class CustomersService implements OnModuleInit { private customerService: CustomersProtoService; - private logger: DadosferaLogger; + private pipelineReadService: ReadService.PipelineV2ReadService; constructor( @Inject(DucClient.name) private readonly grpcClient: ClientGrpc, @Inject(PipelinesClientConfiguration.name) private readonly pipelinesGrpcClient: ClientGrpc, - @Inject(DadosferaLogger) - dadosferaLogger: DadosferaLogger, - ) { - this.logger = dadosferaLogger.logger; - } + ) {} onModuleInit() { this.customerService = this.grpcClient.getService( diff --git a/src/modules/customers/dtos/customers.ts b/src/modules/customers/dtos/customers.ts index db56ee3..c3b3070 100644 --- a/src/modules/customers/dtos/customers.ts +++ b/src/modules/customers/dtos/customers.ts @@ -20,4 +20,3 @@ export class CustomerLinksResponse { @ApiProperty({ type: [CustomerLink] }) links: CustomerLink[]; } - diff --git a/src/modules/duc/client.config.ts b/src/modules/duc/client.config.ts index 4cf4124..25ce28b 100644 --- a/src/modules/duc/client.config.ts +++ b/src/modules/duc/client.config.ts @@ -29,8 +29,6 @@ export class DucClient { objects: true, arrays: true, }, - maxSendMessageLength: 15 * 1024 * 1024, // 15 MB por mensagem - maxReceiveMessageLength: 15 * 1024 * 1024, }, }; diff --git a/src/modules/open-data/dto/wordpres-form.ts b/src/modules/open-data/dto/wordpres-form.ts deleted file mode 100644 index 39b6ed7..0000000 --- a/src/modules/open-data/dto/wordpres-form.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; - -export class CreateUserOpenDataDTO { - @ApiProperty() - firstName: string; - @ApiProperty() - lastName: string; - @ApiProperty() - email: string; - @ApiProperty() - organization: string; - @ApiProperty() - enquiryType: string; -} - -type FormField = { - id: string; - type: string; - title: string; - value: string; - raw_value: string; - required: string; -}; - -type MetaData = { - title: string; - value: string; -}; - -export type WordpressForm = { - form: { - id: string; - name: string; - }; - fields: { - [key: string]: FormField; - }; - meta: { - date: MetaData; - time: MetaData; - page_url: MetaData; - user_agent: MetaData; - remote_ip: MetaData; - credit: MetaData; - }; -}; - - diff --git a/src/modules/open-data/open-data.controller.ts b/src/modules/open-data/open-data.controller.ts deleted file mode 100644 index b999060..0000000 --- a/src/modules/open-data/open-data.controller.ts +++ /dev/null @@ -1,98 +0,0 @@ -import DadosferaLogger from '@dadosfera/dadosfera-logs'; -import { Body, Controller, ForbiddenException, Header, HttpCode, Inject, Param, Post, Query, Req, UseFilters, UseGuards, UseInterceptors } from '@nestjs/common'; -import { ApiCreatedResponse, ApiHeaders, ApiOkResponse, ApiTags } from '@nestjs/swagger'; -import { ApiInternalOnlyController } from 'src/decorators/swagger.decorator'; -import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; -import { LanguageEnum } from 'src/utils/languages.enum'; -import { UsersService } from '../users/users.service'; -import { Language } from 'src/decorators/language.decorator'; -import { OpenDataService } from './open-data.service'; -import { CreateUserOpenDataDTO, WordpressForm } from './dto/wordpres-form'; -import { Metadata } from '@grpc/grpc-js'; -import { PackTheMetadata } from 'src/utils/ PackTheMetadata'; -import { request } from 'http'; -import { Request } from 'express'; - -@Controller('open-data') -@ApiInternalOnlyController() -@ApiTags('OpenData') -@ApiHeaders([{ name: 'dadosfera-lang', enum: LanguageEnum, required: false }]) -@UseFilters(GrpcToHttpExceptionFilter) -export class OpenDataController { - logger: DadosferaLogger; - - constructor( - @Inject(DadosferaLogger) - dadosferaLogger: DadosferaLogger, - private openDataService: OpenDataService, - ) { - this.logger = dadosferaLogger.logger; - } - - @Post("/sharing-ocean-data") - @HttpCode(200) - @Header('content-type', 'application/json') - @ApiOkResponse() - async createUser( - @Body() - body: WordpressForm, - @Query('language') - language: string, - @Req() - request: Request, - ) { - if (!request.headers['user-agent'].includes('WordPress/6.7.1; https://devsbm.dadosfera.io')) { - throw new ForbiddenException(); - } - this.logger.info('createUser for open data'); - - this.logger.info('user-agent', request.headers['user-agent']); - - const OPENDATA_CUSTOMER_ID = process.env.OPEN_CUSTOMER_ID; - const OPENDATA_GROUP_ID = process.env.OPEN_GROUP_ID; - const roles = [process.env.OPEN_GROUP_ID]; - const metadata = PackTheMetadata({ - language: language || 'en-us' - }); - - const data = {} - - try { - Object.keys(body.fields) - .filter(key => body.fields[key].required === "1") - .forEach(key => { - const field = body.fields[key] - data[field.id] = field.value - }); - } catch (e) { - this.logger.error('user data ' + e.message); - } - - const user: CreateUserOpenDataDTO = { - email: data["email"], - enquiryType: data["enquiry_type"], - firstName: data["first_name"], - lastName: data["last_name"], - organization: data["organization"] - } - this.logger.info(`user request to group ${OPENDATA_CUSTOMER_ID} with role ${OPENDATA_GROUP_ID}`); - - try { - const id = await this.openDataService.createUser(OPENDATA_CUSTOMER_ID, user, roles, metadata); - this.logger.info('user created with id: '+ id); - return { - success: true, - status: 'success', - message: 'user created with succesfull' - } - } catch (e) { - this.logger.error('failed with exception: ' + e.message); - return { - success: false, - status: 'failed', - message: e.message - }; - } - } - -} diff --git a/src/modules/open-data/open-data.module.ts b/src/modules/open-data/open-data.module.ts deleted file mode 100644 index f82b125..0000000 --- a/src/modules/open-data/open-data.module.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Module } from '@nestjs/common'; -import { OpenDataController } from './open-data.controller'; -import { UsersService } from '../users/users.service'; -import { ClientsModule } from '@nestjs/microservices' -import { DucClient } from '../duc/client.config'; -import DadosferaLogger from '@dadosfera/dadosfera-logs'; -import { RolesModule } from '../roles/roles.module'; -import { PermissionsModule } from '../permissions/permissions.module'; -import { OpenDataService } from './open-data.service'; - -const client = new DucClient(); - -@Module({ - controllers: [OpenDataController], - imports: [ - ClientsModule.register([client.providerOptions]), - RolesModule, - // PermissionsModule, - ], - providers: [DadosferaLogger, UsersService, OpenDataService] -}) -export class OpenDataModule {} diff --git a/src/modules/open-data/open-data.service.ts b/src/modules/open-data/open-data.service.ts deleted file mode 100644 index 4c927fa..0000000 --- a/src/modules/open-data/open-data.service.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Inject, Injectable, OnModuleInit } from '@nestjs/common'; -import { lastValueFrom } from 'rxjs'; -import { CreateUserOpenDataDTO } from './dto/wordpres-form'; -import DadosferaLogger from '@dadosfera/dadosfera-logs'; -import { UsersProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service'; -import { DucClient } from '../duc/client.config'; -import { ClientGrpc } from '@nestjs/microservices'; -import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc'; -import { Metadata } from '@grpc/grpc-js'; - -@Injectable() -export class OpenDataService implements OnModuleInit { - logger: DadosferaLogger; - - private usersClientService: UsersProtoService; - constructor( - @Inject(DadosferaLogger) - private dadosferaLogger: DadosferaLogger, - @Inject(DucClient.name) - private readonly grpcClient: ClientGrpc, - ) { - this.logger = dadosferaLogger.logger; - } - - onModuleInit() { - this.usersClientService = this.grpcClient.getService( - ProtoServices.UsersProtoService, - ); - - } - - async createUser(customerId: string, data: CreateUserOpenDataDTO, roleIds: string[], metadata: Metadata) { - const body = { - email: data.email, - name: data.firstName + " " + data.lastName, - department: data.organization, - jobTitle: data.enquiryType, - customerId: customerId, - roleIds: roleIds - } - - try { - const { user } = await lastValueFrom( - this.usersClientService.SimpleUserCreate(body, metadata), - ); - return user.id; - } catch(err) { - return err; - } - } -} diff --git a/src/modules/pipelinesV2/pipelines.service.ts b/src/modules/pipelinesV2/pipelines.service.ts index f10b8ee..9b9be63 100644 --- a/src/modules/pipelinesV2/pipelines.service.ts +++ b/src/modules/pipelinesV2/pipelines.service.ts @@ -328,7 +328,7 @@ export class PipelinesService implements OnModuleInit { const res = await lastValueFrom( this.pipelineReadService.PipelineV2GetDashboardUrl( { - dashboard_id: '95', + dashboard_id: '83', exp: '15m', metabase_customer_name: 'dadosferatech', }, diff --git a/src/modules/theme/dtos/customers.ts b/src/modules/theme/dtos/customers.ts deleted file mode 100644 index 05f5305..0000000 --- a/src/modules/theme/dtos/customers.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Link, Theme } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/entities'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; - -export class CustomerLink implements Link { - @ApiProperty() - href: string; - @ApiProperty() - name: string; - @ApiProperty() - description: string; - @ApiPropertyOptional() - iconSrc: string; -} -export class CustomerLinkRequest { - @ApiProperty({ type: [CustomerLink] }) - links: CustomerLink[]; -} - -export class CustomerLinksResponse { - @ApiProperty({ type: [CustomerLink] }) - links: CustomerLink[]; -} - -export class CustomerTheme implements Theme { - @ApiProperty() - backgroundColor: string; - @ApiProperty() - textColor: string; - @ApiProperty() - logo: string; - @ApiProperty() - logoLogin: string; -} - -export class CustomerThemeResponse { - @ApiProperty() - theme: CustomerTheme; -} - -export class CustomerThemeRequest { - @ApiProperty() - displayName: string; - @ApiProperty() - backgroundColor: string; - @ApiProperty() - textColor: string; -} diff --git a/src/modules/theme/theme.controller.ts b/src/modules/theme/theme.controller.ts deleted file mode 100644 index 327c5be..0000000 --- a/src/modules/theme/theme.controller.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; -import { - Body, - Controller, - Get, - HttpException, - HttpStatus, - Inject, - Param, - Post, - Put, - Query, - UploadedFiles, - UseFilters, - UseInterceptors, - HttpCode -} from '@nestjs/common'; -import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; -import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; -import { - Authenticated, - RequireAllPermissions, -} from 'src/decorators/authentication.decorator'; -import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; -import { CustomerThemeRequest, CustomerThemeResponse } from './dtos/customers'; - -import ErrorCodes from 'src/utils/errorCodes'; -import { AnyFilesInterceptor } from '@nestjs/platform-express'; -import { ThemeService } from './theme.service'; - -@ApiTags('Theme') -@Controller('customers') -@UseFilters(GrpcToHttpExceptionFilter) -export class ThemeController { - logger: DadosferaLogger; - - constructor( - @Inject(DadosferaLogger) - dadosferaLogger: DadosferaLogger, - private themeService: ThemeService, - ) { - this.logger = dadosferaLogger.logger; - } - - - @Post('/:id/theme') - @Authenticated() - @RequireAllPermissions(PERMISSIONS_GROUPS.USERS.permissions.ADMIN) - @ApiOkResponse({ type: CustomerThemeResponse }) - @UseInterceptors(AnyFilesInterceptor()) - @HttpCode(HttpStatus.OK) - async saveCustomertheme( - @Param('id') id: string, - @Body() data: CustomerThemeRequest, - @UploadedFiles() files: Array - ) { - - this.logger.info('saveCustomertheme' + JSON.stringify({ - id, - })); - - const logo = files.find(file => file.fieldname === 'logo'); - const logoLogin = files.find(file => file.fieldname === 'logoLogin'); - - this.validFileSize(logo); - this.validFileSize(logoLogin); - this.validMimeType(logo); - this.validMimeType(logoLogin); - - try { - const theme = await this.themeService.createThemeByCustomer(id, { - ...data, - logo, - logoLogin - }); - this.logger.info('saveCustomertheme' + JSON.stringify(theme)); - return theme; - } catch (err) { - if (err.details === ErrorCodes.CUSTOMER.NOT_FOUND) { - this.logger.error('Error - saveCustomertheme - Expect CUSTOMER.NOT_FOUND'); - throw new HttpException(err.details, HttpStatus.NOT_FOUND); - } else { - this.logger.error('Error - saveCustomertheme Unknown Error:' + err?.message); - return { theme: null }; - }; - } - } - - private validFileSize(file: Express.Multer.File) { - const maxFileSize = 10 * 1024 * 1024; // 10MB - - if (file && file.size > maxFileSize) { - throw new HttpException(`O Arquivo ${file.filename} possui mais de 10MB`, HttpStatus.BAD_REQUEST); - } - } - - private validMimeType(file: Express.Multer.File) { - const mimeTypesValid = ['image/jpeg', 'image/jpg', 'image/png', 'image/svg+xml']; - - if (file && !mimeTypesValid.includes(file.mimetype)) { - throw new HttpException(`O Arquivo ${file.fieldname} deve ser jpeg, jpg, png ou svg`, HttpStatus.BAD_REQUEST); - } - } - - @Get('/:id/theme') - @ApiOkResponse({ type: CustomerThemeResponse }) - async getCustomerTheme(@Param('id') id: string) { - this.logger.info('getCustomerTheme with id' + id); - - try { - const data = await this.themeService.getThemeByCustomer(id); - this.logger.info('Success - getCustomerTheme'+ JSON.stringify(data)); - if (data?.theme) return data; - - return { theme: null }; - }catch (err) { - if (err.details === ErrorCodes.CUSTOMER.NOT_FOUND) { - this.logger.error('Error - getCustomerTheme - Expect CUSTOMER.NOT_FOUND'); - throw new HttpException(err.details, HttpStatus.NOT_FOUND); - } else { - this.logger.error('Error - getCustomerTheme Unknown Error:' + err?.message); - return { theme: null }; - }; - } - } - -} diff --git a/src/modules/theme/theme.module.ts b/src/modules/theme/theme.module.ts deleted file mode 100644 index 4fc3d53..0000000 --- a/src/modules/theme/theme.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Module } from '@nestjs/common'; -import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; -import { ClientsModule } from '@nestjs/microservices'; -import { ThemeController } from './theme.controller'; -import { ThemeService } from './theme.service'; -import { DucClient } from '../duc/client.config'; - -const ducClient = new DucClient(); - -@Module({ - imports: [ - ClientsModule.register([ - ducClient.providerOptions, - ]), - ], - controllers: [ThemeController], - providers: [ThemeService, DadosferaLogger], - exports: [ThemeService], -}) -export class ThemeModule {} diff --git a/src/modules/theme/theme.service.ts b/src/modules/theme/theme.service.ts deleted file mode 100644 index b62338b..0000000 --- a/src/modules/theme/theme.service.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { - OnModuleInit, - Inject, - Injectable, - HttpException, - HttpStatus, - InternalServerErrorException, -} from '@nestjs/common'; - -import { firstValueFrom, lastValueFrom, ReplaySubject } from 'rxjs'; -import { Link } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/entities'; -import { DucClient } from '../duc/client.config'; -import { ClientGrpc } from '@nestjs/microservices'; -import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc'; -import { CustomerUpdateRequest } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages'; -import { ThemeProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service'; -import { ThemeRequest } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages'; -import { CustomerThemeRequest, CustomerThemeResponse } from './dtos/customers'; -import DadosferaLogger from '@dadosfera/dadosfera-logs'; -import { resolve } from 'path'; -import { Readable } from 'stream'; - -type Files = { - logo: Express.Multer.File, - logoLogin: Express.Multer.File, -} - -@Injectable() -export class ThemeService implements OnModuleInit { - private themeService: ThemeProtoService; - private logger: DadosferaLogger; - - constructor( - @Inject(DucClient.name) private readonly grpcClient: ClientGrpc, - @Inject(DadosferaLogger) - dadosferaLogger: DadosferaLogger, - ) { - this.logger = dadosferaLogger.logger; - } - - onModuleInit() { - this.themeService = this.grpcClient.getService( - ProtoServices.ThemeProtoService, - ); - } - - async createThemeByCustomer(id: string, theme: CustomerThemeRequest & Files) { - if (!id) { - this.logger.error('Error - saveCustomertheme - not found id:' + id); - throw new HttpException(null, HttpStatus.BAD_REQUEST); - } - - const customerThemeRequest$ = new ReplaySubject(); - - customerThemeRequest$.next({ - customerId: id, - displayName: theme.displayName, - backgroundColor: theme.backgroundColor, - textColor: theme.textColor, - isMetadata: true, - filename: '', - chunk: Buffer.alloc(0) - }) - - if(theme.logo) { - await this.sendFile(theme.logo, customerThemeRequest$); - } - - if(theme.logoLogin) { - await this.sendFile(theme.logoLogin, customerThemeRequest$); - } - customerThemeRequest$.complete(); - - const stream = this.themeService.CustomerCreateTheme(customerThemeRequest$); - - return lastValueFrom(stream); - } - - async getThemeByCustomer(id: string): Promise { - if (!id) { - this.logger.error('Error - getCustomerTheme - not found id:' + id); - throw new HttpException(null, HttpStatus.BAD_REQUEST); - } - - const { theme } = await firstValueFrom( - this.themeService.CustomerGetTheme({ - id - }), - ); - - return { - theme - } - } - - private async sendFile(file: Express.Multer.File, stream$: ReplaySubject) { - const chunkSize = 4 * 1024 * 1024; - const bufferStream = new CustomBufferStream(file.buffer, chunkSize); - const parseMimitypeForExtension = { - 'image/jpeg': '.jpeg', - 'image/jpg': '.jpg', - 'image/png': '.png', - 'image/svg+xml': '.svg', - } - - const extension = parseMimitypeForExtension[file.mimetype]; - - return new Promise((resolve, reject) => { - bufferStream.on('data', (chunk) => { - const filename = file.fieldname.concat(extension); - stream$.next({ - customerId: '', - displayName: '', - backgroundColor: '', - textColor: '', - isMetadata: false, - filename: filename, - chunk: chunk - }); - }); - - bufferStream.on('end', () => { - resolve(file.filename) - }); - - bufferStream.on('error', (err) => { - reject(err); - }); - }); - } - -} - -class CustomBufferStream extends Readable { - buffer: Buffer; - offset: number; - chunkSize: number; - - constructor(buffer: Buffer, chunkSize: number) { - super({ highWaterMark: chunkSize }); // Configura o tamanho do chunk - this.buffer = buffer; - this.offset = 0; - this.chunkSize = chunkSize; - } - - _read() { - if (this.offset < this.buffer.length) { - const end = Math.min(this.offset + this.chunkSize, this.buffer.length); - - const copiedBuf = Uint8Array.prototype.slice.call(this.buffer); - const chunk = copiedBuf.slice(this.offset, end); - this.offset = end; - this.push(chunk); - } else { - this.push(null); - } - } -}