From 1ca86358b8f5094b656475ac4af921cd6dc4b2ef Mon Sep 17 00:00:00 2001 From: Matan Yadaev Date: Wed, 31 Jul 2024 16:19:21 +0300 Subject: [PATCH] List customers and set customer config (#2591) * feat: list customers and allow setting config * fix: add missing property to config schema * fix: endpoint --------- Co-authored-by: Alon Peretz <8467965+alonp99@users.noreply.github.com> --- .../customer/customer.controller.external.ts | 62 +-------------- .../customer/customer.controller.internal.ts | 76 ++++++++++++++++++- .../src/customer/dtos/customer-create.ts | 8 ++ .../src/workflow/schemas/zod-schemas.ts | 1 + 4 files changed, 84 insertions(+), 63 deletions(-) diff --git a/services/workflows-service/src/customer/customer.controller.external.ts b/services/workflows-service/src/customer/customer.controller.external.ts index 5e4e421274..465d426975 100644 --- a/services/workflows-service/src/customer/customer.controller.external.ts +++ b/services/workflows-service/src/customer/customer.controller.external.ts @@ -3,77 +3,19 @@ import * as common from '@nestjs/common'; import { Request, UseGuards, UsePipes } from '@nestjs/common'; import * as swagger from '@nestjs/swagger'; import { CustomerService } from '@/customer/customer.service'; -import { Customer, Prisma } from '@prisma/client'; -import { CustomerCreateDto } from '@/customer/dtos/customer-create'; -import { AdminAuthGuard } from '@/common/guards/admin-auth.guard'; +import { Customer } from '@prisma/client'; import { CustomerModel } from '@/customer/customer.model'; import { AuthenticatedEntity } from '@/types'; import { CustomerAuthGuard } from '@/common/guards/customer-auth.guard'; -import { createDemoMockData } from '../../scripts/workflows/workflow-runtime'; -import { PrismaService } from '@/prisma/prisma.service'; import { ZodValidationPipe } from '@/common/pipes/zod.pipe'; import { CustomerSubscriptionDto } from './dtos/customer-config-create.dto'; import { ValidationError } from '@/errors'; -import { randomUUID } from 'node:crypto'; @swagger.ApiTags('Customers') @swagger.ApiExcludeController() @common.Controller('external/customers') export class CustomerControllerExternal { - constructor( - protected readonly service: CustomerService, - protected readonly prisma: PrismaService, - ) {} - - @common.Post() - @UseGuards(AdminAuthGuard) - @swagger.ApiCreatedResponse({ type: [CustomerCreateDto] }) - @swagger.ApiForbiddenResponse() - async create(@common.Body() customerCreateModel: CustomerCreateDto) { - const { projectName, ...customer } = customerCreateModel; - - if (projectName) { - (customer as Prisma.CustomerCreateInput).projects = { - create: { name: customerCreateModel.projectName! }, - }; - } - - const apiKey = customer.authenticationConfiguration?.authValue ?? randomUUID(); - - const createdCustomer = (await this.service.create({ - data: { - ...customer, - authenticationConfiguration: { - ...customer.authenticationConfiguration, - authValue: apiKey, - }, - }, - select: { - id: true, - name: true, - displayName: true, - logoImageUri: true, - faviconImageUri: true, - country: true, - language: true, - customerStatus: true, - projects: true, - }, - })) as Customer & { projects: Array<{ id: string }> }; - - if (projectName == 'demo') { - await createDemoMockData({ - prismaClient: this.prisma, - customer: customerCreateModel, - projects: createdCustomer.projects, - }); - } - - return { - ...createdCustomer, - apiKey, - }; - } + constructor(protected readonly service: CustomerService) {} @common.Get('/me') @UseGuards(CustomerAuthGuard) diff --git a/services/workflows-service/src/customer/customer.controller.internal.ts b/services/workflows-service/src/customer/customer.controller.internal.ts index 6fd921f815..38c58ba461 100644 --- a/services/workflows-service/src/customer/customer.controller.internal.ts +++ b/services/workflows-service/src/customer/customer.controller.internal.ts @@ -1,16 +1,32 @@ import * as common from '@nestjs/common'; -import { NotFoundException } from '@nestjs/common'; +import { NotFoundException, UseGuards } from '@nestjs/common'; import * as swagger from '@nestjs/swagger'; import { CustomerService } from '@/customer/customer.service'; import { CustomerModel } from '@/customer/customer.model'; -import type { TProjectIds } from '@/types'; +import { InputJsonValue, type TProjectIds } from '@/types'; import { ProjectIds } from '@/common/decorators/project-ids.decorator'; import { TCustomerWithDefinitionsFeatures } from '@/customer/types'; +import { AdminAuthGuard } from '@/common/guards/admin-auth.guard'; +import { CustomerCreateDto } from '@/customer/dtos/customer-create'; +import { ConfigSchema } from '@/workflow/schemas/zod-schemas'; +import { Customer, Prisma } from '@prisma/client'; +import { randomUUID } from 'node:crypto'; +import { createDemoMockData } from '../../scripts/workflows/workflow-runtime'; +import { PrismaService } from '@/prisma/prisma.service'; @swagger.ApiExcludeController() @common.Controller('internal/customers') export class CustomerControllerInternal { - constructor(protected readonly service: CustomerService) {} + constructor( + protected readonly service: CustomerService, + protected readonly prisma: PrismaService, + ) {} + + @common.Get() + @UseGuards(AdminAuthGuard) + async list() { + return await this.service.list(); + } @common.Get() @swagger.ApiOkResponse({ type: [CustomerModel] }) @@ -36,4 +52,58 @@ export class CustomerControllerInternal { }, }); } + + @common.Post() + @UseGuards(AdminAuthGuard) + @swagger.ApiCreatedResponse({ type: [CustomerCreateDto] }) + @swagger.ApiForbiddenResponse() + async create(@common.Body() customerCreateModel: CustomerCreateDto) { + const { projectName, config, ...customer } = customerCreateModel; + + const parsedConfig = ConfigSchema.parse(config); + + if (projectName) { + (customer as Prisma.CustomerCreateInput).projects = { + create: { name: customerCreateModel.projectName! }, + }; + } + + const apiKey = customer.authenticationConfiguration?.authValue ?? randomUUID(); + + const createdCustomer = (await this.service.create({ + data: { + ...customer, + config: parsedConfig as InputJsonValue, + authenticationConfiguration: { + ...customer.authenticationConfiguration, + authValue: apiKey, + }, + }, + select: { + id: true, + name: true, + displayName: true, + logoImageUri: true, + faviconImageUri: true, + country: true, + language: true, + customerStatus: true, + projects: true, + config: true, + }, + })) as Customer & { projects: Array<{ id: string }> }; + + if (projectName == 'demo') { + await createDemoMockData({ + prismaClient: this.prisma, + customer: customerCreateModel, + projects: createdCustomer.projects, + }); + } + + return { + ...createdCustomer, + apiKey, + }; + } } diff --git a/services/workflows-service/src/customer/dtos/customer-create.ts b/services/workflows-service/src/customer/dtos/customer-create.ts index 7221eaae83..d2148f48b3 100644 --- a/services/workflows-service/src/customer/dtos/customer-create.ts +++ b/services/workflows-service/src/customer/dtos/customer-create.ts @@ -72,4 +72,12 @@ export class CustomerCreateDto { @IsString() @IsOptional() websiteUrl?: string; + + @ApiProperty({ + required: false, + type: 'object', + }) + @IsObject() + @IsOptional() + config?: Record; } diff --git a/services/workflows-service/src/workflow/schemas/zod-schemas.ts b/services/workflows-service/src/workflow/schemas/zod-schemas.ts index 84ef69f36b..f41181fe3d 100644 --- a/services/workflows-service/src/workflow/schemas/zod-schemas.ts +++ b/services/workflows-service/src/workflow/schemas/zod-schemas.ts @@ -61,6 +61,7 @@ export const ConfigSchema = z theme: WorkflowDefinitionConfigThemeSchema.optional(), hasUboOngoingMonitoring: z.boolean().optional(), maxBusinessReports: z.number().nonnegative().optional(), + isMerchantMonitoringEnabled: z.boolean().optional(), }) .strict() .optional();