feat: 자산 정보 수정 시 메모, 용도, 접속정보, 유형 변경 사항도 시스템 이력에 기록되도록 개선
This commit is contained in:
80
server.js
80
server.js
@@ -288,6 +288,7 @@ app.post('/api/asset/:category/save', async (req, res) => {
|
||||
// 3.0 History Tracking & Auto Field Update
|
||||
const [oldCoreRows] = await connection.query('SELECT * FROM asset_core WHERE id = ?', [asset.id]);
|
||||
const [oldSpecRows] = await connection.query('SELECT * FROM asset_spec WHERE asset_id = ?', [asset.id]);
|
||||
const [oldRemoteRows] = await connection.query('SELECT * FROM asset_remote WHERE asset_id = ? AND is_active = 1', [asset.id]);
|
||||
const oldCore = oldCoreRows[0] || {};
|
||||
const oldSpec = oldSpecRows[0] || {};
|
||||
|
||||
@@ -350,6 +351,85 @@ app.post('/api/asset/:category/save', async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
// 3.0.4 메모, 용도, 유형 변동 감지
|
||||
const oldMemo = String(oldCore.memo || '').trim();
|
||||
const newMemo = String(asset.memo || '').trim();
|
||||
if (newMemo !== '' && oldMemo !== newMemo) {
|
||||
historyLogs.push({
|
||||
event_type: 'MEMO_CHANGE',
|
||||
details: `[메모 변경] ${oldMemo || '(없음)'} -> ${newMemo}`
|
||||
});
|
||||
}
|
||||
|
||||
const oldPurpose = String(oldCore.asset_purpose || '').trim();
|
||||
const newPurpose = String(asset.asset_purpose || '').trim();
|
||||
if (newPurpose !== '' && oldPurpose !== newPurpose) {
|
||||
historyLogs.push({
|
||||
event_type: 'PURPOSE_CHANGE',
|
||||
details: `[용도 변경] ${oldPurpose || '(없음)'} -> ${newPurpose}`
|
||||
});
|
||||
}
|
||||
|
||||
const oldType = String(oldCore.asset_type || '').trim();
|
||||
const newType = String(asset.asset_type || '').trim();
|
||||
if (newType !== '' && oldType !== newType) {
|
||||
historyLogs.push({
|
||||
event_type: 'TYPE_CHANGE',
|
||||
details: `[유형 변경] ${oldType || '(없음)'} -> ${newType}`
|
||||
});
|
||||
}
|
||||
|
||||
// 3.0.5 접속정보 변동 감지
|
||||
const formatRemote = (r) => {
|
||||
const type = r.net_type || r.type || '';
|
||||
const name = r.net_name || r.name || '';
|
||||
const val1 = r.net_value1 || r.val1 || '';
|
||||
const val2 = r.net_value2 || r.val2 || '';
|
||||
return `${type}:${name}:${val1}:${val2}`;
|
||||
};
|
||||
|
||||
const oldRemotesSummary = oldRemoteRows.map(formatRemote).sort().join(' | ');
|
||||
|
||||
let newNets = [];
|
||||
if (asset.remotes) {
|
||||
try {
|
||||
newNets = typeof asset.remotes === 'string' ? JSON.parse(asset.remotes) : asset.remotes;
|
||||
} catch(e) { newNets = []; }
|
||||
} else if (asset.ip_address || asset.mac_address || asset.remote_tool) {
|
||||
if (asset.ip_address || asset.mac_address) {
|
||||
newNets.push({ type: 'IP', name: '기본망', val1: asset.ip_address, val2: asset.mac_address });
|
||||
}
|
||||
if (asset.remote_tool || asset.remote_id || asset.remote_pw) {
|
||||
newNets.push({ type: 'REMOTE', name: asset.remote_tool, val1: asset.remote_id, val2: asset.remote_pw });
|
||||
}
|
||||
}
|
||||
const newRemotesSummary = newNets.map(formatRemote).sort().join(' | ');
|
||||
|
||||
if (newRemotesSummary !== '' && oldRemotesSummary !== newRemotesSummary) {
|
||||
const formatDisplay = (summary) => {
|
||||
if (!summary) return '(없음)';
|
||||
return summary.split(' | ').map(item => {
|
||||
const [type, name, val1, val2] = item.split(':');
|
||||
if (type === 'IP') {
|
||||
return `[IP] ${name}: ${val1} (MAC: ${val2 || '없음'})`;
|
||||
} else {
|
||||
let id = '', pw = '';
|
||||
try {
|
||||
const parsed = JSON.parse(val2);
|
||||
id = parsed.id || '';
|
||||
pw = parsed.pw || '';
|
||||
} catch(e) { id = val1; pw = val2; }
|
||||
return `[원격] ${name}: ID=${id || '없음'}, PW=${pw ? '***' : '없음'}`;
|
||||
}
|
||||
}).join(', ');
|
||||
};
|
||||
|
||||
historyLogs.push({
|
||||
event_type: 'REMOTE_CHANGE',
|
||||
details: `[접속정보 변경] ${formatDisplay(oldRemotesSummary)} -> ${formatDisplay(newRemotesSummary)}`
|
||||
});
|
||||
}
|
||||
|
||||
// 로그 일괄 삽입
|
||||
for (const log of historyLogs) {
|
||||
await connection.query(
|
||||
|
||||
Reference in New Issue
Block a user