edumanagerpro2/manager/recover_exams.js

123 lines
4.7 KiB
JavaScript

import pg from 'pg';
import fs from 'fs';
import path from 'path';
const DATABASE_URL = process.env.DATABASE_URL || 'postgresql://edumanager:EduManager2026!Seguro@150.230.87.131:5432/edumanager';
const pool = new pg.Pool({ connectionString: DATABASE_URL });
async function recover() {
const client = await pool.connect();
try {
console.log('🔄 Iniciando processo de recuperação de Provas e Questões...');
// Tentar ler do backup original
let backupPath = '/app/backup_supabase_2026-04-19.json';
if (!fs.existsSync(backupPath)) {
backupPath = path.join(process.cwd(), 'backup_supabase_2026-04-19.json');
}
if (!fs.existsSync(backupPath)) {
throw new Error(`Arquivo de backup não encontrado em: ${backupPath}`);
}
console.log(`Lendo dados de backup em: ${backupPath}`);
const rawData = fs.readFileSync(backupPath, 'utf8');
const data = JSON.parse(rawData);
if (!data.exams || !Array.isArray(data.exams)) {
throw new Error('Chave "exams" não encontrada ou não é um array no backup.');
}
console.log(`Encontradas ${data.exams.length} provas no arquivo de backup.`);
await client.query('BEGIN');
// Habilitar a gravação das provas no Postgres
let countProvasInseridas = 0;
let countQuestoesInseridas = 0;
for (const e of data.exams) {
if (!e.id || !e.title) continue;
// Inserir Prova
await client.query(
`INSERT INTO provas (id, turma_id, disciplina_id, periodo_id, titulo, duracao_minutos, status, permitir_refacao, is_deleted, evaluation_type, max_score)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
ON CONFLICT (id) DO UPDATE SET
turma_id = COALESCE(provas.turma_id, EXCLUDED.turma_id),
disciplina_id = COALESCE(provas.disciplina_id, EXCLUDED.disciplina_id),
periodo_id = COALESCE(provas.periodo_id, EXCLUDED.periodo_id),
titulo = EXCLUDED.titulo,
duracao_minutos = EXCLUDED.duracao_minutos,
status = EXCLUDED.status,
permitir_refacao = EXCLUDED.permitir_refacao,
evaluation_type = EXCLUDED.evaluation_type,
max_score = EXCLUDED.max_score`,
[
e.id,
e.classId || e.turma_id || null,
e.subjectId || e.disciplina_id || null,
e.periodId || e.periodo_id || null,
e.title || e.titulo,
e.durationMinutes || e.duracao_minutos || 60,
e.status || 'draft',
e.allowRetake || e.permitir_refacao || false,
e.isDeleted || e.is_deleted || false,
e.evaluationType || e.evaluation_type || 'exam',
e.maxScore !== undefined ? Number(e.maxScore) : (e.max_score !== undefined ? Number(e.max_score) : 10.0)
]
);
countProvasInseridas++;
// Inserir Questões da Prova
if (e.questions && Array.isArray(e.questions)) {
let ordem = 0;
for (const q of e.questions) {
if (!q.id || !q.text) continue;
await client.query(
`INSERT INTO questoes_provas (id, prova_id, texto, opcoes, indice_correto, ordem, imagem_url)
VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (id) DO UPDATE SET
texto = EXCLUDED.texto,
opcoes = EXCLUDED.opcoes,
indice_correto = EXCLUDED.indice_correto,
ordem = EXCLUDED.ordem,
imagem_url = COALESCE(questoes_provas.imagem_url, EXCLUDED.imagem_url)`,
[
q.id,
e.id,
q.text,
JSON.stringify(q.options || []),
q.correctOptionIndex !== undefined ? q.correctOptionIndex : (q.indice_correto ?? 0),
q.order !== undefined ? q.order : (q.ordem ?? ordem++),
q.imageUrl || q.imagem_url || null
]
);
countQuestoesInseridas++;
}
}
}
console.log(`Restaurando chaves no school_data JSON da tabela school_data no Postgres...`);
const { rows } = await client.query('SELECT data FROM school_data WHERE id = 1');
if (rows[0]?.data) {
const currentJson = rows[0].data;
// Atualizar a chave exams no JSON
currentJson.exams = data.exams;
await client.query('UPDATE school_data SET data = $1, updated_at = NOW() WHERE id = 1', [JSON.stringify(currentJson)]);
console.log('Chave exams atualizada no JSON school_data da tabela.');
}
await client.query('COMMIT');
console.log(`✅ Sucesso! Foram restauradas ${countProvasInseridas} provas e ${countQuestoesInseridas} questões no PostgreSQL.`);
} catch (err) {
await client.query('ROLLBACK');
console.error('❌ Erro na recuperação:', err);
} finally {
client.release();
await pool.end();
}
}
recover();