initial commit
This commit is contained in:
152
src/dashboardApi.js
Normal file
152
src/dashboardApi.js
Normal file
@@ -0,0 +1,152 @@
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
buildAlertRules,
|
||||
inferAlertOn,
|
||||
normalizeAlertOn,
|
||||
parseTargetPrice,
|
||||
} = require("./alertRules");
|
||||
const { createHttpError, parseBoolean } = require("./dashboardUtils");
|
||||
const { extractFlightSearchRequest } = require("./llmParameterExtractor");
|
||||
|
||||
function readInput(body) {
|
||||
const input = typeof body.input === "string" ? body.input.trim() : "";
|
||||
if (!input) {
|
||||
throw createHttpError(400, "input 문자열이 필요합니다.");
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
function hasOwnProperty(source, key) {
|
||||
return Object.prototype.hasOwnProperty.call(source, key);
|
||||
}
|
||||
|
||||
function createDashboardApi({ watcher, store }) {
|
||||
async function parseInput(body = {}) {
|
||||
const input = readInput(body);
|
||||
|
||||
return extractFlightSearchRequest(input, {
|
||||
preferRuleParser: parseBoolean(body.useLlm, true) === false,
|
||||
});
|
||||
}
|
||||
|
||||
async function createWatch(body = {}) {
|
||||
const extracted = await parseInput(body);
|
||||
const input = readInput(body);
|
||||
|
||||
const alertRules = buildAlertRules({
|
||||
targetPrice: body.targetPrice,
|
||||
alertOn: body.alertOn || "both",
|
||||
});
|
||||
|
||||
const watchId = watcher.addWatch({
|
||||
rawInput: input,
|
||||
searchParams: extracted.params,
|
||||
alertRules,
|
||||
pollingEnabled: parseBoolean(body.pollingEnabled, true),
|
||||
alertsEnabled: parseBoolean(body.alertsEnabled, true),
|
||||
});
|
||||
|
||||
const created = watcher.getWatch(watchId);
|
||||
await store.saveWatch(created);
|
||||
|
||||
if (parseBoolean(body.pollNow, false)) {
|
||||
await watcher.pollWatch(watchId);
|
||||
}
|
||||
|
||||
return {
|
||||
watch: watcher.getWatch(watchId),
|
||||
parserSource: extracted.source,
|
||||
};
|
||||
}
|
||||
|
||||
async function updateSystem(body = {}) {
|
||||
const controls = watcher.setGlobalControls({
|
||||
crawlingEnabled: parseBoolean(body.crawlingEnabled, watcher.getGlobalControls().crawlingEnabled),
|
||||
alertsEnabled: parseBoolean(body.alertsEnabled, watcher.getGlobalControls().alertsEnabled),
|
||||
});
|
||||
await store.setGlobalControls(controls);
|
||||
return { controls };
|
||||
}
|
||||
|
||||
function listWatches() {
|
||||
return {
|
||||
controls: watcher.getGlobalControls(),
|
||||
watches: watcher.listWatches(),
|
||||
};
|
||||
}
|
||||
|
||||
async function listEvents(rawLimit) {
|
||||
const limit = Number(rawLimit);
|
||||
const events = await store.listEvents(Number.isFinite(limit) ? limit : 50);
|
||||
return { events };
|
||||
}
|
||||
|
||||
async function pollWatch(watchId) {
|
||||
const existing = watcher.getWatch(watchId);
|
||||
if (!existing) {
|
||||
throw createHttpError(404, `watch를 찾을 수 없습니다: ${watchId}`);
|
||||
}
|
||||
|
||||
const pollResult = await watcher.pollWatch(watchId);
|
||||
return {
|
||||
watch: watcher.getWatch(watchId),
|
||||
pollResult,
|
||||
};
|
||||
}
|
||||
|
||||
async function updateWatch(watchId, body = {}) {
|
||||
const existing = watcher.getWatch(watchId);
|
||||
if (!existing) {
|
||||
throw createHttpError(404, `watch를 찾을 수 없습니다: ${watchId}`);
|
||||
}
|
||||
|
||||
const patch = {};
|
||||
if (hasOwnProperty(body, "pollingEnabled")) {
|
||||
patch.pollingEnabled = parseBoolean(body.pollingEnabled, existing.pollingEnabled);
|
||||
}
|
||||
if (hasOwnProperty(body, "alertsEnabled")) {
|
||||
patch.alertsEnabled = parseBoolean(body.alertsEnabled, existing.alertsEnabled);
|
||||
}
|
||||
|
||||
const hasAlertModePatch = hasOwnProperty(body, "alertOn") || hasOwnProperty(body, "targetPrice");
|
||||
if (hasAlertModePatch) {
|
||||
const targetPrice = hasOwnProperty(body, "targetPrice")
|
||||
? parseTargetPrice(body.targetPrice)
|
||||
: existing.alertRules.targetPrice;
|
||||
const alertOn = hasOwnProperty(body, "alertOn")
|
||||
? normalizeAlertOn(body.alertOn)
|
||||
: inferAlertOn(existing.alertRules);
|
||||
|
||||
patch.alertRules = buildAlertRules({
|
||||
targetPrice,
|
||||
alertOn,
|
||||
});
|
||||
}
|
||||
|
||||
const updated = watcher.updateWatch(watchId, patch);
|
||||
await store.saveWatch(updated);
|
||||
return { watch: updated };
|
||||
}
|
||||
|
||||
async function deleteWatch(watchId) {
|
||||
const existed = watcher.removeWatch(watchId);
|
||||
await store.deleteWatch(watchId);
|
||||
return { deleted: existed };
|
||||
}
|
||||
|
||||
return {
|
||||
createWatch,
|
||||
deleteWatch,
|
||||
listEvents,
|
||||
listWatches,
|
||||
parseInput,
|
||||
pollWatch,
|
||||
updateSystem,
|
||||
updateWatch,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createDashboardApi,
|
||||
};
|
||||
Reference in New Issue
Block a user