refactor: extract signals filter builder, add ESLint 10 config, fix low-hanging issues
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { type NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
import { withAuth, buildItemFilter } from '@/lib/apiHelpers';
|
||||
import pool from '@/lib/db';
|
||||
import { withAuth } from '@/lib/apiHelpers';
|
||||
import { getServerLocaleMap } from '@/lib/localeServer';
|
||||
import { matchKeys } from '@/lib/localization';
|
||||
|
||||
export const GET = withAuth(async (req: NextRequest) => {
|
||||
const p = req.nextUrl.searchParams;
|
||||
@@ -14,59 +13,30 @@ export const GET = withAuth(async (req: NextRequest) => {
|
||||
const to = p.get('to');
|
||||
const useRegex = p.get('regex') === 'true';
|
||||
const orderBy = p.get('order_by') ?? 'value_asc';
|
||||
const limit = p.get('limit') ? parseInt(p.get('limit')!, 10) : null;
|
||||
const limitStr = p.get('limit');
|
||||
const limit = limitStr ? parseInt(limitStr, 10) : null;
|
||||
|
||||
const conditions: string[] = [];
|
||||
const values: unknown[] = [];
|
||||
let i = 1;
|
||||
const param = { current: 1 };
|
||||
|
||||
if (combinators.length > 0) {
|
||||
conditions.push(`combinator = ANY($${i++})`);
|
||||
conditions.push(`combinator = ANY($${param.current++})`);
|
||||
values.push(combinators);
|
||||
}
|
||||
|
||||
if (itemsWhitelist.length > 0) {
|
||||
if (useRegex) {
|
||||
const localeMap = getServerLocaleMap();
|
||||
const localeKeys = [...new Set(itemsWhitelist.flatMap((p) => matchKeys(p, localeMap)))];
|
||||
const sqlPattern = itemsWhitelist.map((p) => `(${p})`).join('|');
|
||||
const orConds = [`item_key ~* $${i++}`];
|
||||
values.push(sqlPattern);
|
||||
if (localeKeys.length > 0) {
|
||||
orConds.push(`item_key = ANY($${i++})`);
|
||||
values.push(localeKeys);
|
||||
}
|
||||
conditions.push(`(${orConds.join(' OR ')})`);
|
||||
} else {
|
||||
conditions.push(`item_key = ANY($${i++})`);
|
||||
values.push(itemsWhitelist);
|
||||
}
|
||||
}
|
||||
const wlClause = buildItemFilter(itemsWhitelist, useRegex, true, values, param);
|
||||
if (wlClause) conditions.push(wlClause);
|
||||
|
||||
if (itemsBlacklist.length > 0) {
|
||||
if (useRegex) {
|
||||
const localeMap = getServerLocaleMap();
|
||||
const localeKeys = [...new Set(itemsBlacklist.flatMap((p) => matchKeys(p, localeMap)))];
|
||||
const sqlPattern = itemsBlacklist.map((p) => `(${p})`).join('|');
|
||||
const andConds = [`item_key !~* $${i++}`];
|
||||
values.push(sqlPattern);
|
||||
if (localeKeys.length > 0) {
|
||||
andConds.push(`item_key != ALL($${i++})`);
|
||||
values.push(localeKeys);
|
||||
}
|
||||
conditions.push(`(${andConds.join(' AND ')})`);
|
||||
} else {
|
||||
conditions.push(`item_key != ALL($${i++})`);
|
||||
values.push(itemsBlacklist);
|
||||
}
|
||||
}
|
||||
const blClause = buildItemFilter(itemsBlacklist, useRegex, false, values, param);
|
||||
if (blClause) conditions.push(blClause);
|
||||
|
||||
if (from) {
|
||||
conditions.push(`real_time >= $${i++}`);
|
||||
conditions.push(`real_time >= $${param.current++}`);
|
||||
values.push(new Date(from));
|
||||
}
|
||||
if (to) {
|
||||
conditions.push(`real_time <= $${i++}`);
|
||||
conditions.push(`real_time <= $${param.current++}`);
|
||||
values.push(new Date(to));
|
||||
}
|
||||
|
||||
@@ -83,46 +53,18 @@ export const GET = withAuth(async (req: NextRequest) => {
|
||||
if ((orderBy === 'delta_asc' || orderBy === 'delta_desc') && limit !== null) {
|
||||
const baseConditions: string[] = [];
|
||||
const baseValues: unknown[] = [];
|
||||
let j = 1;
|
||||
const baseParam = { current: 1 };
|
||||
|
||||
if (combinators.length > 0) {
|
||||
baseConditions.push(`combinator = ANY($${j++})`);
|
||||
baseConditions.push(`combinator = ANY($${baseParam.current++})`);
|
||||
baseValues.push(combinators);
|
||||
}
|
||||
if (itemsWhitelist.length > 0) {
|
||||
if (useRegex) {
|
||||
const localeMap = getServerLocaleMap();
|
||||
const localeKeys = [...new Set(itemsWhitelist.flatMap((p) => matchKeys(p, localeMap)))];
|
||||
const sqlPattern = itemsWhitelist.map((p) => `(${p})`).join('|');
|
||||
const orConds = [`item_key ~* $${j++}`];
|
||||
baseValues.push(sqlPattern);
|
||||
if (localeKeys.length > 0) {
|
||||
orConds.push(`item_key = ANY($${j++})`);
|
||||
baseValues.push(localeKeys);
|
||||
}
|
||||
baseConditions.push(`(${orConds.join(' OR ')})`);
|
||||
} else {
|
||||
baseConditions.push(`item_key = ANY($${j++})`);
|
||||
baseValues.push(itemsWhitelist);
|
||||
}
|
||||
}
|
||||
if (itemsBlacklist.length > 0) {
|
||||
if (useRegex) {
|
||||
const localeMap = getServerLocaleMap();
|
||||
const localeKeys = [...new Set(itemsBlacklist.flatMap((p) => matchKeys(p, localeMap)))];
|
||||
const sqlPattern = itemsBlacklist.map((p) => `(${p})`).join('|');
|
||||
const andConds = [`item_key !~* $${j++}`];
|
||||
baseValues.push(sqlPattern);
|
||||
if (localeKeys.length > 0) {
|
||||
andConds.push(`item_key != ALL($${j++})`);
|
||||
baseValues.push(localeKeys);
|
||||
}
|
||||
baseConditions.push(`(${andConds.join(' AND ')})`);
|
||||
} else {
|
||||
baseConditions.push(`item_key != ALL($${j++})`);
|
||||
baseValues.push(itemsBlacklist);
|
||||
}
|
||||
}
|
||||
|
||||
const wlBase = buildItemFilter(itemsWhitelist, useRegex, true, baseValues, baseParam);
|
||||
if (wlBase) baseConditions.push(wlBase);
|
||||
|
||||
const blBase = buildItemFilter(itemsBlacklist, useRegex, false, baseValues, baseParam);
|
||||
if (blBase) baseConditions.push(blBase);
|
||||
|
||||
const baseWhere = baseConditions.length > 0 ? `WHERE ${baseConditions.join(' AND ')}` : '';
|
||||
const baseWhereAnd = baseConditions.length > 0 ? `AND ${baseConditions.join(' AND ')}` : '';
|
||||
@@ -155,25 +97,27 @@ export const GET = withAuth(async (req: NextRequest) => {
|
||||
SELECT combinator, item_key, delta
|
||||
FROM deltas
|
||||
ORDER BY delta ${orderBy === 'delta_asc' ? 'ASC' : 'DESC'}
|
||||
LIMIT $${j}
|
||||
LIMIT $${baseParam.current}
|
||||
`;
|
||||
|
||||
const deltaResult = await pool.query<{ combinator: string; item_key: string; delta: number }>(
|
||||
deltaQuery,
|
||||
[...baseValues, limit],
|
||||
);
|
||||
const deltaResult = await pool.query<{
|
||||
combinator: string;
|
||||
item_key: string;
|
||||
delta: number;
|
||||
}>(deltaQuery, [...baseValues, limit]);
|
||||
|
||||
const top = deltaResult.rows;
|
||||
if (top.length === 0) return NextResponse.json([]);
|
||||
|
||||
const seriesConditions = top.map(
|
||||
(_, idx) => `(combinator = $${i + idx * 2} AND item_key = $${i + idx * 2 + 1})`,
|
||||
(_, idx) =>
|
||||
`(combinator = $${param.current + idx * 2} AND item_key = $${param.current + idx * 2 + 1})`,
|
||||
);
|
||||
const fullWhere = `${where ? where + ' AND' : 'WHERE'} (${seriesConditions.join(' OR ')})`;
|
||||
const orderCase = top
|
||||
.map(
|
||||
(_, idx) =>
|
||||
`WHEN combinator = $${i + idx * 2} AND item_key = $${i + idx * 2 + 1} THEN ${idx}`,
|
||||
`WHEN combinator = $${param.current + idx * 2} AND item_key = $${param.current + idx * 2 + 1} THEN ${idx}`,
|
||||
)
|
||||
.join(' ');
|
||||
const result = await pool.query(
|
||||
@@ -187,7 +131,11 @@ export const GET = withAuth(async (req: NextRequest) => {
|
||||
(orderBy === 'value_asc' || orderBy === 'value_desc' || orderBy === 'abs_desc') &&
|
||||
limit !== null
|
||||
) {
|
||||
const latestVals = await pool.query<{ combinator: string; item_key: string; val: number }>(
|
||||
const latestVals = await pool.query<{
|
||||
combinator: string;
|
||||
item_key: string;
|
||||
val: number;
|
||||
}>(
|
||||
`SELECT DISTINCT ON (combinator, item_key)
|
||||
combinator, item_key, ${valueCol} AS val
|
||||
FROM signals ${where}
|
||||
@@ -205,13 +153,14 @@ export const GET = withAuth(async (req: NextRequest) => {
|
||||
if (top.length === 0) return NextResponse.json([]);
|
||||
|
||||
const seriesConditions = top.map(
|
||||
(_, idx) => `(combinator = $${i + idx * 2} AND item_key = $${i + idx * 2 + 1})`,
|
||||
(_, idx) =>
|
||||
`(combinator = $${param.current + idx * 2} AND item_key = $${param.current + idx * 2 + 1})`,
|
||||
);
|
||||
const fullWhere = `${where ? where + ' AND' : 'WHERE'} (${seriesConditions.join(' OR ')})`;
|
||||
const orderCase = top
|
||||
.map(
|
||||
(_, idx) =>
|
||||
`WHEN combinator = $${i + idx * 2} AND item_key = $${i + idx * 2 + 1} THEN ${idx}`,
|
||||
`WHEN combinator = $${param.current + idx * 2} AND item_key = $${param.current + idx * 2 + 1} THEN ${idx}`,
|
||||
)
|
||||
.join(' ');
|
||||
const result = await pool.query(
|
||||
|
||||
Reference in New Issue
Block a user