cleanup: remove database migration and utility scripts

This commit is contained in:
2026-06-02 14:44:45 +09:00
parent a30f99f0ad
commit 46422e8544
4 changed files with 0 additions and 434 deletions

View File

@@ -1,92 +0,0 @@
import mysql from 'mysql2/promise';
import dotenv from 'dotenv';
dotenv.config();
const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env;
async function run() {
const pool = mysql.createPool({
host: DB_HOST,
user: DB_USER,
password: DB_PASS,
database: DB_NAME,
port: parseInt(DB_PORT || '3306')
});
console.log('🔄 Step 1: Updating purchase_date for PC-000000 assets to 2015-12-01...');
const [updateResult] = await pool.query(
"UPDATE asset_pc SET purchase_date = '2015-12-01' WHERE asset_code LIKE 'PC-000000%'"
);
console.log(`✅ Updated ${updateResult.affectedRows} records.`);
console.log('🔄 Step 2: Re-sequencing all PC asset codes by Year...');
const [pcs] = await pool.query('SELECT * FROM asset_pc');
const getPrefix = (type) => {
const t = type || '';
if (t.includes('공용PC') || t.includes('개인PC') || t.includes('서버PC') || t === 'PC') return 'PC';
return 'ETC';
};
const parseYYYYMM = (dateStr) => {
if (!dateStr) return '000000';
const clean = dateStr.replace(/[^0-9]/g, '');
if (clean.length >= 6) return clean.substring(0, 6);
return '000000';
};
const parseYYYY = (dateStr) => {
const yyyymm = parseYYYYMM(dateStr);
return yyyymm.substring(0, 4);
};
// Group and sort
const mapped = pcs.map(item => {
const prefix = getPrefix(item.asset_type);
const yyyymm = parseYYYYMM(item.purchase_date);
const yyyy = yyyymm.substring(0, 4);
const sortKey = [
item.purchase_date || '9999-99-99',
item.model_name || '',
item.mainboard || '',
item.os || '',
item.id
].join('|');
return { ...item, prefix, yyyymm, yyyy, sortKey };
});
mapped.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
const counters = {};
const updates = mapped.map(item => {
const groupKey = `${item.prefix}-${item.yyyy}`;
counters[groupKey] = (counters[groupKey] || 0) + 1;
const serial = String(counters[groupKey]).padStart(4, '0');
const newCode = `${item.prefix}-${item.yyyymm}-${serial}`;
return { id: item.id, asset_code: newCode };
});
console.log('💾 Reflecting changes to DB...');
const connection = await pool.getConnection();
try {
await connection.beginTransaction();
// Clear codes to avoid unique constraint issues
await connection.query("UPDATE asset_pc SET asset_code = CONCAT('TEMP_', id)");
for (const u of updates) {
await connection.query("UPDATE asset_pc SET asset_code = ? WHERE id = ?", [u.asset_code, u.id]);
}
await connection.commit();
console.log(`✅ Re-sequencing completed for ${updates.length} PCs.`);
} catch (err) {
await connection.rollback();
console.error('❌ Failed to re-sequence:', err);
} finally {
connection.release();
}
await pool.end();
}
run().catch(console.error);

View File

@@ -1,94 +0,0 @@
import mysql from 'mysql2/promise';
import XLSX from 'xlsx';
import dotenv from 'dotenv';
dotenv.config();
const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env;
async function run() {
const pool = mysql.createPool({
host: DB_HOST,
user: DB_USER,
password: DB_PASS,
database: DB_NAME,
port: parseInt(DB_PORT || '3306')
});
console.log('📡 Fetching data from DB...');
const [pcs] = await pool.query('SELECT * FROM asset_pc');
const [servers] = await pool.query('SELECT * FROM asset_server');
const getPrefix = (type) => {
const t = type || '';
if (t.includes('서버 렉') || t.includes('워크스테이션')) return 'SVR';
if (t.includes('스토리지 렉')) return 'STO';
if (t.includes('공용PC') || t.includes('개인PC') || t.includes('서버PC') || t === 'PC') return 'PC';
return 'ETC';
};
const parseYYYYMM = (dateStr) => {
if (!dateStr) return '000000';
const clean = dateStr.replace(/[^0-9]/g, '');
if (clean.length >= 6) return clean.substring(0, 6);
return '000000';
};
const processList = (list) => {
// 1. Prepare data with sorting keys and groups
const mapped = list.map(item => {
const prefix = getPrefix(item.asset_type);
const yyyymm = parseYYYYMM(item.purchase_date);
// Sort by: purchase_date -> model_name -> mainboard -> os -> id (stability)
const sortKey = [
item.purchase_date || '9999-99-99',
item.model_name || '',
item.mainboard || '',
item.os || '',
item.id
].join('|');
return { ...item, prefix, yyyymm, sortKey };
});
// 2. Sort the list
mapped.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
// 3. Assign new codes
const counters = {};
return mapped.map(item => {
const groupKey = `${item.prefix}-${item.yyyymm}`;
counters[groupKey] = (counters[groupKey] || 0) + 1;
const serial = String(counters[groupKey]).padStart(4, '0');
const newCode = `${groupKey}-${serial}`;
return {
asset_code: newCode,
category: item.category,
asset_type: item.asset_type,
asset_purpose: item.asset_purpose || '',
memo: `[Legacy: ${item.asset_code || 'N/A'}] ${item.memo || ''}`.trim()
};
});
};
console.log('🔄 Processing codes...');
const finalServers = processList(servers);
const finalPcs = processList(pcs);
console.log('📊 Generating Excel...');
const wb = XLSX.utils.book_new();
const wsServers = XLSX.utils.json_to_sheet(finalServers);
const wsPcs = XLSX.utils.json_to_sheet(finalPcs);
XLSX.utils.book_append_sheet(wb, wsServers, 'asset_server');
XLSX.utils.book_append_sheet(wb, wsPcs, 'asset_pc');
const fileName = 'Asset_Code_Preview_20260602.xlsx';
XLSX.writeFile(wb, fileName);
console.log(`✅ Completed! File saved as: ${fileName}`);
await pool.end();
}
run().catch(console.error);

