3 Commits

Author SHA1 Message Date
Christopher Mayor
37c07e468d fix: lazy-init OpenAI client to avoid build failure without API key 2026-04-24 14:37:28 -07:00
Christopher Mayor
3539a5f3eb feat: add .env.example with required environment variables 2026-04-24 14:35:19 -07:00
Christopher Mayor
26d879c82e feat: add standalone output to next.config.ts for Docker builds 2026-04-24 14:34:50 -07:00
4 changed files with 17 additions and 5 deletions

6
.env.example Normal file
View File

@@ -0,0 +1,6 @@
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/comparaison
BETTER_AUTH_SECRET=change-me-to-random-string
OPENAI_API_KEY=
PERPLEXITY_API_KEY=
TAVILY_API_KEY=
NEXT_PUBLIC_APP_URL=http://localhost:3000

1
.gitignore vendored
View File

@@ -32,6 +32,7 @@ yarn-error.log*
# env files (can opt-in for committing if needed) # env files (can opt-in for committing if needed)
.env* .env*
!.env.example
# vercel # vercel
.vercel .vercel

View File

@@ -1,7 +1,7 @@
import type { NextConfig } from "next"; import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
/* config options here */ output: "standalone",
}; };
export default nextConfig; export default nextConfig;

View File

@@ -6,9 +6,14 @@ import type {
ItemResearch, ItemResearch,
} from "../types"; } from "../types";
const client = new OpenAI({ let _client: OpenAI | null = null;
apiKey: process.env.OPENAI_API_KEY,
}); function getClient(): OpenAI {
if (!_client) {
_client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
}
return _client;
}
const SYSTEM_PROMPT = `You are an expert research analyst. Your job is to compare items across multiple dimensions and produce structured, insightful comparison data. const SYSTEM_PROMPT = `You are an expert research analyst. Your job is to compare items across multiple dimensions and produce structured, insightful comparison data.
@@ -105,7 +110,7 @@ Provide a comprehensive comparison with scores, pros/cons, and a recommendation.
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) { for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
try { try {
const response = await client.chat.completions.create({ const response = await getClient().chat.completions.create({
model: "gpt-4o-mini", model: "gpt-4o-mini",
messages: [ messages: [
{ role: "system", content: SYSTEM_PROMPT }, { role: "system", content: SYSTEM_PROMPT },