|
|
|
import * as AnalyticsController from '../controllers/analytics_controller';
|
|
|
|
import * as AnalyticUnit from '../models/analytic_units';
|
|
|
|
|
|
|
|
import { saveAnalyticUnitFromObject } from '../controllers/analytics_controller';
|
|
|
|
|
|
|
|
import * as Router from 'koa-router';
|
|
|
|
import * as _ from 'lodash';
|
|
|
|
|
|
|
|
|
|
|
|
async function getStatus(ctx: Router.IRouterContext) {
|
|
|
|
let analyticUnitId = ctx.request.query.id as string;
|
|
|
|
if(analyticUnitId === undefined) {
|
|
|
|
throw new Error('Cannot get status of undefined id');
|
|
|
|
}
|
|
|
|
|
|
|
|
let analyticUnit = await AnalyticUnit.findById(analyticUnitId);
|
|
|
|
if(analyticUnit === null) {
|
|
|
|
throw new Error(`Cannot find analytic unit with id ${analyticUnitId}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.response.body = {
|
|
|
|
status: analyticUnit.status
|
|
|
|
};
|
|
|
|
|
|
|
|
if(analyticUnit.status === AnalyticUnit.AnalyticUnitStatus.FAILED) {
|
|
|
|
ctx.response.body = {
|
|
|
|
errorMessage: analyticUnit.error
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getUnits(ctx: Router.IRouterContext) {
|
|
|
|
const panelId = ctx.request.query.panelId as string;
|
|
|
|
if(panelId === undefined) {
|
|
|
|
throw new Error('Cannot get units of undefined panelId');
|
|
|
|
}
|
|
|
|
|
|
|
|
let analyticUnits = await AnalyticUnit.findMany({ panelId });
|
|
|
|
if(analyticUnits === null) {
|
|
|
|
analyticUnits = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
const analyticUnitObjects = analyticUnits.map(analyticUnit => analyticUnit.toPanelObject());
|
|
|
|
|
|
|
|
ctx.response.body = {
|
|
|
|
analyticUnits: analyticUnitObjects
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function getTypes(ctx: Router.IRouterContext) {
|
|
|
|
ctx.response.body = AnalyticUnit.ANALYTIC_UNIT_TYPES;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function createUnit(ctx: Router.IRouterContext) {
|
|
|
|
const id = await saveAnalyticUnitFromObject(ctx.request.body);
|
|
|
|
|
|
|
|
ctx.response.body = { id };
|
|
|
|
}
|
|
|
|
|
|
|
|
async function updateUnit(ctx: Router.IRouterContext) {
|
|
|
|
const analyticUnitObj = ctx.request.body as unknown as AnalyticUnit.AnalyticUnit;
|
|
|
|
if(analyticUnitObj.id === undefined) {
|
|
|
|
throw new Error('Cannot update undefined id');
|
|
|
|
}
|
|
|
|
|
|
|
|
await AnalyticUnit.update(analyticUnitObj.id, analyticUnitObj);
|
|
|
|
// TODO: check if learning is necessary without database query
|
|
|
|
const analyticUnit = await AnalyticUnit.findById(analyticUnitObj.id);
|
|
|
|
|
|
|
|
if(analyticUnit.learningAfterUpdateRequired) {
|
|
|
|
await AnalyticsController.runLearning(analyticUnitObj.id);
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 200,
|
|
|
|
message: 'Success'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
async function updateMetric(ctx: Router.IRouterContext) {
|
|
|
|
const { analyticUnitId, metric, datasource } = ctx.request.body as {
|
|
|
|
analyticUnitId: AnalyticUnit.AnalyticUnitId, metric: any, datasource: any
|
|
|
|
};
|
|
|
|
if(analyticUnitId === undefined) {
|
|
|
|
throw new Error('Cannot update undefined id');
|
|
|
|
}
|
|
|
|
if(metric === undefined) {
|
|
|
|
throw new Error('Cannot set undefined metric');
|
|
|
|
}
|
|
|
|
if(datasource === undefined) {
|
|
|
|
throw new Error('Cannot set undefined datasource');
|
|
|
|
}
|
|
|
|
|
|
|
|
await AnalyticsController.setMetric(analyticUnitId, metric, datasource);
|
|
|
|
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 200,
|
|
|
|
message: 'Success'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
async function updateAlert(ctx: Router.IRouterContext) {
|
|
|
|
const { analyticUnitId, alert } = ctx.request.body as {
|
|
|
|
analyticUnitId: AnalyticUnit.AnalyticUnitId, alert: boolean
|
|
|
|
};
|
|
|
|
if(analyticUnitId === undefined) {
|
|
|
|
throw new Error('Cannot update undefined id');
|
|
|
|
}
|
|
|
|
if(alert === undefined) {
|
|
|
|
throw new Error('Cannot set undefined alert status');
|
|
|
|
}
|
|
|
|
|
|
|
|
await AnalyticsController.setAlert(analyticUnitId, alert);
|
|
|
|
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 200,
|
|
|
|
message: 'Success'
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
async function deleteUnit(ctx: Router.IRouterContext) {
|
|
|
|
const analyticUnitId = ctx.request.query.id as string;
|
|
|
|
if(analyticUnitId === undefined) {
|
|
|
|
throw new Error('Cannot delete undefined id');
|
|
|
|
}
|
|
|
|
await AnalyticsController.remove(analyticUnitId);
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 200,
|
|
|
|
message: 'Success'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
async function runDetect(ctx: Router.IRouterContext) {
|
|
|
|
const { ids, from, to } = ctx.request.body as {
|
|
|
|
ids: AnalyticUnit.AnalyticUnitId[], from: number, to: number
|
|
|
|
};
|
|
|
|
|
|
|
|
await Promise.all(ids.map(id => AnalyticsController.runLearningWithDetection(id, from, to)));
|
|
|
|
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 200,
|
|
|
|
message: 'Success'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export var router = new Router();
|
|
|
|
|
|
|
|
router.get('/units', getUnits);
|
|
|
|
router.get('/status', getStatus);
|
|
|
|
router.get('/types', getTypes);
|
|
|
|
router.patch('/metric', updateMetric);
|
|
|
|
router.patch('/alert', updateAlert);
|
|
|
|
|
|
|
|
router.post('/', createUnit);
|
|
|
|
router.delete('/', deleteUnit);
|
|
|
|
router.patch('/', updateUnit);
|
|
|
|
|
|
|
|
router.post('/detect', runDetect);
|