Files
no-twitter-bot-stats/src/graphql/resolvers.ts
Lucid 07aa4ff6b5
Some checks are pending
Main / build-and-push-docker-image (20.x) (push) Waiting to run
Removed image. Added gradient. Removed unnecessary logic in resolvers. Added line chart label.
2025-12-16 17:11:44 -05:00

296 lines
7.0 KiB
TypeScript

import prisma from "@/lib/prismaClient";
import { BigIntResolver } from "graphql-scalars";
const envMutationKey = process.env.MUTATION_KEY || "";
const env = process.env.NODE_ENV || "development";
const isDailyStatToday = (date: string): boolean => {
const today = new Date().setHours(0, 0, 0, 0);
const dailyStatCreated = new Date(date).setHours(0, 0, 0, 0);
return today == dailyStatCreated;
};
const getLatestDailyStat = async () => {
return await prisma.dailyStats.findFirst({
orderBy: {
createdAt: "desc"
}
});
};
// Prisma
export const resolvers = {
// scalars
BigInt: BigIntResolver,
Query: {
getTotalGroups: async () => await prisma.groups.count(),
getTodayStats: async () =>
await prisma.dailyStats.findFirst({
orderBy: {
createdAt: "desc"
}
}),
getStatsRange: async (
_parent: unknown,
data: { startDate: Date; endDate: Date }
// _ctx: unknown
) => {
const { startDate, endDate } = data;
if (!startDate || !endDate) {
return null;
}
return await prisma.dailyStats.findMany({
where: {
createdAt: {
gt: startDate,
lte: endDate
}
},
orderBy: {
createdAt: "asc"
}
});
},
getTotalStats: async () =>
await prisma.totalStats.findFirst({
orderBy: {
createdAt: "asc"
}
}),
getGroupStats: async (
_parent: unknown,
data: { groupID: number }
// _ctx: unknown
) =>
await prisma.groups.findUnique({
where: {
telegramID: BigInt(data.groupID)
}
})
},
Mutation: {
init: async (
_parent: unknown,
data: { mutationKey?: string }
// _ctx: unknown
) => {
const { mutationKey } = data;
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
const date = new Date().toISOString();
let count = 0;
if ((await prisma.dailyStats.count()) === 0) {
await prisma.dailyStats.create({ data: { createdAt: date } });
count++;
}
if ((await prisma.totalStats.count()) === 0) {
await prisma.totalStats.create({ data: { createdAt: date } });
count++;
}
return `${count} tables have been initialized with data.`;
},
cronJob: async (
_parent: unknown,
data: { mutationKey?: string }
// _ctx: unknown
) => {
const { mutationKey } = data;
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
const latestDailyStats = await getLatestDailyStat();
if (latestDailyStats !== null) {
if (isDailyStatToday(String(latestDailyStats.createdAt))) {
return null;
}
}
const date = new Date().toISOString();
await prisma.dailyStats.create({ data: { createdAt: date } });
const allStats = await prisma.dailyStats.findMany({});
const calculatedStats = allStats.reduce(
(acc, curr) => {
const links = (acc.linksDeleted += curr.linksDeleted);
const commands = (acc.commandResponses += curr.commandResponses);
const triggers = (acc.timesTriggered += curr.timesTriggered);
return {
linksDeleted: links,
commandResponses: commands,
timesTriggered: triggers
};
},
{
linksDeleted: 0,
commandResponses: 0,
timesTriggered: 0
}
);
const totalStats = await prisma.totalStats.findFirst({
orderBy: {
createdAt: "desc"
}
});
return await prisma.totalStats.update({
where: {
createdAt: totalStats?.createdAt
},
data: {
...calculatedStats
}
});
},
addGroup: async (
_parent: unknown,
data: {
groupID: string;
groupName: string;
groupUsername: string;
mutationKey?: string;
}
// _ctx: unknown
) => {
const { groupID, groupName, groupUsername, mutationKey } = data;
const groupIDInt = BigInt(groupID);
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
const existingGroup = await prisma.groups.findUnique({
where: { telegramID: groupIDInt }
});
if (existingGroup !== null) {
if (
existingGroup.name !== groupName ||
existingGroup.username !== groupUsername
) {
return await prisma.groups.update({
where: {
telegramID: existingGroup.telegramID
},
data: { name: groupName, username: groupUsername || "" }
});
}
return existingGroup;
}
return await prisma.groups.create({
data: {
telegramID: groupIDInt,
name: groupName
}
});
},
incrementGroup: async (
_parent: unknown,
data: { groupID: number; linksDeleted: number; mutationKey?: string }
// _ctx: unknown
) => {
const { groupID, linksDeleted, mutationKey } = data;
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
return await prisma.groups.update({
where: { telegramID: BigInt(groupID) },
data: { linksDeleted: { increment: linksDeleted } }
});
},
increment: async (
_parent: unknown,
data: {
link: boolean;
command: boolean;
trigger: boolean;
mutationKey?: string;
}
// _ctx: unknown
) => {
const { link, command, trigger, mutationKey } = data;
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
let latestDailyStats = await getLatestDailyStat();
if (latestDailyStats !== null) {
if (!isDailyStatToday(String(latestDailyStats.createdAt))) {
const date = new Date().toISOString();
await prisma.dailyStats
.create({ data: { createdAt: date } })
.then(async () => {
latestDailyStats = await prisma.dailyStats.findFirst({
orderBy: {
createdAt: "desc"
}
});
});
}
return await prisma.dailyStats.update({
where: { createdAt: latestDailyStats.createdAt },
data: {
linksDeleted: { increment: link ? 1 : 0 },
commandResponses: { increment: command ? 1 : 0 },
timesTriggered: { increment: trigger ? 1 : 0 }
}
});
}
}
}
};
export default resolvers;