Initial commit: MOPC platform with Docker deployment setup
Full Next.js 15 platform with tRPC, Prisma, PostgreSQL, NextAuth. Includes production Dockerfile (multi-stage, port 7600), docker-compose with registry-based image pull, Gitea Actions CI workflow, nginx config for portal.monaco-opc.com, deployment scripts, and DEPLOYMENT.md guide. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
109
src/lib/openai.ts
Normal file
109
src/lib/openai.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import OpenAI from 'openai'
|
||||
import { prisma } from './prisma'
|
||||
|
||||
// OpenAI client singleton with lazy initialization
|
||||
const globalForOpenAI = globalThis as unknown as {
|
||||
openai: OpenAI | undefined
|
||||
openaiInitialized: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OpenAI API key from SystemSettings
|
||||
*/
|
||||
async function getOpenAIApiKey(): Promise<string | null> {
|
||||
try {
|
||||
const setting = await prisma.systemSettings.findUnique({
|
||||
where: { key: 'openai_api_key' },
|
||||
})
|
||||
return setting?.value || process.env.OPENAI_API_KEY || null
|
||||
} catch {
|
||||
// Fall back to env var if database isn't available
|
||||
return process.env.OPENAI_API_KEY || null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create OpenAI client instance
|
||||
*/
|
||||
async function createOpenAIClient(): Promise<OpenAI | null> {
|
||||
const apiKey = await getOpenAIApiKey()
|
||||
|
||||
if (!apiKey) {
|
||||
console.warn('OpenAI API key not configured')
|
||||
return null
|
||||
}
|
||||
|
||||
return new OpenAI({
|
||||
apiKey,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the OpenAI client singleton
|
||||
* Returns null if API key is not configured
|
||||
*/
|
||||
export async function getOpenAI(): Promise<OpenAI | null> {
|
||||
if (globalForOpenAI.openaiInitialized) {
|
||||
return globalForOpenAI.openai || null
|
||||
}
|
||||
|
||||
const client = await createOpenAIClient()
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
globalForOpenAI.openai = client || undefined
|
||||
globalForOpenAI.openaiInitialized = true
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if OpenAI is configured and available
|
||||
*/
|
||||
export async function isOpenAIConfigured(): Promise<boolean> {
|
||||
const apiKey = await getOpenAIApiKey()
|
||||
return !!apiKey
|
||||
}
|
||||
|
||||
/**
|
||||
* Test OpenAI connection
|
||||
*/
|
||||
export async function testOpenAIConnection(): Promise<{
|
||||
success: boolean
|
||||
error?: string
|
||||
model?: string
|
||||
}> {
|
||||
try {
|
||||
const client = await getOpenAI()
|
||||
|
||||
if (!client) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'OpenAI API key not configured',
|
||||
}
|
||||
}
|
||||
|
||||
// Simple test request
|
||||
const response = await client.chat.completions.create({
|
||||
model: 'gpt-4o-mini',
|
||||
messages: [{ role: 'user', content: 'Hello' }],
|
||||
max_tokens: 5,
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
model: response.model,
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default models for different use cases
|
||||
export const AI_MODELS = {
|
||||
ASSIGNMENT: 'gpt-4o', // Best for complex reasoning
|
||||
QUICK: 'gpt-4o-mini', // Faster, cheaper for simple tasks
|
||||
} as const
|
||||
Reference in New Issue
Block a user