import { cache } from 'react'; import { AccountWithParams } from '@/packages/features/accounts/src/types/accounts'; import { getSupabaseServerClient } from '@/packages/supabase/src/clients/server-client'; import { createServerClient } from '@supabase/ssr'; import OpenAI from 'openai'; import PersonalCode from '~/lib/utils'; import { AnalysisTestResponse } from '../../(dashboard)/analysis-results/test/test-responses'; import { OrderAnalysisCard } from '../../_components/order-analyses-cards'; export const loadRecommendations = cache(recommendationsLoader); type FormattedAnalysisResponse = { value: string; name: string; responseTime: string; }; const getLatestResponseTime = (items: FormattedAnalysisResponse[]) => { if (!items?.length) return null; let latest = null; for (const it of items) { const d = new Date(it.responseTime); const t = d.getTime(); if (!Number.isNaN(t) && (latest === null || t > latest.getTime())) { latest = d; } } return latest; }; const getLatestUniqueAnalysResponses = ( analysisResponses: AnalysisTestResponse[], ): { name: string; value: string; responseTime: string }[] => { const analysisElements = analysisResponses .map(({ orderedAnalysisElements }) => orderedAnalysisElements) .flat(); console.log('analysisElements', analysisElements.length); const byName = analysisElements.reduce< Record >((acc, it) => { const responseTime = it?.results?.responseTime; const responseValue = it?.results?.responseValue; if (!responseTime || !responseValue) return acc; const key = it.analysisName; const cur = acc[key]; const t = Date.parse(responseTime); const prevT = cur ? Date.parse(cur.responseTime) : -Infinity; if (!cur || t > prevT) { acc[key] = { name: key, value: responseValue.toString(), responseTime, }; } return acc; }, {}); return Object.values(byName); }; async function recommendationsLoader( analysisResponses: AnalysisTestResponse[], analyses: OrderAnalysisCard[], account: AccountWithParams | null, ): Promise { if (!process.env.OPENAI_API_KEY) { return []; } if (!account?.personal_code) { return []; } const supabaseClient = getSupabaseServerClient(); const analysesRecommendationsPromptId = 'pmpt_68ca9c8bfa8c8193b27eadc6496c36440df449ece4f5a8dd'; const latestUniqueAnalysResponses = getLatestUniqueAnalysResponses(analysisResponses); const latestResponseTime = getLatestResponseTime(latestUniqueAnalysResponses); const latestISO = latestResponseTime ? new Date(latestResponseTime).toISOString() : 'none'; const previouslyRecommended = await supabaseClient .schema('medreport') .from('ai_responses') .select('*') .eq('account_id', account.id) .eq('prompt_id', analysesRecommendationsPromptId) .eq('latest_data_change', latestISO); const openAIClient = new OpenAI(); const { gender, age } = PersonalCode.parsePersonalCode(account.personal_code); const weight = account.accountParams?.weight || 'unknown'; console.log('analysisResponses', analysisResponses); console.log('analyises', analyses); const formattedAnalysisResponses = latestUniqueAnalysResponses.map( ({ name, value }) => ({ name, value }), ); const formattedAnalyses = analyses.map(({ description, title }) => ({ description, title, })); const response = await openAIClient.responses.create({ model: 'gpt-5-mini', store: false, prompt: { id: analysesRecommendationsPromptId, variables: { analyses: JSON.stringify(formattedAnalyses), results: JSON.stringify(formattedAnalysisResponses), gender: gender.value, age: age.toString(), weight: weight.toString(), }, }, max_output_tokens: 100, }); const json = JSON.parse(response.output_text); console.log('response.output_text', response.output_text); return json.recommended; }