View File

@@ -1,98 +0,0 @@
import mysql from 'mysql2/promise';
import XLSX from 'xlsx';
import dotenv from 'dotenv';
dotenv.config();
const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env;
async function run() {
const pool = mysql.createPool({
host: DB_HOST,
user: DB_USER,
password: DB_PASS,
database: DB_NAME,
port: parseInt(DB_PORT || '3306')
});
const excelFile = 'Asset_Code_Preview_MOD 20260602.xlsx';
console.log(`📖 Reading corrected info from: ${excelFile}`);
const workbook = XLSX.readFile(excelFile);
const syncTable = async (sheetName, tableName) => {
console.log(`🔍 Processing ${sheetName}...`);
const data = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
const [dbRecords] = await pool.query(`SELECT id, asset_code FROM ${tableName}`);
const extractLegacyCode = (memo) => {
const match = (memo || '').match(/\[Legacy:\s*([^\]]+)\]/);
return match ? match[1] : 'N/A';
};
const extractOriginalMemo = (memo) => {
return (memo || '').replace(/\[Legacy:\s*[^\]]+\]\s*/, '').trim();
};
const updates = [];
for (const row of data) {
const legacyCode = extractLegacyCode(row.memo);
const match = dbRecords.find(db => (db.asset_code || 'N/A') === legacyCode);
if (match) {
// 엑셀의 자산번호에서 날짜 추출 (PC-201512-0001 -> 2015-12-01)
const codeParts = row.asset_code.split('-');
let purchaseDate = null;
if (codeParts.length >= 2 && codeParts[1].length === 6) {
const ym = codeParts[1];
purchaseDate = `${ym.substring(0, 4)}-${ym.substring(4, 6)}-01`;
}
updates.push({
id: match.id,
asset_code: row.asset_code, // 엑셀에 적힌 번호 그대로 (사용자 수정 반영)
purchase_date: purchaseDate,
memo: extractOriginalMemo(row.memo)
});
}
}
console.log(`💾 Updating ${updates.length} records in ${tableName}...`);
const connection = await pool.getConnection();
try {
await connection.beginTransaction();
await connection.query(`UPDATE ${tableName} SET asset_code = CONCAT('TEMP_', id)`);
for (const u of updates) {
if (u.purchase_date) {
await connection.query(
`UPDATE ${tableName} SET asset_code = ?, purchase_date = ?, memo = ? WHERE id = ?`,
[u.asset_code, u.purchase_date, u.memo, u.id]
);
} else {
await connection.query(
`UPDATE ${tableName} SET asset_code = ?, memo = ? WHERE id = ?`,
[u.asset_code, u.memo, u.id]
);
}
}
await connection.commit();
console.log(`${tableName} Sync Completed.`);
} catch (err) {
await connection.rollback();
console.error(`${tableName} Error:`, err);
} finally {
connection.release();
}
};
await syncTable('asset_pc', 'asset_pc');
await syncTable('asset_server', 'asset_server');
console.log('🔄 Re-sequencing all PC and Server codes by YEAR for absolute consistency...');
// 여기서 마지막으로 전체 정렬 및 일련번호 재부여를 수행하여 중복이나 누락을 완벽히 방지
await pool.end();
// Re-run the existing update script to ensure yearly sequencing is perfect
// (Using the relaxed matching logic we already improved)
}
run().catch(console.error);

View File

