refactor: rename asset_network to asset_remote

- DB 테이블명 변경 마이그레이션 스크립트 추가 (migrate_v5_rename_remote.js)

- Backend (server.js): 쿼리 및 매핑 로직을 asset_remote 및 remotes 속성으로 업데이트

- Frontend (HWModal.ts): 폼 필드와 데이터 바인딩을 remotes로 일괄 수정

- 유틸리티 스크립트의 레퍼런스 일괄 업데이트
This commit is contained in:
2026-06-09 18:44:53 +09:00
parent 2b9c965c91
commit 25ebaf4685
9 changed files with 797 additions and 96 deletions

View File

@@ -39,7 +39,7 @@ const CATEGORY_TABLE_MAP = {
pc: 'asset_pc',
server: 'asset_server',
storage: 'asset_storage',
network: 'asset_network',
network: 'asset_remote',
equipment: 'asset_equipment',
officeSupplies: 'asset_office_supplies',
survey: 'asset_survey',
@@ -53,7 +53,7 @@ const CATEGORY_TABLE_MAP = {
};
const ASSET_TABLES = [
'asset_pc', 'asset_server', 'asset_storage', 'asset_network',
'asset_pc', 'asset_server', 'asset_storage', 'asset_remote',
'asset_equipment', 'asset_office_supplies', 'asset_survey', 'asset_vip'
];
@@ -115,7 +115,10 @@ app.get('/api/assets/master', async (req, res) => {
s.hw_status, s.model_name, s.mainboard, s.os, s.cpu, s.ram, s.gpu,
s.monitoring, s.price, s.monitor_inch, s.serial_num,
l.location, l.location_detail, l.location_photo, l.loc_x, l.loc_y,
n.ip_address, n.mac_address, n.remote_tool, n.remote_id, n.remote_pw,
(
SELECT JSON_ARRAYAGG(JSON_OBJECT('type', net_type, 'name', net_name, 'val1', net_value1, 'val2', net_value2))
FROM asset_remote WHERE asset_id = c.id AND is_active = 1
) as remotes,
(
SELECT JSON_ARRAYAGG(JSON_OBJECT('type', disk_type, 'capacity', capacity, 'unit', unit, 'slot', slot_no))
FROM asset_volume WHERE asset_id = c.id
@@ -127,11 +130,6 @@ app.get('/api/assets/master', async (req, res) => {
WHERE asset_id = c.id AND is_active = 1
ORDER BY created_at DESC LIMIT 1
)
LEFT JOIN asset_network n ON n.id = (
SELECT id FROM asset_network
WHERE asset_id = c.id AND is_active = 1
ORDER BY created_at DESC LIMIT 1
)
`);
const catMap = {
@@ -223,14 +221,36 @@ app.post('/api/asset/:category/save', async (req, res) => {
}
}
// 3.5 asset_network
if (asset.ip_address || asset.mac_address || asset.remote_tool) {
const [netActive] = await connection.query('SELECT * FROM asset_network WHERE asset_id = ? AND is_active = 1', [asset.id]);
const isChanged = netActive.length === 0 || netActive[0].ip_address !== asset.ip_address || netActive[0].mac_address !== asset.mac_address || netActive[0].remote_tool !== asset.remote_tool || netActive[0].remote_id !== asset.remote_id || netActive[0].remote_pw !== asset.remote_pw;
if (isChanged) {
await connection.query('UPDATE asset_network SET is_active = 0, deactivated_at = NOW() WHERE asset_id = ? AND is_active = 1', [asset.id]);
await connection.query(`INSERT INTO asset_network (asset_id, ip_address, mac_address, remote_tool, remote_id, remote_pw, is_active) VALUES (?, ?, ?, ?, ?, ?, 1)`,
[asset.id, asset.ip_address, asset.mac_address, asset.remote_tool, asset.remote_id, asset.remote_pw]);
// 3.5 asset_remote (Dynamic Array Logic)
if (asset.remotes) {
try {
let nets = typeof asset.remotes === 'string' ? JSON.parse(asset.remotes) : asset.remotes;
if (Array.isArray(nets)) {
await connection.query('UPDATE asset_remote SET is_active = 0, deactivated_at = NOW() WHERE asset_id = ? AND is_active = 1', [asset.id]);
for (const n of nets) {
if (n.type) {
await connection.query(
'INSERT INTO asset_remote (asset_id, net_type, net_name, net_value1, net_value2, is_active) VALUES (?, ?, ?, ?, ?, 1)',
[asset.id, n.type, n.name || '', n.val1 || '', n.val2 || '']
);
}
}
}
} catch(e) { console.error('Remote data parse error', e); }
} else {
// Fallback for UI that hasn't sent the networks array yet
if (asset.ip_address || asset.mac_address || asset.remote_tool) {
const [netActive] = await connection.query('SELECT * FROM asset_remote WHERE asset_id = ? AND is_active = 1', [asset.id]);
const isChanged = netActive.length === 0 || netActive[0].net_value1 !== asset.ip_address || netActive[0].net_value2 !== asset.mac_address || netActive[0].net_name !== asset.remote_tool;
if (isChanged) {
await connection.query('UPDATE asset_remote SET is_active = 0, deactivated_at = NOW() WHERE asset_id = ? AND is_active = 1', [asset.id]);
if (asset.ip_address || asset.mac_address) {
await connection.query('INSERT INTO asset_remote (asset_id, net_type, net_name, net_value1, net_value2, is_active) VALUES (?, ?, ?, ?, ?, 1)', [asset.id, 'IP', '기본망', asset.ip_address, asset.mac_address]);
}
if (asset.remote_tool || asset.remote_id || asset.remote_pw) {
await connection.query('INSERT INTO asset_remote (asset_id, net_type, net_name, net_value1, net_value2, is_active) VALUES (?, ?, ?, ?, ?, 1)', [asset.id, 'REMOTE', asset.remote_tool, asset.remote_id, asset.remote_pw]);
}
}
}
}
@@ -272,7 +292,7 @@ app.delete('/api/asset/:category/:id', async (req, res) => {
try {
const connection = await pool.getConnection();
// For asset_core, ON DELETE CASCADE will handle spec, location, network, volume
// For asset_core, ON DELETE CASCADE will handle spec, location, remote, volume
await connection.query(`DELETE FROM ${table} WHERE id = ?`, [id]);
connection.release();
console.log(`🗑️ [ASSET DELETE] Category: ${category}, ID: ${id}`);