41 lines
2.5 KiB
JavaScript
41 lines
2.5 KiB
JavaScript
import { loadConfig } from './config.mjs';
|
||
import { openStore } from './store.mjs';
|
||
|
||
const config = loadConfig();
|
||
const args = process.argv.slice(2);
|
||
function optionsFrom(items) {
|
||
const result = {};
|
||
for (const item of items) {
|
||
const at = item.indexOf('=');
|
||
if (at <= 0 || Object.hasOwn(result, item.slice(0, at))) throw new Error('Use unique key=value options');
|
||
result[item.slice(0, at)] = item.slice(at + 1);
|
||
}
|
||
return result;
|
||
}
|
||
const store = openStore(config.dbPath);
|
||
try {
|
||
if (args[0] === 'list') {
|
||
console.log(JSON.stringify(store.incidents().map(({ signature: _signature, ...incident }) => incident), null, 2));
|
||
} else if (args[0] === 'resolve' && /^\d+$/.test(args[1] || '')) {
|
||
const options = optionsFrom(args.slice(2));
|
||
const input = Object.keys(options).length ? { messageRu: options['message-ru'], messageEn: options['message-en'] } : null;
|
||
if (!store.resolveIncident(args[1], Date.now(), input)) throw new Error('Open manual incident not found; monitor incidents close after recovery');
|
||
console.log(`Resolved incident ${args[1]}`);
|
||
} else if (args[0] === 'update' && /^\d+$/.test(args[1] || '')) {
|
||
const options = optionsFrom(args.slice(2));
|
||
store.updateIncident(args[1], { stage: options.stage, messageRu: options['message-ru'], messageEn: options['message-en'] });
|
||
console.log(`Updated incident ${args[1]}`);
|
||
} else if (args[0] === 'create') {
|
||
const options = optionsFrom(args.slice(1));
|
||
const required = ['title-ru', 'title-en', 'message-ru', 'message-en'];
|
||
if (required.some(key => !options[key]?.trim() || options[key].length > 2000)) throw new Error('Provide title-ru, title-en, message-ru, message-en, 1–2000 characters');
|
||
if (options.service && !config.services.some(service => service.id === options.service)) throw new Error('Unknown service');
|
||
const id = store.createIncident({ serviceId: options.service || null, titleRu: options['title-ru'], titleEn: options['title-en'], messageRu: options['message-ru'], messageEn: options['message-en'] });
|
||
console.log(`Created incident ${id}`);
|
||
} else {
|
||
console.log('Usage: npm run incident -- list | resolve ID ["message-ru=..." "message-en=..."] | update ID stage=investigating|identified|monitoring|postmortem "message-ru=..." "message-en=..." | create service=api "title-ru=..." "title-en=..." "message-ru=..." "message-en=..."');
|
||
process.exitCode = 1;
|
||
}
|
||
} catch (error) { console.error(error.message); process.exitCode = 1; }
|
||
finally { store.close(); }
|