refactor(api): cleaned the feed api code to be more maintainable, and added logging
Some checks failed
Build & Push Docker Image / build (push) Has been cancelled
Test & Build / build (push) Has been cancelled

This commit is contained in:
Corban-Lee Jones 2025-05-20 17:19:42 +01:00
parent 99e1b0ef96
commit dc3deffb32

View File

@ -1,11 +1,15 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import prisma, { Prisma } from "@server/prisma"; import prisma, { Prisma } from "@server/prisma";
import { datatableRequest } from "@server/controllers/guild/api/dt.module"; import { datatableRequest } from "@server/controllers/guild/api/dt.module";
import { logger } from "@server/../log"; import { getLogger } from "@server/../log";
const logger = getLogger(__filename);
export const get = async (request: Request, response: Response) => { export const get = async (request: Request, response: Response) => {
logger.info(`Getting feed: ${request.query.id}`);
if (!request.query.id) { if (!request.query.id) {
response.status(400).json({ error: "missing 'id' query" }); response.status(400).json({ error: "Missing 'id' query" });
return; return;
} }
@ -15,162 +19,111 @@ export const get = async (request: Request, response: Response) => {
}); });
if (!feed) { if (!feed) {
response.status(404).json({ message: "no result found" }); response.status(404).json({ message: "No result found" });
return; return;
} }
response.json(feed); response.json(feed);
}; };
const unpackChannels = (channels: string[] | string | undefined) => {
if (channels === undefined) return channels;
return Array.isArray(channels)
? channels.map(channelId => ({ channel_id: channelId }))
: [{ channel_id: channels }];
};
const unpackFilters = (filters: string[] | string | undefined) => {
if (filters === undefined) return filters;
return Array.isArray(filters)
? filters.map(filterId => ({ id: Number(filterId) }))
: [{ id: Number(filters) }]
};
export const post = async (request: Request, response: Response) => { export const post = async (request: Request, response: Response) => {
const guildId = request.params.guildId; logger.info(`Posting feed: ${request.body.url} - ${request.params.guildId}`);
const {
name,
url,
active,
channels,
filters,
message_style,
published_threshold
} = request.body;
logger.debug("Post Feed", request.body); const body = {
...request.body,
active: request.body.active === "on",
message_style: Number(request.body.message_style) || null,
published_threshold: new Date(request.body.published_threshold)
};
// channels comes through as either String[] or String const createInputData: Prisma.FeedUncheckedCreateInput = {
let formattedChannels = undefined; guild_id: request.params.guildId,
if (channels !== undefined) { name: body.name,
formattedChannels = Array.isArray(channels) url: body.url,
? channels.map((channelId) => ({ channel_id: channelId })) active: body.active,
: [{ channel_id: channels }] channels: { create: unpackChannels(body.channels) },
} filters: { connect: unpackFilters(body.filters) },
message_style_id: body.message_style,
let formattedFilters = undefined; published_threshold: body.published_threshold
if (filters !== undefined) { };
formattedFilters = Array.isArray(filters)
? filters.map((filterId) => ({ id: Number(filterId) }))
: [{ id: Number(filters) }]
}
let feed;
try { try {
feed = await prisma.feed.create({ const createResponse = await prisma.feed.create({ data: createInputData });
data: { response.status(201).json(createResponse);
name: name, } catch (error) {
url: url, logger.error(error);
guild_id: guildId, const isPrismaError = error instanceof Prisma.PrismaClientKnownRequestError;
active: active === "on", response.status(500).json({ error: isPrismaError ? error.message : error });
channels: { create: formattedChannels },
filters: { connect: formattedFilters },
message_style_id: message_style === "" ? null : Number(message_style),
published_threshold: new Date(published_threshold)
}
});
} }
catch (error) {
console.error(error);
if (error instanceof Prisma.PrismaClientKnownRequestError) {
response.status(500).json({ error: error.message });
return;
}
}
response.status(201).json(feed);
}; };
export const patch = async (request: Request, response: Response) => { export const patch = async (request: Request, response: Response) => {
const guildId = request.params.guildId; logger.info(`Patching feed: ${request.body.id} - ${request.params.guildId}`);
const {
id,
name,
url,
active,
channels,
filters,
message_style,
published_threshold
} = request.body;
logger.info("Patch Feed", request.body); const body = {
...request.body,
active: request.body.active === "on",
message_style: Number(request.body.message_style) || null,
published_threshold: new Date(request.body.published_threshold)
};
// channels comes through as either String[] or String const updateInputData: Prisma.FeedUncheckedUpdateInput = {
let formattedChannels = undefined; id: Number(body.id),
if (channels !== undefined) { name: body.name,
formattedChannels = Array.isArray(channels) url: body.url,
? channels.map((channelId) => ({ channel_id: channelId })) active: body.active,
: [{ channel_id: channels }] channels: { deleteMany: {}, create: unpackChannels(body.channels) },
} filters: { set: [], connect: unpackFilters(body.filters) },
message_style_id: body.message_style,
let formattedFilters = undefined; published_threshold: body.published_threshold
if (filters !== undefined) { };
formattedFilters = Array.isArray(filters)
? filters.map((filterId) => ({ id: Number(filterId) }))
: [{ id: Number(filters) }]
}
let feed;
try { try {
feed = await prisma.feed.update({ const updateArgs = { where: { id: Number(body.id) }, data: updateInputData };
where: { id: Number(id) }, const updateResponse = await prisma.feed.update(updateArgs);
data: { response.status(200).json(updateResponse);
name: name, } catch (error) {
url: url, logger.error(error);
guild_id: guildId, const isPrismaError = error instanceof Prisma.PrismaClientKnownRequestError;
active: active === "on", response.status(500).json({ error: isPrismaError ? error.message : error });
channels: {
deleteMany: {},
create: formattedChannels
},
filters: {
set: [],
connect: formattedFilters
},
message_style_id:
message_style === ""
? null
: Number(message_style),
published_threshold: new Date(published_threshold)
}
});
} }
catch (error) { };
console.error(error);
if (error instanceof Prisma.PrismaClientKnownRequestError) {
response.status(500).json({ error: error.message });
return;
}
}
response.status(201).json(feed);
}
export const del = async (request: Request, response: Response) => { export const del = async (request: Request, response: Response) => {
let { ids } = request.body; logger.info(`Deleting feed(s): ${request.body.ids} - ${request.params.guildId}`);
const guildId = request.params.guildId;
if (!ids || !Array.isArray(ids)) { const ids = request.body.ids?.map((id: string) => Number(id));
response.status(400).json({ error: "invalid request body" });
if (!ids) {
response.status(400).json({ error: `Couldn't parse ID's from request body` });
return; return;
} }
ids = ids.map(id => Number(id));
try { try {
await prisma.feed.deleteMany({ where: { const deleteArgs = { where: { guild_id: request.params.guildId, id: { in: ids } } };
id: { in: ids }, await prisma.feed.deleteMany(deleteArgs);
guild_id: guildId response.status(204).send();
}}); } catch (error) {
logger.error(error);
const isPrismaError = error instanceof Prisma.PrismaClientKnownRequestError;
response.status(500).json({ error: isPrismaError ? error.message : error });
} }
catch (error) {
console.error(error);
if (error instanceof Prisma.PrismaClientKnownRequestError) {
response.status(500).json({ error: error.message });
return;
}
}
response.status(204).json(null);
}; };
export const datatable = async (request: Request, response: Response) => { export const datatable = async (request: Request, response: Response) => {