194 lines
6.7 KiB
JavaScript
194 lines
6.7 KiB
JavaScript
/**
|
|
* Script: Export Teacher Profiles to JSON
|
|
* Xuất chi tiết thông tin tất cả teachers ra file JSON
|
|
*
|
|
* Usage:
|
|
* node src/scripts/export-teachers-info.js
|
|
* node src/scripts/export-teachers-info.js --output=teachers.json
|
|
*/
|
|
|
|
require('dotenv').config();
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { sequelize, TeacherDetail, UserProfile, UsersAuth } = require('../models');
|
|
|
|
async function exportTeachersInfo() {
|
|
console.log('📤 Exporting All Teachers Information...\n');
|
|
|
|
try {
|
|
await sequelize.authenticate();
|
|
console.log('✅ Database connected\n');
|
|
|
|
// Get all teachers
|
|
const teachers = await TeacherDetail.findAll({
|
|
order: [['created_at', 'ASC']],
|
|
});
|
|
|
|
console.log(`📊 Found ${teachers.length} teachers\n`);
|
|
console.log('Processing...\n');
|
|
|
|
const exportData = [];
|
|
|
|
for (const teacher of teachers) {
|
|
// Get auth info
|
|
const userAuth = await UsersAuth.findByPk(teacher.user_id, {
|
|
attributes: ['id', 'username', 'email', 'is_active', 'last_login', 'login_count', 'qr_version'],
|
|
});
|
|
|
|
// Get profile info
|
|
const userProfile = await UserProfile.findOne({
|
|
where: { user_id: teacher.user_id },
|
|
});
|
|
|
|
const teacherData = {
|
|
// Teacher Details
|
|
teacher_id: teacher.id,
|
|
teacher_code: teacher.teacher_code,
|
|
teacher_type: teacher.teacher_type,
|
|
status: teacher.status,
|
|
qualification: teacher.qualification,
|
|
specialization: teacher.specialization,
|
|
hire_date: teacher.hire_date,
|
|
training_hours: teacher.training_hours,
|
|
last_training_date: teacher.last_training_date,
|
|
training_score_avg: teacher.training_score_avg,
|
|
skill_tags: teacher.skill_tags,
|
|
certifications: teacher.certifications,
|
|
created_at: teacher.created_at,
|
|
updated_at: teacher.updated_at,
|
|
|
|
// Auth Info
|
|
user_id: teacher.user_id,
|
|
username: userAuth?.username,
|
|
email: userAuth?.email,
|
|
is_active: userAuth?.is_active,
|
|
last_login: userAuth?.last_login,
|
|
login_count: userAuth?.login_count,
|
|
qr_version: userAuth?.qr_version,
|
|
|
|
// Profile Info
|
|
has_profile: !!userProfile,
|
|
profile: userProfile ? {
|
|
profile_id: userProfile.id,
|
|
full_name: userProfile.full_name,
|
|
first_name: userProfile.first_name,
|
|
last_name: userProfile.last_name,
|
|
phone: userProfile.phone,
|
|
date_of_birth: userProfile.date_of_birth,
|
|
gender: userProfile.gender,
|
|
address: userProfile.address,
|
|
school_id: userProfile.school_id,
|
|
city: userProfile.city,
|
|
district: userProfile.district,
|
|
avatar_url: userProfile.avatar_url,
|
|
etc: userProfile.etc,
|
|
created_at: userProfile.created_at,
|
|
updated_at: userProfile.updated_at,
|
|
} : null,
|
|
};
|
|
|
|
exportData.push(teacherData);
|
|
}
|
|
|
|
// Summary statistics
|
|
const stats = {
|
|
total_teachers: exportData.length,
|
|
with_profile: exportData.filter(t => t.has_profile).length,
|
|
without_profile: exportData.filter(t => !t.has_profile).length,
|
|
active: exportData.filter(t => t.is_active).length,
|
|
inactive: exportData.filter(t => !t.is_active).length,
|
|
by_type: {
|
|
foreign: exportData.filter(t => t.teacher_type === 'foreign').length,
|
|
homeroom: exportData.filter(t => t.teacher_type === 'homeroom').length,
|
|
subject: exportData.filter(t => t.teacher_type === 'subject').length,
|
|
assistant: exportData.filter(t => t.teacher_type === 'assistant').length,
|
|
},
|
|
by_status: {
|
|
active: exportData.filter(t => t.status === 'active').length,
|
|
on_leave: exportData.filter(t => t.status === 'on_leave').length,
|
|
resigned: exportData.filter(t => t.status === 'resigned').length,
|
|
},
|
|
};
|
|
|
|
// Parse output filename
|
|
const args = process.argv.slice(2);
|
|
const outputArg = args.find(arg => arg.startsWith('--output='));
|
|
const outputFileName = outputArg ? outputArg.split('=')[1] : 'teachers-export.json';
|
|
const outputPath = path.join(process.cwd(), '..', 'data', outputFileName);
|
|
|
|
// Prepare export object
|
|
const exportObject = {
|
|
exported_at: new Date().toISOString(),
|
|
statistics: stats,
|
|
teachers: exportData,
|
|
};
|
|
|
|
// Write to file
|
|
fs.writeFileSync(outputPath, JSON.stringify(exportObject, null, 2), 'utf8');
|
|
|
|
console.log('✅ Export completed!\n');
|
|
console.log('📊 Statistics:');
|
|
console.log('='.repeat(60));
|
|
console.log(`Total Teachers: ${stats.total_teachers}`);
|
|
console.log(` ✅ With Profile: ${stats.with_profile}`);
|
|
console.log(` ❌ Without Profile: ${stats.without_profile}`);
|
|
console.log(` 🟢 Active: ${stats.active}`);
|
|
console.log(` 🔴 Inactive: ${stats.inactive}`);
|
|
console.log('\nBy Teacher Type:');
|
|
console.log(` Foreign: ${stats.by_type.foreign}`);
|
|
console.log(` Homeroom: ${stats.by_type.homeroom}`);
|
|
console.log(` Subject: ${stats.by_type.subject}`);
|
|
console.log(` Assistant: ${stats.by_type.assistant}`);
|
|
console.log('\nBy Status:');
|
|
console.log(` Active: ${stats.by_status.active}`);
|
|
console.log(` On Leave: ${stats.by_status.on_leave}`);
|
|
console.log(` Resigned: ${stats.by_status.resigned}`);
|
|
console.log('='.repeat(60));
|
|
console.log(`\n📁 File saved: ${outputPath}`);
|
|
console.log(` Size: ${(fs.statSync(outputPath).size / 1024).toFixed(2)} KB\n`);
|
|
|
|
// Show sample data
|
|
console.log('📋 Sample Teacher Data (first 3):\n');
|
|
exportData.slice(0, 3).forEach((t, i) => {
|
|
console.log(`${i + 1}. ${t.teacher_code} (${t.teacher_type})`);
|
|
console.log(` Username: ${t.username}`);
|
|
console.log(` Email: ${t.email}`);
|
|
console.log(` Full Name: ${t.profile?.full_name || 'N/A'}`);
|
|
console.log(` Phone: ${t.profile?.phone || 'N/A'}`);
|
|
console.log(` Status: ${t.status} | Active: ${t.is_active}`);
|
|
console.log('');
|
|
});
|
|
|
|
return {
|
|
outputPath,
|
|
stats,
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('❌ Export failed:', error.message);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
console.log('\n🚀 Teacher Profile Export Tool\n');
|
|
|
|
try {
|
|
const result = await exportTeachersInfo();
|
|
|
|
console.log('🎉 Done! You can now view the exported file:\n');
|
|
console.log(` cat ${result.outputPath}`);
|
|
console.log(` or open it in a text editor/VS Code\n`);
|
|
|
|
process.exit(0);
|
|
|
|
} catch (error) {
|
|
console.error('\n❌ Error:', error.message);
|
|
console.error(error.stack);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Run
|
|
main();
|