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:
2026-01-30 13:41:32 +01:00
commit a606292aaa
290 changed files with 70691 additions and 0 deletions

109
src/lib/openai.ts Normal file
View 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