diff --git a/apps/backend/src/controllers/submission.controller.ts b/apps/backend/src/controllers/submission.controller.ts index 2aaf004..122fc65 100644 --- a/apps/backend/src/controllers/submission.controller.ts +++ b/apps/backend/src/controllers/submission.controller.ts @@ -11,27 +11,19 @@ export class SubmissionController { public submitReceipt = async (req: Request, res: Response, next: NextFunction): Promise => { try { - const body: Omit = req.body; + const body: Omit = req.body; const submissionRequest: Submission = { ...body, timestamp: Date.now(), }; - // Submission validation with smart contract - await this.contracts.validateSubmission(submissionRequest); - //const validationResult = await this.openai.validateImage(body.image); + // TODO: Submission validation with smart contract + const validationResult = await this.openai.validateImage(body.image, req.body.promptType); - //if (validationResult == undefined || !('validityFactor' in (validationResult as object))) { - // throw new HttpException(500, 'Error validating image'); - //} - - const validityFactor = 1; - - if (validityFactor > 0.5) { - if (!(await this.contracts.registerSubmission(submissionRequest))) { - throw new HttpException(500, 'Error registering submission and sending rewards'); - } + const validityFactor = validationResult['validityFactor']; + if (validityFactor < 0.5) { + throw new HttpException(500, 'Error registering submission and sending rewards'); } res.status(200).json({ validation: { validityFactor: 1 } }); diff --git a/apps/backend/src/dtos/submission.dto.ts b/apps/backend/src/dtos/submission.dto.ts index 207a248..a5c27e5 100644 --- a/apps/backend/src/dtos/submission.dto.ts +++ b/apps/backend/src/dtos/submission.dto.ts @@ -13,4 +13,8 @@ export class SubmitDto { @IsString() @IsNotEmpty() public deviceID: string; + + @IsString() + @IsNotEmpty() + public promptType: string; } diff --git a/apps/backend/src/interfaces/submission.interface.ts b/apps/backend/src/interfaces/submission.interface.ts index b884818..afe05ba 100644 --- a/apps/backend/src/interfaces/submission.interface.ts +++ b/apps/backend/src/interfaces/submission.interface.ts @@ -5,4 +5,5 @@ export interface Submission { timestamp: number; image?: string; deviceID?: string; + promptType?: string; } diff --git a/apps/backend/src/services/openai.service.ts b/apps/backend/src/services/openai.service.ts index 730beda..3e3a483 100644 --- a/apps/backend/src/services/openai.service.ts +++ b/apps/backend/src/services/openai.service.ts @@ -5,21 +5,42 @@ import { Service } from 'typedi'; @Service() export class OpenaiService { - public async validateImage(image: string): Promise { + public async validateImage(image: string, promptType: string): Promise { if (!isBase64Image(image)) throw new HttpException(400, 'Invalid image format'); - const prompt = ` + let prompt = ''; + switch (promptType) { + case 'Transport': + prompt = ` Analyze the image provided. The image MUST satisfy all of the following criteria: - 1. It must have as subject a receipt of purchase of at least one product. - 2. It must not be a screenshot. - 3. It must include the date of the purchase. - 4. It must include the name of the store where the purchase was made. + 1. It must be a screenshot or picture of public transport including bikes, and buses + 2. It must include the distance travelled Please respond always and uniquely with the following JSON object as you are REST API that returns the following object: { "validityFactor": {validityFactorNumber}, // 0-1, 1 if it satisfies all the criteria, 0 otherwise "descriptionOfAnalysis": "{analysis}", // indicate your analysis of the image and why it satisfies or not the criteria. The analysis will be shown to the user so make him understand why the image doesn't satisfy the criteria if it doesn't without going into detail on exact criteria. Remember we are rewarding users that drink coffee in a sustainable way. } `; + break; + + case 'Electricity': + break; + + case 'Packaging': + break; + + case 'Trees': + break; + + case 'Trash': + break; + + case 'Volunteering': + break; + + default: + throw new HttpException(400, 'Invalid prompt type'); + } const gptResponse = await openAIHelper.askChatGPTAboutImage({ base64Image: image, diff --git a/apps/frontend/src/components/Dropzone.tsx b/apps/frontend/src/components/Dropzone.tsx index 96d7cdf..62ea9d5 100644 --- a/apps/frontend/src/components/Dropzone.tsx +++ b/apps/frontend/src/components/Dropzone.tsx @@ -7,7 +7,7 @@ import { useWallet } from "@vechain/dapp-kit-react"; import { submitReceipt } from "../networking"; import { useDisclosure, useSubmission } from "../hooks"; -export const Dropzone = () => { +export const Dropzone = ({ promptType }: { promptType: string }) => { const { account } = useWallet(); const { setIsLoading, setResponse } = useSubmission(); @@ -51,6 +51,7 @@ export const Dropzone = () => { address: account, deviceID, image: base64Image, + promptType, }); console.log(response); @@ -62,7 +63,7 @@ export const Dropzone = () => { setIsLoading(false); } }, - [account, onOpen, setIsLoading, setResponse], + [account, onOpen, setIsLoading, setResponse] ); return ( diff --git a/apps/frontend/src/networking/type.ts b/apps/frontend/src/networking/type.ts index 1ed0b01..2f756b4 100644 --- a/apps/frontend/src/networking/type.ts +++ b/apps/frontend/src/networking/type.ts @@ -2,4 +2,5 @@ export interface ReceiptData { image: string; address: string; deviceID: string; + promptType: string; } diff --git a/apps/frontend/src/routes/form.tsx b/apps/frontend/src/routes/form.tsx index 5925f63..e0f034c 100644 --- a/apps/frontend/src/routes/form.tsx +++ b/apps/frontend/src/routes/form.tsx @@ -5,7 +5,7 @@ import { Link } from "react-router-dom"; import "./form.css"; export default function Form({ type }: { type: "reduce" | "offset" }) { - const [category, setCategory] = useState("All"); + const [category, setCategory] = useState("Transport"); // Define categories based on the type prop const categories = @@ -65,7 +65,7 @@ export default function Form({ type }: { type: "reduce" | "offset" }) { Step 2{" "} Step 1asdkjndsfkjcnkjsd - + {/* Submit area */}