first commit
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
import express, { Request, Response } from 'express';
|
||||
import cors from 'cors';
|
||||
import dotenv from 'dotenv';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { GoogleGenAI } from '@google/generative-ai';
|
||||
|
||||
// 환경 변수 설정
|
||||
dotenv.config();
|
||||
dotenv.config({ path: '.env.production' });
|
||||
|
||||
const app = express();
|
||||
const port = process.env.PORT || 4000;
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
// 헬스체크 API
|
||||
app.get('/api/health', (req: Request, res: Response) => {
|
||||
res.status(200).json({ status: 'ok', message: '백엔드 서버가 정상 구동 중입니다.' });
|
||||
});
|
||||
|
||||
// AI 일지 작성 API
|
||||
app.post('/api/diary/generate', async (req: Request, res: Response) => {
|
||||
const { content, keywords, childName } = req.body;
|
||||
|
||||
// AI 설정 값 읽기 (env.production에 설정 예정)
|
||||
const apiKey = process.env.AI_API_KEY;
|
||||
const modelName = process.env.AI_MODEL || 'gemini-1.5-flash';
|
||||
|
||||
if (!apiKey) {
|
||||
return res.status(500).json({
|
||||
error: 'AI_API_KEY 환경 변수가 설정되지 않았습니다. .env.production 파일을 확인해 주세요.'
|
||||
});
|
||||
}
|
||||
|
||||
if (!content && (!keywords || keywords.length === 0)) {
|
||||
return res.status(400).json({ error: '일지 내용 또는 키워드를 입력해 주세요.' });
|
||||
}
|
||||
|
||||
try {
|
||||
const ai = new GoogleGenAI({ apiKey });
|
||||
const model = ai.getGenerativeModel({ model: modelName });
|
||||
|
||||
const prompt = `
|
||||
당신은 유치원 교사입니다. 교사가 작성한 간단한 메모나 키워드를 바탕으로 학부모님께 보낼 정성스럽고 자연스러운 알림장(유치원 일지)을 작성해 주세요.
|
||||
|
||||
[아이 이름]
|
||||
${childName || '아이'}
|
||||
|
||||
[교사 작성 내용]
|
||||
${content || ''}
|
||||
|
||||
[키워드]
|
||||
${keywords ? keywords.join(', ') : ''}
|
||||
|
||||
[작성 지침]
|
||||
1. 정중하고 따뜻한 어조(해요체)로 작성해 주세요.
|
||||
2. 아이의 활동을 구체적이고 긍정적으로 묘사해 주세요.
|
||||
3. 너무 길지 않고 가독성 좋게 단락을 나누어 작성해 주세요.
|
||||
4. 학부모님께 드리는 인사와 마무리 멘트를 포함해 주세요.
|
||||
`;
|
||||
|
||||
const result = await model.generateContent(prompt);
|
||||
const responseText = result.response.text();
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
originalContent: content,
|
||||
generatedContent: responseText,
|
||||
modelUsed: modelName
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('AI 생성 에러:', error);
|
||||
return res.status(500).json({
|
||||
error: 'AI 일지 작성 중 에러가 발생했습니다.',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 일지 저장 API (DB 연동)
|
||||
app.post('/api/diary/save', async (req: Request, res: Response) => {
|
||||
const { childName, originalContent, generatedContent } = req.body;
|
||||
|
||||
try {
|
||||
const newDiary = await prisma.diary.create({
|
||||
data: {
|
||||
childName: childName || '미지정',
|
||||
originalContent: originalContent || '',
|
||||
generatedContent: generatedContent || '',
|
||||
}
|
||||
});
|
||||
|
||||
return res.status(201).json({
|
||||
success: true,
|
||||
message: '일지가 데이터베이스에 정상적으로 저장되었습니다.',
|
||||
data: newDiary
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('DB 저장 에러:', error);
|
||||
return res.status(500).json({
|
||||
error: '데이터베이스 저장 중 에러가 발생했습니다.',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 전체 일지 조회 API
|
||||
app.get('/api/diary/list', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const diaries = await prisma.diary.findMany({
|
||||
orderBy: {
|
||||
createdAt: 'desc'
|
||||
}
|
||||
});
|
||||
return res.status(200).json({ success: true, data: diaries });
|
||||
} catch (error: any) {
|
||||
console.error('DB 조회 에러:', error);
|
||||
return res.status(500).json({
|
||||
error: '데이터베이스 조회 중 에러가 발생했습니다.',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`서버가 http://localhost:${port} 에서 구동 중입니다.`);
|
||||
});
|
||||
Reference in New Issue
Block a user