Skip to content

Commit

Permalink
Add new endpoint for correcting product titles and descriptions
Browse files Browse the repository at this point in the history
 - Implement new OpenAI endpoint `/openai/products-title` with associated request and response schemas
 - Add `OpenAIControllerProductTitle` and `OpenAIProductTitleService` for title correction functionality
 - Remove unused `CustomerProductServiceGet` import in `update-product.ts`
 - Refactor `updateProduct` function to use lean queries and simplify product update logic
  • Loading branch information
jamalsoueidan committed Jun 30, 2024
1 parent 6b40825 commit a4d0e36
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 19 deletions.
3 changes: 3 additions & 0 deletions openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -532,3 +532,6 @@ paths:
$ref: "./paths/user/search/index.yaml"
/users/top:
$ref: "./paths/user/top/index.yaml"

/openai/products-title:
$ref: "./paths/openai/product-title/index.yaml"
8 changes: 8 additions & 0 deletions openapi/paths/openai/product-title/body.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type: object
properties:
title:
type: string
description:
type: string
required:
- title
28 changes: 28 additions & 0 deletions openapi/paths/openai/product-title/index.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
post:
tags:
- OpenAI
operationId: openAIProductTitle
summary: POST Correct any grammatical errors in title and description
description: This endpoint correct any grammatical errors in title and description
requestBody:
required: true
content:
application/json:
schema:
$ref: "./body.yaml"

responses:
"200":
description: Response
content:
application/json:
schema:
$ref: "./response.yaml"
"400":
$ref: "../../../responses/bad.yaml"
"401":
$ref: "../../../responses/unauthorized.yaml"
"403":
$ref: "../../../responses/forbidden.yaml"

security: []
19 changes: 19 additions & 0 deletions openapi/paths/openai/product-title/response.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
type: object
properties:
success:
type: boolean
example: true
payload:
type: object
properties:
title:
type: string
description:
type: string
required:
- title
- description

required:
- success
- payload
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { CustomerServiceGet } from "~/functions/customer/services/customer/get";
import { CustomerProductServiceGet } from "~/functions/customer/services/product/get";
import { LocationModel } from "~/functions/location";
import { OpenAIServiceProductCategorize } from "~/functions/openai/services/product-categorize";
import { ScheduleModel } from "~/functions/schedule";
Expand All @@ -26,15 +25,17 @@ export const updateProduct = async ({
productId,
},
},
}).orFail(
new NotFoundError([
{
code: "custom",
message: "PRODUCT_NOT_FOUND",
path: ["productId"],
},
])
);
})
.lean()
.orFail(
new NotFoundError([
{
code: "custom",
message: "PRODUCT_NOT_FOUND",
path: ["productId"],
},
])
);

const product = schedule.products.find((p) => p.productId === productId);

Expand Down Expand Up @@ -100,12 +101,6 @@ export const updateProduct = async ({
});
});

const { scheduleId, scheduleMetafieldId, scheduleName, ...oldProduct } =
await CustomerProductServiceGet({
customerId,
productId,
});

await ScheduleModel.updateOne(
{
customerId,
Expand All @@ -114,10 +109,10 @@ export const updateProduct = async ({
{
$set: {
"products.$": {
...oldProduct,
...product,
collectionIds:
categories?.map((c) => GidFormat.parse(c.id)) ||
oldProduct.collectionIds,
product.collectionIds,
},
},
}
Expand Down
10 changes: 9 additions & 1 deletion src/functions/openai-product.function.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { app } from "@azure/functions";
import "module-alias/register";
import { OpenAIControllerProductCategorize } from "./openai/controllers/product";
import { OpenAIControllerProductCategorize } from "./openai/controllers/product-categorize";
import { OpenAIControllerProductTitle } from "./openai/controllers/product-title";

app.http("openaiProductCategorize", {
methods: ["POST"],
authLevel: "anonymous",
route: "openai/products-categorize",
handler: OpenAIControllerProductCategorize,
});

app.http("openaiProductTitle", {
methods: ["POST"],
authLevel: "anonymous",
route: "openai/products-title",
handler: OpenAIControllerProductTitle,
});
File renamed without changes.
23 changes: 23 additions & 0 deletions src/functions/openai/controllers/product-title.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { z } from "zod";
import { _ } from "~/library/handler";
import { OpenAIServiceProductTitle } from "../services/product-title";

export type OpenAIControllerProductTitleRequest = {
body: z.infer<typeof OpenAIControllerProductTitleSchema>;
};

export const OpenAIControllerProductTitleSchema = z.object({
title: z.string(),
description: z.string().optional(),
});

export type OpenaiProductCategorizeResponse = Awaited<
ReturnType<typeof OpenAIControllerProductTitle>
>;

export const OpenAIControllerProductTitle = _(
({ body }: OpenAIControllerProductTitleRequest) => {
const validateBody = OpenAIControllerProductTitleSchema.parse(body);
return OpenAIServiceProductTitle(validateBody);
}
);
40 changes: 40 additions & 0 deletions src/functions/openai/services/product-title.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import OpenAI from "openai";

const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});

type OpenAIServiceProductTitleReturn = {
title: string;
description: string;
};

export const OpenAIServiceProductTitle = async ({
title,
description,
}: {
title: string;
description?: string;
}) => {
const response = await openai.chat.completions.create({
model: "gpt-4o-2024-05-13",
messages: [
{
role: "system",
content: `You are an expert in correcting treatment titles and descriptions. Please correct any grammatical errors in title and description. If the description is missing, add a short sentence that encourages customers to buy the product. Please responds with title, description json format and keep the language in danish.`,
},
{
role: "user",
content: `Title: ${title}\nDescription: ${description || ""}`,
},
],
max_tokens: 100,
response_format: {
type: "json_object",
},
});

return JSON.parse(
response.choices[0].message.content as any
) as OpenAIServiceProductTitleReturn;
};

0 comments on commit a4d0e36

Please sign in to comment.