edumanagerpro2/manager/scratch/restore_and_link_students.js

177 lines
6.4 KiB
JavaScript

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import pg from 'pg';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const pool = new pg.Pool({
connectionString: 'postgresql://edumanager:EduManager2026!Seguro@150.230.87.131:5432/edumanager'
});
const photoMapping = {
// 1. ANA CLARA DA SILVA NASCIMENTO (17:57:55)
'e917ffe5-70d6-451e-9120-7692ec8d7024': '/storage/fotos-alunos/student_1777139875689_4l971l.webp',
// 2. ANTÔNIA CERMILANE PEREIRA PINHEIRO (17:58:31)
'b9a7ddee-e03f-411f-9ef2-d22629d38e35': '/storage/fotos-alunos/student_1777139911929_21v6av.webp',
// 3. DOUGLAS EMANUEL DE SOUSA PEREIRA (17:59:02)
'0ab24299-f583-40eb-8812-d6005ebc50a8': '/storage/fotos-alunos/student_1777139942925_aoxyls.webp',
// 4. EVILLA PINHEIRO DA SILVA BORGES (18:00:08)
'311709fb-68ab-4168-8684-887b5ec2d731': '/storage/fotos-alunos/student_1777140008401_3966cd.webp',
// 5. GABRIELY CAETANO DA SILVA (18:00:38)
'0ef75207-3ab1-4524-b737-b543e804d3f0': '/storage/fotos-alunos/student_1777140038192_xntcja.webp',
// 6. KARLA BIANCA PINHEIRO TRINDADE (18:01:06)
'c7e2d021-52ab-4229-8550-1aa8549507b3': '/storage/fotos-alunos/student_1777140066701_dfzecd.webp',
// 7. NAPOLEÃO DA SILVA CARDOSO (18:01:38)
'3653aea3-7e7e-49d6-b372-068863084a27': '/storage/fotos-alunos/student_1777140098875_tcan7k.webp',
// 8. Sidney Gomes da silva (15:01)
'5a231b04-b95c-4026-ba37-bc7b8144f646': '/storage/fotos-alunos/student_1776870119652_z0tdgp.webp',
// 9. MARIA LOHANNY ROQUE DA SILVA (May 2)
'05de4757-d36f-4de6-9e57-5792d13ad3e7': '/storage/fotos-alunos/student_1777743393187_rf50t.webp'
};
async function run() {
const backupPath = path.join(__dirname, '../backup_supabase_2026-04-19.json');
console.log(`Lendo dados completos do backup original de: ${backupPath}`);
if (!fs.existsSync(backupPath)) {
console.error('ERRO: Arquivo de backup original não encontrado!');
process.exit(1);
}
const raw = fs.readFileSync(backupPath, 'utf8');
const backupData = JSON.parse(raw);
const backupStudents = backupData.students || [];
try {
// 1. Atualizar registros individuais na tabela alunos
console.log('Atualizando a tabela "alunos" no PostgreSQL...');
for (const bs of backupStudents) {
const mappedPhoto = photoMapping[bs.id];
if (!mappedPhoto) continue;
const birthDate = bs.birthDate ? bs.birthDate.split('T')[0] : null;
const rgIssueDate = bs.rgIssueDate ? bs.rgIssueDate.split('T')[0] : null;
const guardianBirthDate = bs.guardianBirthDate ? bs.guardianBirthDate.split('T')[0] : null;
const registrationDate = bs.registrationDate ? bs.registrationDate.split('T')[0] : null;
const query = `
UPDATE alunos
SET
rg = $1,
data_nascimento = $2,
rg_data_emissao = $3,
cep = $4,
rua = $5,
numero = $6,
bairro = $7,
cidade = $8,
estado = $9,
tem_responsavel = $10,
nome_responsavel = $11,
cpf_responsavel = $12,
telefone_responsavel = $13,
data_nascimento_responsavel = $14,
numero_matricula = $15,
data_matricula = $16,
modelo_contrato_id = $17,
foto_url = $18,
senha_portal = $19
WHERE id = $20
`;
const values = [
bs.rg || '',
birthDate,
rgIssueDate,
bs.addressZip || '',
bs.addressStreet || '',
bs.addressNumber || '',
bs.addressNeighborhood || '',
bs.addressCity || '',
bs.addressState || '',
bs.hasGuardian || false,
bs.guardianName || '',
bs.guardianCpf || '',
bs.guardianPhone || '',
guardianBirthDate,
bs.enrollmentNumber || null,
registrationDate,
bs.contractTemplateId || 'default-template',
mappedPhoto,
bs.portalPassword || null,
bs.id
];
await pool.query(query, values);
console.log(`✅ [SQL] Restaurado e Vinculado: ${bs.name} (${bs.id}) -> ${mappedPhoto}`);
}
// 2. Buscar, atualizar e salvar o espelho JSONB em school_data
console.log('\nSincronizando espelho JSONB na tabela "school_data"...');
const { rows } = await pool.query('SELECT data FROM school_data WHERE id = 1');
const schoolData = rows[0]?.data;
if (!schoolData) {
console.error('ERRO: Registro do school_data com ID=1 não encontrado!');
return;
}
let updatedJsonCount = 0;
if (schoolData.students && Array.isArray(schoolData.students)) {
for (const s of schoolData.students) {
const bs = backupStudents.find(x => x.id === s.id);
const mappedPhoto = photoMapping[s.id];
if (bs && mappedPhoto) {
s.photo = mappedPhoto;
s.foto_url = mappedPhoto;
s.birthDate = bs.birthDate;
s.rg = bs.rg || '';
s.rgIssueDate = bs.rgIssueDate;
s.addressZip = bs.addressZip || '';
s.addressStreet = bs.addressStreet || '';
s.addressNumber = bs.addressNumber || '';
s.addressNeighborhood = bs.addressNeighborhood || '';
s.addressCity = bs.addressCity || '';
s.addressState = bs.addressState || '';
s.hasGuardian = bs.hasGuardian || false;
s.guardianName = bs.guardianName || '';
s.guardianCpf = bs.guardianCpf || '';
s.guardianPhone = bs.guardianPhone || '';
s.guardianBirthDate = bs.guardianBirthDate;
s.enrollmentNumber = bs.enrollmentNumber || null;
s.registrationDate = bs.registrationDate;
s.portalPassword = bs.portalPassword || null;
updatedJsonCount++;
console.log(`✅ [JSONB] Atualizado no mirror: ${s.name} (${s.id})`);
}
}
// Salvar de volta ao banco de dados usando COMMIT para persistir a gravação em modo leitura/gravação
await pool.query('COMMIT');
await pool.query('BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED');
await pool.query('UPDATE school_data SET data = $1 WHERE id = 1', [JSON.stringify(schoolData)]);
await pool.query('COMMIT');
console.log(`\n🎉 Sincronização concluída! ${updatedJsonCount} registros atualizados com sucesso no JSONB.`);
}
} catch (err) {
console.error('ERRO CRÍTICO DURANTE A RESTAURAÇÃO:', err);
} finally {
await pool.end();
}
}
run();