Initial commit: MetisClass - Plataforma Educacional
This commit is contained in:
145
src/app/api/generate/route.ts
Normal file
145
src/app/api/generate/route.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "@/lib/auth";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { generateWithGemini } from "@/lib/gemini";
|
||||
|
||||
const GENERATION_PROMPTS = {
|
||||
LESSON_PLAN: `Você é um especialista em educação brasileira. Crie um plano de aula completo e detalhado seguindo a estrutura abaixo:
|
||||
|
||||
## Dados da Aula
|
||||
- **Disciplina:** {subject}
|
||||
- **Ano/Série:** {grade}
|
||||
- **Tema:** {topic}
|
||||
- **Duração:** {duration}
|
||||
|
||||
## Estrutura do Plano
|
||||
|
||||
### 1. Objetivos de Aprendizagem
|
||||
- Objetivo geral
|
||||
- Objetivos específicos (3-5)
|
||||
- Competências da BNCC relacionadas
|
||||
|
||||
### 2. Conteúdos
|
||||
- Conceituais
|
||||
- Procedimentais
|
||||
- Atitudinais
|
||||
|
||||
### 3. Metodologia
|
||||
- Abordagem pedagógica
|
||||
- Estratégias de ensino
|
||||
- Recursos didáticos necessários
|
||||
|
||||
### 4. Desenvolvimento da Aula
|
||||
- Momento inicial (aquecimento/motivação)
|
||||
- Desenvolvimento (atividades principais)
|
||||
- Fechamento (síntese/avaliação)
|
||||
|
||||
### 5. Avaliação
|
||||
- Critérios de avaliação
|
||||
- Instrumentos avaliativos
|
||||
- Indicadores de aprendizagem
|
||||
|
||||
### 6. Referências e Materiais de Apoio
|
||||
|
||||
Seja detalhado, prático e alinhado às diretrizes da BNCC. Use linguagem clara e objetiva.`,
|
||||
|
||||
EXAM: `Você é um especialista em avaliação educacional. Crie uma prova/lista de exercícios seguindo os parâmetros:
|
||||
|
||||
- **Disciplina:** {subject}
|
||||
- **Ano/Série:** {grade}
|
||||
- **Tema:** {topic}
|
||||
- **Número de questões:** {questionCount}
|
||||
- **Tipos de questões:** {questionTypes}
|
||||
- **Nível de dificuldade:** {difficulty}
|
||||
|
||||
Para cada questão, inclua:
|
||||
- Enunciado claro e objetivo
|
||||
- Alternativas (se múltipla escolha)
|
||||
- Gabarito
|
||||
- Habilidade BNCC relacionada
|
||||
|
||||
Varie os tipos de questões e níveis de dificuldade progressivamente.`,
|
||||
};
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const session = await getServerSession(authOptions);
|
||||
|
||||
if (!session?.user?.id) {
|
||||
return NextResponse.json({ error: "Não autorizado" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: session.user.id },
|
||||
select: { credits: true, plan: true },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json({ error: "Usuário não encontrado" }, { status: 404 });
|
||||
}
|
||||
|
||||
if (user.credits <= 0 && user.plan === "FREE") {
|
||||
return NextResponse.json(
|
||||
{ error: "Créditos insuficientes. Faça upgrade para continuar." },
|
||||
{ status: 403 }
|
||||
);
|
||||
}
|
||||
|
||||
const body = await request.json();
|
||||
const { type, ...params } = body;
|
||||
|
||||
if (!type || !GENERATION_PROMPTS[type as keyof typeof GENERATION_PROMPTS]) {
|
||||
return NextResponse.json({ error: "Tipo de geração inválido" }, { status: 400 });
|
||||
}
|
||||
|
||||
// Build prompt
|
||||
let prompt = GENERATION_PROMPTS[type as keyof typeof GENERATION_PROMPTS];
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
prompt = prompt.replace(`{${key}}`, value as string);
|
||||
});
|
||||
|
||||
// Call Gemini API
|
||||
const content = await generateWithGemini(
|
||||
prompt,
|
||||
"Você é um assistente especializado em educação brasileira, ajudando professores a criar conteúdos pedagógicos de alta qualidade."
|
||||
);
|
||||
|
||||
if (!content) {
|
||||
throw new Error("Resposta vazia da IA");
|
||||
}
|
||||
|
||||
// Save generation
|
||||
const generation = await prisma.generation.create({
|
||||
data: {
|
||||
userId: session.user.id,
|
||||
type: type as any,
|
||||
title: params.topic || params.title || "Sem título",
|
||||
content: { text: content },
|
||||
prompt: prompt,
|
||||
model: "gemini-2.0-flash",
|
||||
tokens: 0,
|
||||
},
|
||||
});
|
||||
|
||||
// Deduct credits (only for FREE plan)
|
||||
if (user.plan === "FREE") {
|
||||
await prisma.user.update({
|
||||
where: { id: session.user.id },
|
||||
data: { credits: { decrement: 1 } },
|
||||
});
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
id: generation.id,
|
||||
content: content,
|
||||
tokens: 0,
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error("Generation error:", error);
|
||||
return NextResponse.json(
|
||||
{ error: error.message || "Erro ao gerar conteúdo" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user