import { Request, Response } from "express"; import { buildDatatableQuery } from "@utils/datatable"; import { db } from "@db/db"; import { Subscription, Channel } from "@db/models/subs.model"; const isPostgres = db.client.config.client === "pg"; const TABLE = "subscriptions"; export const datatable = async (request: Request, response: Response) => { try { let query = db(TABLE).where({ guild_id: request.params.guildId }); const datatableQuery = await buildDatatableQuery(request as any, query, TABLE); const { recordsTotal, recordsFiltered } = datatableQuery; query = datatableQuery.query; query.select("subscriptions.*") .leftJoin("channels", "subscriptions.id", "=", "channels.subscription_id") .select(db.raw(isPostgres ? "json_agg(channels.channel_id) as channels" :"JSON_GROUP_ARRAY(channels.channel_id) as channels" )) .groupBy("subscriptions.id") const data = await query; console.debug(`total: ${recordsTotal} filtered: ${recordsFiltered} filtered+paged: ${data.length}`); data.forEach((item: any) => { item.channels = item.channels === "[null]" ? [] : JSON.parse(item.channels); }); response.json({ data, recordsFiltered, recordsTotal, }); } catch (error) { console.error(error); response.status(500).json({ error: "Failed to fetch datatable for subscriptions" }); } } export const get = async (request: Request, response: Response) => { try { if (!request.query.id) { response.status(400).json({ error: "missing 'id' query" }); return; } const data = await db("subscriptions") .leftJoin("channels", "subscriptions.id", "=", "channels.subscription_id") .select("subscriptions.*") .select(db.raw(isPostgres ? "json_agg(channels.channel_id) as channels" :"JSON_GROUP_ARRAY(channels.channel_id) as channels" )) .groupBy("subscriptions.id") .where({ "subscriptions.id": request.query.id }) .first(); if (!data) { response.status(404).json({ message: "no result found" }); return; } data.channels = JSON.parse(data.channels); response.json(data); } catch (error) { console.error(error); response.status(500).json({ error: "Failed to fetch subscription" }); } } export const post = async (request: Request, response: Response) => { try { console.debug(JSON.stringify(request.body, null, 4)); const guild_id = request.params.guildId; const { name, url, message_style, published_threshold, channels, filters, active } = request.body; if (!name || !url || !message_style || !published_threshold) { response.status(400).json({ error: "Missing required fields" }); return; } const [subscription] = await db(TABLE) .insert({ name, url, guild_id, active: active ?? true, created_at: new Date(), updated_at: new Date() }) .returning("*"); if (channels && channels.length) { const channelData = channels.map((channel_id: string) => ({ channel_id, subscription_id: subscription.id })); await db("channels").insert(channelData); } response.status(201).json({ ...subscription, channels: channels ?? [] }); } catch (error) { console.error(error); response.status(500).json({ error: "Failed to create subscription" }); } } export const del = async (request: Request, response: Response) => { try { let ids: any = request.query.id; if (!ids) { response.status(400).json({ error: "missing 'id' query" }); return; } if (Array.isArray(ids)) { ids = [ids]; } await db(TABLE).whereIn("id", ids).delete(); response.status(204).json(null); } catch (error) { console.error(error); response.status(500).json({ error: "Failed to delete subscription" }) } } export default { datatable, get, post, del }