@@ -1,150 +0,0 @@
import mysql from 'mysql2/promise';
import XLSX from 'xlsx';
import dotenv from 'dotenv';
dotenv.config();
const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env;
async function run() {
const pool = mysql.createPool({
host: DB_HOST,
user: DB_USER,
password: DB_PASS,
database: DB_NAME,
port: parseInt(DB_PORT || '3306')
});
const fileName = 'Asset_Code_Preview_MOD 20260602.xlsx';
console.log(`📖 Reading modified Excel: ${fileName}`);
const workbook = XLSX.readFile(fileName);
// 1. Fetch current DB state for matching
console.log('📡 Fetching current DB state...');
const [dbPcs] = await pool.query('SELECT * FROM asset_pc');
const [dbServers] = await pool.query('SELECT * FROM asset_server');
const processSheet = async (sheetName, dbRecords, tableName) => {
console.log(`🔍 Processing sheet: ${sheetName}`);
const sheet = workbook.Sheets[sheetName];
if (!sheet) {
console.warn(`⚠️ Sheet ${sheetName} not found.`);
return;
}
const data = XLSX.utils.sheet_to_json(sheet);
// Helper to extract legacy code from memo
const extractLegacyCode = (memo) => {
const match = memo.match(/\[Legacy:\s*([^\]]+)\]/);
return match ? match[1] : 'N/A';
};
// Helper to extract original memo (without legacy tag)
const extractOriginalMemo = (memo) => {
return memo.replace(/\[Legacy:\s*[^\]]+\]\s*/, '').trim();
};
// Helper to parse current asset_code into parts (Prefix-YYYYMM-Serial)
const parseCodeParts = (code) => {
const parts = code.split('-');
if (parts.length >= 3) {
return {
prefix: parts[0],
yyyymm: parts[1],
yyyy: parts[1].substring(0, 4), // Extract Year
serial: parts[parts.length - 1]
};
}
return { prefix: 'ETC', yyyymm: '000000', yyyy: '0000', serial: '0000' };
};
// 2. Map Excel rows back to DB records
const updates = [];
const usedDbIds = new Set();
const groups = {};
for (const row of data) {
const legacyCode = extractLegacyCode(row.memo || '');
const originalMemo = extractOriginalMemo(row.memo || '');
let match = null;
if (legacyCode !== 'N/A') {
match = dbRecords.find(db => !usedDbIds.has(db.id) && (db.asset_code || 'N/A') === legacyCode);
}
if (!match) {
match = dbRecords.find(db => !usedDbIds.has(db.id) && db.asset_type === row.asset_type && (db.asset_purpose || '') === row.asset_purpose);
}
if (!match) {
match = dbRecords.find(db => !usedDbIds.has(db.id) && db.asset_type === row.asset_type);
}
if (match) {
usedDbIds.add(match.id);
const parts = parseCodeParts(row.asset_code);
// Group by Prefix and Year (YYYY)
const groupKey = `${parts.prefix}-${parts.yyyy}`;
if (!groups[groupKey]) groups[groupKey] = [];
groups[groupKey].push({
dbId: match.id,
originalRow: row,
yyyymm: parts.yyyymm, // Keep the specific month for the code
requestedSerial: parts.serial
});
}
}
// 3. Resolve Duplicates and Re-sequence BY YEAR
console.log(`⚖️ Resolving duplicates for ${sheetName} (Yearly Sequencing)...`);
for (const key in groups) {
const items = groups[key];
// Sort by YearMonth first, then by the serial provided to maintain order
items.sort((a, b) => {
const monthCompare = a.yyyymm.localeCompare(b.yyyymm);
if (monthCompare !== 0) return monthCompare;
return a.requestedSerial.localeCompare(b.requestedSerial);
});
items.forEach((item, index) => {
const newSerial = String(index + 1).padStart(4, '0');
// Format remains Prefix-YYYYMM-Serial
const finalCode = `${item.originalRow.asset_code.split('-').slice(0, 2).join('-')}-${newSerial}`;
updates.push({ id: item.dbId, asset_code: finalCode, memo: extractOriginalMemo(item.originalRow.memo || '') });
});
}
// 4. Perform DB Updates
console.log(`💾 Updating ${tableName} in DB...`);
const connection = await pool.getConnection();
try {
await connection.beginTransaction();
// IMPORTANT: To avoid UNIQUE constraint errors during the update process,
// we first set all asset_codes to a temporary unique value.
console.log(`🔄 Clearing existing codes in ${tableName} for safe update...`);
await connection.query(`UPDATE ${tableName} SET asset_code = CONCAT('TEMP_', id)`);
for (const update of updates) {
await connection.query(
`UPDATE ${tableName} SET asset_code = ?, memo = ? WHERE id = ?`,
[update.asset_code, update.memo, update.id]
);
}
await connection.commit();
console.log(`✅ Updated ${updates.length} records in ${tableName}.`);
} catch (err) {
await connection.rollback();
console.error(`❌ Failed to update ${tableName}:`, err);
} finally {
connection.release();
}
};
await processSheet('asset_server', dbServers, 'asset_server');
await processSheet('asset_pc', dbPcs, 'asset_pc');
console.log('🏁 All updates completed.');
await pool.end();
}
run().catch(console.error);