From e49a7b0bb47248cd7bb18fed310e7d548784ddcc Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Fri, 24 Oct 2025 02:09:46 +0200 Subject: [PATCH] Add backend support for setting compatibility answers --- backend/api/src/app.ts | 4 ++- backend/api/src/set-compatibility-answer.ts | 34 +++++++++++++++++++ common/src/api/schema.ts | 15 ++++++++ .../answer-compatibility-question-content.tsx | 15 ++++---- 4 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 backend/api/src/set-compatibility-answer.ts diff --git a/backend/api/src/app.ts b/backend/api/src/app.ts index c63ccb8..2f5f373 100644 --- a/backend/api/src/app.ts +++ b/backend/api/src/app.ts @@ -12,6 +12,7 @@ import {blockUser, unblockUser} from './block-user' import {getCompatibleProfilesHandler} from './compatible-profiles' import {createComment} from './create-comment' import {createCompatibilityQuestion} from './create-compatibility-question' +import {setCompatibilityAnswer} from './set-compatibility-answer' import {createProfile} from './create-profile' import {createUser} from './create-user' import {getCompatibilityQuestions} from './get-compatibililty-questions' @@ -170,6 +171,7 @@ const handlers: { [k in APIPath]: APIHandler } = { 'create-comment': createComment, 'hide-comment': hideComment, 'create-compatibility-question': createCompatibilityQuestion, + 'set-compatibility-answer': setCompatibilityAnswer, 'create-vote': createVote, 'vote': vote, 'contact': contact, @@ -188,7 +190,7 @@ const handlers: { [k in APIPath]: APIHandler } = { 'set-last-online-time': setLastOnlineTime, 'save-subscription': saveSubscription, 'create-bookmarked-search': createBookmarkedSearch, - 'delete-bookmarked-search': deleteBookmarkedSearch, + 'delete-bookmarked-search': deleteBookmarkedSearch, } Object.entries(handlers).forEach(([path, handler]) => { diff --git a/backend/api/src/set-compatibility-answer.ts b/backend/api/src/set-compatibility-answer.ts new file mode 100644 index 0000000..156b209 --- /dev/null +++ b/backend/api/src/set-compatibility-answer.ts @@ -0,0 +1,34 @@ +import {APIHandler} from './helpers/endpoint' +import {createSupabaseDirectClient} from 'shared/supabase/init' +import {Row} from 'common/supabase/utils' + +export const setCompatibilityAnswer: APIHandler<'set-compatibility-answer'> = async ( + {questionId, multipleChoice, prefChoices, importance, explanation}, + auth +) => { + const pg = createSupabaseDirectClient() + + const result = await pg.one>({ + text: ` + INSERT INTO compatibility_answers + (creator_id, question_id, multiple_choice, pref_choices, importance, explanation) + VALUES ($1, $2, $3, $4, $5, $6) + ON CONFLICT (question_id, creator_id) + DO UPDATE SET multiple_choice = EXCLUDED.multiple_choice, + pref_choices = EXCLUDED.pref_choices, + importance = EXCLUDED.importance, + explanation = EXCLUDED.explanation + RETURNING * + `, + values: [ + auth.uid, + questionId, + multipleChoice, + prefChoices, + importance, + explanation ?? null, + ], + }) + + return result +} diff --git a/common/src/api/schema.ts b/common/src/api/schema.ts index ecb8ae4..f0a47d2 100644 --- a/common/src/api/schema.ts +++ b/common/src/api/schema.ts @@ -515,6 +515,21 @@ export const API = (_apiTypeCheck = { options: z.record(z.string(), z.number()), }), }, + 'set-compatibility-answer': { + method: 'POST', + authed: true, + rateLimited: true, + returns: {} as Row<'compatibility_answers'>, + props: z + .object({ + questionId: z.number(), + multipleChoice: z.number(), + prefChoices: z.array(z.number()), + importance: z.number(), + explanation: z.string().nullable().optional(), + }) + .strict(), + }, 'create-vote': { method: 'POST', authed: true, diff --git a/web/components/answers/answer-compatibility-question-content.tsx b/web/components/answers/answer-compatibility-question-content.tsx index 1c1e61a..9a71ffb 100644 --- a/web/components/answers/answer-compatibility-question-content.tsx +++ b/web/components/answers/answer-compatibility-question-content.tsx @@ -16,6 +16,7 @@ import {Tooltip} from 'web/components/widgets/tooltip' import {QuestionWithCountType} from 'web/hooks/use-questions' import {track} from 'web/lib/service/analytics' import {db} from 'web/lib/supabase/db' +import {api} from 'web/lib/api' import {filterKeys} from '../questions-form' import toast from "react-hot-toast"; @@ -58,18 +59,20 @@ export const submitCompatibilityAnswer = async ( } as CompatibilityAnswerSubmitType try { - await run( - db.from('compatibility_answers').upsert(input, { - onConflict: 'question_id,creator_id', - }) - ); + await api('set-compatibility-answer', { + questionId: input.question_id, + multipleChoice: input.multiple_choice, + prefChoices: input.pref_choices ?? [], + importance: input.importance, + explanation: input.explanation ?? null, + }) // Track only if upsert succeeds track('answer compatibility question', { ...newAnswer, }); } catch (error) { - console.error('Failed to upsert compatibility_answers:', error); + console.error('Failed to set compatibility answer:', error); toast.error('Error submitting. Try again?') } }