From dddb15df6348969f86f970003e9921623f4c1f24 Mon Sep 17 00:00:00 2001 From: nael Date: Thu, 23 May 2024 23:44:55 +0200 Subject: [PATCH] :sparkles: Added docs updates --- docs/core-concepts/custom-fields.mdx | 21 ++++++- .../dto/create-custom-field.dto.ts | 20 +++++-- .../field-mapping/field-mapping.controller.ts | 14 +++++ .../field-mapping/field-mapping.service.ts | 37 ++++++++++++ packages/api/swagger/swagger-spec.json | 60 +++++++++++++++++++ 5 files changed, 147 insertions(+), 5 deletions(-) diff --git a/docs/core-concepts/custom-fields.mdx b/docs/core-concepts/custom-fields.mdx index f57c0c8f4..38fed6ad4 100644 --- a/docs/core-concepts/custom-fields.mdx +++ b/docs/core-concepts/custom-fields.mdx @@ -21,7 +21,7 @@ In this video we define a field and then once a connection is available we fetch > -## Create a custom field mapping using the our UI dashboard +## Create a custom field mapping using our UI dashboard @@ -49,6 +49,25 @@ You will now find all the fields your user has in its software. Pick the one tha ## Create a custom field mapping using our API +The following example creates a custom field mapping in two steps (**define and map**) where we map a remote field called `hair_color_hubspot_123_id` (existing in the `Husbpot` provider) and mapping it to the `crm.contact` unified model of Panora under the name of `hair_color`. + + ```shell Create custom field + curl --request POST \ + --url https://api.panora.dev/field-mappings \ + --header 'Authorization: Bearer ' \ + --header 'Content-Type: application/json' \ + --data '{ + "object_type_owner": "crm.contact", + "name": "hair_color", + "description": "My hair_color field mapping", + "data_type": "text", + "source_custom_field_id": "hair_color_hubspot_123_id", # id of the remote field inside the remote provider + "source_provider": "hubspot", + "linked_user_id": "acme_customer_a" + }' + ``` +You may want to define it in two steps if you miss some information to map in the 1st step. + The following example creates a custom field mapping in two steps (**define and map**) where we map a remote field called `hair_color_hubspot_123_id` (existing in the `Husbpot` provider) and mapping it to the `crm.contact` unified model of Panora under the name of `hair_color`. diff --git a/packages/api/src/@core/field-mapping/dto/create-custom-field.dto.ts b/packages/api/src/@core/field-mapping/dto/create-custom-field.dto.ts index b52fe26b3..d8de20e51 100644 --- a/packages/api/src/@core/field-mapping/dto/create-custom-field.dto.ts +++ b/packages/api/src/@core/field-mapping/dto/create-custom-field.dto.ts @@ -1,8 +1,22 @@ import { StandardObject } from '@@core/utils/types'; import { ApiProperty } from '@nestjs/swagger'; -export class CustomFieldCreateDto {} - +export class CustomFieldCreateDto { + @ApiProperty({ type: String }) + object_type_owner: StandardObject; + @ApiProperty() + name: string; + @ApiProperty() + description: string; + @ApiProperty() + data_type: string; + @ApiProperty() + source_custom_field_id: string; + @ApiProperty() + source_provider: string; + @ApiProperty() + linked_user_id: string; +} export class DefineTargetFieldDto { @ApiProperty({ type: String }) object_type_owner: StandardObject; @@ -12,8 +26,6 @@ export class DefineTargetFieldDto { description: string; @ApiProperty() data_type: string; - //@ApiProperty() - //project_id: string; } export class MapFieldToProviderDto { diff --git a/packages/api/src/@core/field-mapping/field-mapping.controller.ts b/packages/api/src/@core/field-mapping/field-mapping.controller.ts index a6b62bdf0..f40a3c2ad 100644 --- a/packages/api/src/@core/field-mapping/field-mapping.controller.ts +++ b/packages/api/src/@core/field-mapping/field-mapping.controller.ts @@ -10,6 +10,7 @@ import { import { LoggerService } from '../logger/logger.service'; import { FieldMappingService } from './field-mapping.service'; import { + CustomFieldCreateDto, DefineTargetFieldDto, MapFieldToProviderDto, } from './dto/create-custom-field.dto'; @@ -80,6 +81,19 @@ export class FieldMappingController { ); } + @ApiOperation({ + operationId: 'createCustomField', + summary: 'Create Custom Field', + }) + @ApiBody({ type: CustomFieldCreateDto }) + @ApiResponse({ status: 201 }) + @Post() + @UseGuards(JwtAuthGuard) + createCustomField(@Request() req: any, @Body() data: CustomFieldCreateDto) { + const { id_project } = req.user; + return this.fieldMappingService.createCustomField(data, id_project); + } + @ApiOperation({ operationId: 'mapField', summary: 'Map Custom Field' }) @ApiBody({ type: MapFieldToProviderDto }) @ApiResponse({ status: 201 }) diff --git a/packages/api/src/@core/field-mapping/field-mapping.service.ts b/packages/api/src/@core/field-mapping/field-mapping.service.ts index a8b63d4af..91137fd84 100644 --- a/packages/api/src/@core/field-mapping/field-mapping.service.ts +++ b/packages/api/src/@core/field-mapping/field-mapping.service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import { LoggerService } from '../logger/logger.service'; import { + CustomFieldCreateDto, DefineTargetFieldDto, MapFieldToProviderDto, } from './dto/create-custom-field.dto'; @@ -121,6 +122,42 @@ export class FieldMappingService { } } + async createCustomField(dto: CustomFieldCreateDto, projectId: string) { + try { + const attribute = await this.prisma.attribute.create({ + data: { + id_attribute: uuidv4(), + id_project: projectId, + ressource_owner_type: dto.object_type_owner as string, + slug: dto.name, + description: dto.description, + data_type: dto.data_type, + status: 'defined', // [defined | mapped] + // below is done in step 2 + remote_id: '', + source: '', + //id_entity: id_entity, + scope: 'user', // [user | org] wide + }, + }); + const updatedAttribute = await this.prisma.attribute.update({ + where: { + id_attribute: attribute.id_attribute.trim(), + }, + data: { + remote_id: dto.source_custom_field_id, + source: dto.source_provider, + id_consumer: dto.linked_user_id.trim(), + status: 'mapped', + }, + }); + + return updatedAttribute; + } catch (error) { + handleServiceError(error, this.logger); + } + } + async getCustomProperties( linkedUserId: string, providerId: string, diff --git a/packages/api/swagger/swagger-spec.json b/packages/api/swagger/swagger-spec.json index 8dcd78db8..a33cc91c7 100644 --- a/packages/api/swagger/swagger-spec.json +++ b/packages/api/swagger/swagger-spec.json @@ -736,6 +736,31 @@ ] } }, + "/field-mappings": { + "post": { + "operationId": "createCustomField", + "summary": "Create Custom Field", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldCreateDto" + } + } + } + }, + "responses": { + "201": { + "description": "" + } + }, + "tags": [ + "field-mappings" + ] + } + }, "/field-mappings/map": { "post": { "operationId": "mapField", @@ -4922,6 +4947,41 @@ "data_type" ] }, + "CustomFieldCreateDto": { + "type": "object", + "properties": { + "object_type_owner": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "data_type": { + "type": "string" + }, + "source_custom_field_id": { + "type": "string" + }, + "source_provider": { + "type": "string" + }, + "linked_user_id": { + "type": "string" + } + }, + "required": [ + "object_type_owner", + "name", + "description", + "data_type", + "source_custom_field_id", + "source_provider", + "linked_user_id" + ] + }, "MapFieldToProviderDto": { "type": "object", "properties": {