import { sql } from "kysely"; import type { StackedTimeserie } from "~/components/timeserieBarChartStacked"; import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum"; import { adminProcedure, createTRPCRouter } from "~/server/api/trpc"; import { db } from "~/server/db"; export const statsRouter = createTRPCRouter({ adminDashStats: adminProcedure.query(async () => { const userTimeserie = ( await db .selectFrom("users") .select((eb) => [ sql`date_trunc('day', created_at)`.as("date"), eb.fn.count("id").as("value"), ]) .where("isAdmin", "=", false) .groupBy("date") .orderBy("date") .execute() ).map((item) => ({ date: item.date, value: parseInt(String(item.value)), })); const serviziTimeserie = { valueALabel: "Transitorio", valueBLabel: "Stabile", data: Object.values( ( await db .selectFrom("servizio") .select((eb) => [ sql`date_trunc('day', created_at)`.as("date"), eb.fn.count("servizio_id").as("value"), "tipologia", ]) .groupBy(["date", "tipologia"]) .orderBy("date") .execute() ).reduce( (acc, item) => { const dateStr = item.date.toISOString().slice(0, 10); if (!acc[dateStr]) { acc[dateStr] = { date: item.date, valueA: 0, valueB: 0, }; } if (item.tipologia === TipologiaPosizioneEnum.Transitorio) { acc[dateStr].valueA = parseInt(String(item.value)); } else if (item.tipologia === TipologiaPosizioneEnum.Stabile) { acc[dateStr].valueB = parseInt(String(item.value)); } return acc; }, {} as Record, ), ), }; const contattiTimeserie = ( await db .selectFrom("servizio_annunci") .select((eb) => [ sql`date_trunc('day', created_at)`.as("date"), eb.fn .count(eb.fn("concat", ["servizio_id", "annunci_id"])) .as("value"), ]) .where("open_contatti_at", "is not", null) .groupBy("date") .orderBy("date") .execute() ).map((item) => ({ date: item.date, value: parseInt(String(item.value)), })); const userCount = ( await db .selectFrom("users") .select((eb) => [eb.fn.count("id").as("count")]) .executeTakeFirst() )?.count || 0; return { userTimeserie, userCount, contattiTimeserie, serviziTimeserie, }; }), });