100 lines
2.5 KiB
TypeScript
100 lines
2.5 KiB
TypeScript
import { Router } from "express";
|
|
import { SubscriptionStatus } from "@prisma/client";
|
|
import { prisma } from "../../db/prisma.js";
|
|
import { requireAuth, type AuthenticatedRequest } from "../../middleware/auth.js";
|
|
import { signalListSchema } from "./signals.schemas.js";
|
|
import { listActiveSignalCountsByBot, listSignals } from "./signals.service.js";
|
|
|
|
export const signalsRouter = Router();
|
|
|
|
signalsRouter.use(requireAuth);
|
|
|
|
function withCreatedAtAsSignalTime<T extends { signalTime: Date; createdAt: Date }>(signal: T) {
|
|
return {
|
|
...signal,
|
|
signalTime: signal.createdAt
|
|
};
|
|
}
|
|
|
|
function activeSubscriptionWhere(userId: string, botKey: string) {
|
|
const now = new Date();
|
|
|
|
return {
|
|
userId,
|
|
status: SubscriptionStatus.active,
|
|
startsAt: {
|
|
lte: now
|
|
},
|
|
OR: [
|
|
{
|
|
expiresAt: null
|
|
},
|
|
{
|
|
expiresAt: {
|
|
gte: now
|
|
}
|
|
}
|
|
],
|
|
bot: {
|
|
key: botKey
|
|
}
|
|
};
|
|
}
|
|
|
|
signalsRouter.get("/", async (req: AuthenticatedRequest, res, next) => {
|
|
try {
|
|
const filters = signalListSchema.parse(req.query);
|
|
const signals = await listSignals(filters, {
|
|
userId: req.user?.id,
|
|
role: req.user?.role
|
|
});
|
|
res.json(signals);
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
signalsRouter.get("/active-counts", async (req: AuthenticatedRequest, res, next) => {
|
|
try {
|
|
const result = await listActiveSignalCountsByBot({
|
|
userId: req.user?.id,
|
|
role: req.user?.role
|
|
});
|
|
res.json(result);
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
signalsRouter.get("/:id", async (req: AuthenticatedRequest, res) => {
|
|
const signal = await prisma.signal.findUnique({
|
|
where: { id: String(req.params.id) },
|
|
include: { settlement: true, notifications: true }
|
|
});
|
|
|
|
if (!signal) {
|
|
return res.status(404).json({ message: "Сигнал не найден" });
|
|
}
|
|
|
|
if (req.user?.role !== "admin" && signal.sourceType !== "manual") {
|
|
const payload = signal.rawPayload && typeof signal.rawPayload === "object"
|
|
? (signal.rawPayload as Record<string, unknown>)
|
|
: null;
|
|
const botKey = payload?.botKey ? String(payload.botKey) : "";
|
|
|
|
if (!botKey) {
|
|
return res.status(403).json({ message: "Нет доступа к сигналу" });
|
|
}
|
|
|
|
const access = await prisma.userBotAccess.findFirst({
|
|
where: activeSubscriptionWhere(req.user!.id, botKey)
|
|
});
|
|
|
|
if (!access) {
|
|
return res.status(403).json({ message: "Нет доступа к сигналу" });
|
|
}
|
|
}
|
|
|
|
return res.json(withCreatedAtAsSignalTime(signal));
|
|
});
|