import { pool } from '../services/db.service'; import { resolve } from 'node:path'; /** * Genera el esquema de la base de datos automáticamente */ async function generateSchema() { try { const rows = await pool.query(` SELECT TABLE_NAME as t, COLUMN_NAME as f, DATA_TYPE as T, COLUMN_TYPE as fT, EXTRA as e, COLUMN_KEY as k FROM information_schema.columns WHERE table_schema = DATABASE() ORDER BY TABLE_NAME, ORDINAL_POSITION `); const data = rows.reduce((acc, { t, f, T, fT, e, k }) => { if (!acc[t]) acc[t] = {}; // Mapeo de tipos let type = 'text'; if (['int', 'decimal', 'float', 'double'].includes(T)) { type = 'numeric'; } else if (['date', 'datetime', 'timestamp'].includes(T)) { type = T === 'date' ? 'date' : 'datetime'; } else if (T === 'tinyint' && fT.includes('(1)')) { type = 'boolean'; } else if (T === 'enum') { type = 'select'; } const hide = f.startsWith('id') || f === 'password' || f === 'token'; const virt = e.toLowerCase().includes('generated'); const key = k === 'PRI' ? 'PK' : k === 'UNI' ? 'UK' : k === 'MUL' ? 'FK' : false; acc[t][f] = { field: f, header: f.replace(/_/g, ' ').toUpperCase(), type, hide, virt, key, editable: !(hide || key === 'PK' || virt) }; return acc; }, {}); const outPath = resolve('./server/lib/schema.json'); // JSON compacto para ahorrar bytes pero manteniendo legibilidad por tabla const json = JSON.stringify(data, null, 2) .replace(/\{\n\s+"field":[\s\S]+?\n\s+\}/g, m => m.replace(/\s*\n\s*/g, ' ')); await Bun.write(outPath, json); console.log(`✅ Esquema generado: ${outPath}`); console.log(`📊 Tablas: ${Object.keys(data).length}`); } catch (error) { console.error('❌ Error:', error); } finally { await pool.end(); process.exit(0); } } generateSchema();