🚀 Auto-deploy: Implementação das ferramentas Garatujas e BrincarAtivo

This commit is contained in:
2026-06-04 23:44:53 +00:00
parent 6866d565ec
commit dcabe19edd
3 changed files with 984 additions and 0 deletions
+268
View File
@@ -789,6 +789,254 @@ Retorne a resposta estruturada estritamente em Markdown. Separe as seções usan
}
});
// ============================================================
// ROTAS DO GARATUJAS (ANALISADOR DE TRAÇADO INFANTIL)
// ============================================================
app.post('/api/garatujas/analyze', requireAuth, multerUpload.single('image'), async (req, res) => {
const { alunoName } = req.body;
const file = req.file;
if (!alunoName) {
return res.status(400).json({ error: 'O nome do aluno é obrigatório.' });
}
if (!file) {
return res.status(400).json({ error: 'A foto do desenho é obrigatória.' });
}
try {
const fs = require('fs');
const mediaDir = path.join(__dirname, 'public', 'generated-media');
if (!fs.existsSync(mediaDir)) {
fs.mkdirSync(mediaDir, { recursive: true });
}
const ext = path.extname(file.originalname) || '.png';
const fileName = `garatuja_${Date.now()}${ext}`;
const filePath = path.join(mediaDir, fileName);
fs.writeFileSync(filePath, file.buffer);
const imageUrl = `/generated-media/${fileName}`;
const base64Image = file.buffer.toString('base64');
const mimeType = file.mimetype || 'image/png';
const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENROUTER_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'google/gemini-2.5-flash',
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: `Você é um psicopedagogo e especialista em desenvolvimento infantil no Brasil.
Analise a imagem deste desenho/rabisco feito pelo aluno(a) "${alunoName}" (até 6 anos de idade).
Identifique e descreva com base na literatura científica (como Piaget, Luquet, Lowenfeld):
1. O estágio do desenho infantil em que a criança se encontra (ex: Garatuja Desordenada, Garatuja Ordenada, Pré-Esquematismo, etc.) justificando com elementos visuais identificados no desenho.
2. A análise do desenvolvimento cognitivo e da coordenação motora fina expressa nos traços.
3. Propostas práticas de estimulação pedagógica personalizadas para o professor aplicar com o aluno "${alunoName}" em sala de aula para avançar para o próximo estágio.
Retorne a resposta estruturada em Markdown, usando títulos claros:
# Estágio do Desenho e Análise Psicomotora
[Sua análise aqui]
# Diagnóstico de Desenvolvimento Cognitivo
[Seu diagnóstico aqui]
# Sugestões de Atividades para Estimular ${alunoName}
[Suas propostas aqui]`
},
{
type: 'image_url',
image_url: {
url: `data:${mimeType};base64,${base64Image}`
}
}
]
}
]
})
});
if (!response.ok) {
const errText = await response.text();
throw new Error(`Erro na API de visão: ${errText}`);
}
const resData = await response.json();
const analise = resData.choices?.[0]?.message?.content || '';
const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000';
const dbRes = await dbPool.query(
`INSERT INTO escola.garatujas (usuario_id, aluno_name, image_url, analise)
VALUES ($1, $2, $3, $4) RETURNING id, created_at`,
[usuarioId, alunoName, imageUrl, analise]
);
res.json({
success: true,
id: dbRes.rows[0].id,
alunoName,
imageUrl,
analise,
createdAt: dbRes.rows[0].created_at
});
} catch (err) {
console.error('Erro na análise de garatujas:', err);
res.status(500).json({ error: 'Erro ao analisar imagem: ' + err.message });
}
});
app.get('/api/garatujas/list', requireAuth, async (req, res) => {
const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000';
try {
const dbRes = await dbPool.query(
`SELECT id, aluno_name as "alunoName", image_url as "imageUrl", created_at as "createdAt"
FROM escola.garatujas
WHERE usuario_id = $1
ORDER BY created_at DESC`,
[usuarioId]
);
res.json(dbRes.rows);
} catch (err) {
console.error('Erro ao listar garatujas:', err);
res.status(500).json({ error: 'Erro ao obter histórico de desenhos.' });
}
});
app.get('/api/garatujas/:id', requireAuth, async (req, res) => {
const { id } = req.params;
const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000';
try {
const dbRes = await dbPool.query(
`SELECT id, aluno_name as "alunoName", image_url as "imageUrl", analise, created_at as "createdAt"
FROM escola.garatujas
WHERE id = $1 AND usuario_id = $2`,
[id, usuarioId]
);
if (dbRes.rows.length === 0) {
return res.status(404).json({ error: 'Análise não encontrada.' });
}
res.json(dbRes.rows[0]);
} catch (err) {
console.error('Erro ao buscar garatuja:', err);
res.status(500).json({ error: 'Erro ao buscar análise.' });
}
});
// ============================================================
// ROTAS DO BRINCARATIVO (CIRCUITOS PSICOMOTORES E BRINCADEIRAS)
// ============================================================
app.post('/api/brincar-ativo/generate', requireAuth, async (req, res) => {
const { faixaEtaria, recursos } = req.body;
if (!faixaEtaria) {
return res.status(400).json({ error: 'A faixa etária é obrigatória.' });
}
if (!recursos) {
return res.status(400).json({ error: 'A descrição dos recursos é obrigatória.' });
}
try {
const prompt = `Você é um educador físico e pedagogo especializado na Educação Infantil (crianças de 0 a 6 anos) de acordo com a BNCC no Brasil.
Gere uma proposta de circuito psicomotor ou brincadeira ativa adequada para a seguinte faixa etária e com os recursos disponíveis:
Faixa Etária: ${faixaEtaria}
Recursos e Materiais Disponíveis: ${recursos}
Instruções para o conteúdo:
1. Dê um título lúdico e atraente para a atividade.
2. Especifique os Objetivos de Aprendizagem e Desenvolvimento da BNCC (incluindo códigos, como EI01CG02, EI02CG05, etc.).
3. Descreva o Passo a Passo detalhado de como montar o circuito/brincadeira no espaço e como guiar as crianças.
4. Diga o que o professor deve observar durante a atividade para avaliar o desenvolvimento psicomotor dos alunos.
Retorne a resposta estritamente em Markdown estruturado:
# Atividade: [Nome Lúdico]
**Faixa Etária:** ${faixaEtaria}
**Campos de Experiência (BNCC):** [Campos e Códigos]
## 📋 Objetivos
[Objetivos]
## 🛠️ Como Montar e Conduzir
[Passo a passo]
## 🔍 O que Observar (Avaliação Formativa)
[Dicas de observação]`;
const aiResponse = await callMinimax({
system: "Você é um especialista em educação física e psicomotricidade na educação infantil brasileira.",
messages: [{ role: 'user', content: prompt }],
temperature: 0.5,
max_tokens: 3000
});
const atividade = aiResponse.text || '';
const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000';
const dbRes = await dbPool.query(
`INSERT INTO escola.brincar_ativo (usuario_id, faixa_etaria, recursos, atividade)
VALUES ($1, $2, $3, $4) RETURNING id, created_at`,
[usuarioId, faixaEtaria, recursos, atividade]
);
res.json({
success: true,
id: dbRes.rows[0].id,
faixaEtaria,
recursos,
atividade,
createdAt: dbRes.rows[0].created_at
});
} catch (err) {
console.error('Erro no BrincarAtivo:', err);
res.status(500).json({ error: 'Erro ao gerar atividade com a IA: ' + err.message });
}
});
app.get('/api/brincar-ativo/list', requireAuth, async (req, res) => {
const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000';
try {
const dbRes = await dbPool.query(
`SELECT id, faixa_etaria as "faixaEtaria", recursos, created_at as "createdAt"
FROM escola.brincar_ativo
WHERE usuario_id = $1
ORDER BY created_at DESC`,
[usuarioId]
);
res.json(dbRes.rows);
} catch (err) {
console.error('Erro ao listar atividades:', err);
res.status(500).json({ error: 'Erro ao obter lista de atividades.' });
}
});
app.get('/api/brincar-ativo/:id', requireAuth, async (req, res) => {
const { id } = req.params;
const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000';
try {
const dbRes = await dbPool.query(
`SELECT id, faixa_etaria as "faixaEtaria", recursos, atividade, created_at as "createdAt"
FROM escola.brincar_ativo
WHERE id = $1 AND usuario_id = $2`,
[id, usuarioId]
);
if (dbRes.rows.length === 0) {
return res.status(404).json({ error: 'Atividade não encontrada.' });
}
res.json(dbRes.rows[0]);
} catch (err) {
console.error('Erro ao buscar atividade:', err);
res.status(500).json({ error: 'Erro ao buscar atividade.' });
}
});
// Rota GET para obter configurações do agente
app.get('/api/agent-config', requireAuth, (req, res) => {
const config = readAgentConfig();
@@ -968,6 +1216,26 @@ async function initDatabase() {
descricao_fisica_en TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Garatujas (Analisador de Traçado Infantil)
CREATE TABLE IF NOT EXISTS escola.garatujas (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
usuario_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
aluno_name VARCHAR(255) NOT NULL,
image_url TEXT NOT NULL,
analise TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- BrincarAtivo (Circuitos Psicomotores e Brincadeiras)
CREATE TABLE IF NOT EXISTS escola.brincar_ativo (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
usuario_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
faixa_etaria VARCHAR(100) NOT NULL,
recursos TEXT NOT NULL,
atividade TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
`);
// Garantir que a coluna character_description_english exista na tabela projetos_comics