import { redis } from "$lib/server/connectors/redis"; import { dbApiData } from "$lib/server/db/apidata.db"; import { dbDraw } from "$lib/server/db/apidraw.db"; import { dbApiUser } from "$lib/server/db/apiuser.db"; import { getData } from "$lib/server/external/api.scraping.helpers"; import { getReducedFinalSheet } from "$lib/server/finalsheet.helpers"; import { getDefaultTotals, getULID } from "$lib/utils"; import { constants } from "$lib/utils/constants"; import { ApiUserTypes, type APISession, type ReducedFinalSheetData, type ServerError, } from "$lib/utils/data.types"; import { z } from "zod"; import { createTRPCRouter, protectedProcedure } from "../t"; const lastFetched = { get: async () => { const out = await redis.get(constants.LAST_FETCHED_KEY); if (out === null) { return "Not fetched yet"; } return out; }, set: async () => { await redis.set(constants.LAST_FETCHED_KEY, new Date().toISOString()); }, }; export const apiDataRouter = createTRPCRouter({ getDealersAndDraws: protectedProcedure.query(async () => { const draws = await dbDraw.getAllDraws(true); const dealers = await dbApiUser.allUsersOfType(ApiUserTypes.DEALER); const lf = await lastFetched.get(); return { users: dealers, draws, lastFetched: lf }; }), refetchData: protectedProcedure .input( z.object({ userIds: z.array(z.string()), drawId: z.string(), targetDate: z.string(), }), ) .mutation(async ({ input }) => { const { userIds, targetDate, drawId } = input; if (userIds.length < 1) { return { detail: "No users selected", success: false, errors: [ { message: "No users selected to refetch data for" }, ] as ServerError, }; } const sess = JSON.parse( (await redis.get(constants.SCRAP_API_SESSION_KEY)) ?? "", ) as APISession; if (sess === null) { return { detail: "API Session expired", success: false, errors: [ { message: "API Session expired, get a new api session and try again", }, ] as ServerError, }; } const userIdsInt = userIds.map((x) => parseInt(x.split(":")[1])); const out = await getData( sess.sessionToken, userIdsInt, parseInt(drawId.split(":")[1]), targetDate, ); if (!out.ok) { return { success: false, detail: "Error fetching data", errors: [{ message: out.message }] as ServerError, }; } const dataCount = out.data.length; await dbApiData.upsertData(out.data, targetDate); return { detail: `Scraped ${dataCount} entries for ${userIds.length} users`, success: true, errors: [] as ServerError, }; }), getDataByFilters: protectedProcedure .input( z.object({ date: z.string(), drawId: z.string(), userId: z.string() }), ) .mutation(async ({ input }) => { const { date, drawId, userId } = input; const data = await dbApiData.getBookingEntriesForDealer( date, drawId.split(":")[1], userId.split(":")[1], true, ); return { data }; }), getReducedFinalSheet: protectedProcedure .input(z.object({ date: z.string(), drawId: z.string() })) .mutation(async ({ input }) => { const { date, drawId } = input; const draw = await dbDraw.getDraw(drawId); const fsData = { id: getULID(), date, drawId, data: [], totals: getDefaultTotals(), } as ReducedFinalSheetData; if (!draw) { return { ok: false, detail: `Draw for the passed draw ID not found`, data: fsData, errors: [ { message: `Draw for the passed draw ID not found` }, ] as ServerError, }; } console.log("Fetching data"); const data = await getReducedFinalSheet(fsData); console.log(data); if (!data.ok) { return { ok: false, detail: `Error compiling final sheet`, data: fsData, errors: data.errors, }; } return { ok: true, detail: `Final sheet for ${date}, draw ${draw.title} has been compiled`, data: fsData, errors: [] as ServerError, }; }), getFinalSheetRow: protectedProcedure .input( z.object({ date: z.string(), drawId: z.string(), number: z.string() }), ) .mutation(async ({ input }) => { return { ok: true, data: {}, errors: [] as ServerError, }; }), delDataOlderThan2Weeks: protectedProcedure.mutation(async () => { await dbApiData.deleteDataOlderThan2Weeks(); return { ok: true, detail: "Data older than 2 weeks has been deleted" }; }), postTestBooking: protectedProcedure .input(z.object({ drawId: z.string(), date: z.string() })) .mutation(async () => { return { ok: true, detail: "API not live", errors: [] as ServerError, }; // console.log("GENERATING TEST DATA :: ", drawId, date); // const testData = await getTestBookingData(drawId, date); // // console.log(testData); // await dbApiData.upsertData(testData, date); // return { // ok: true, // detail: "Test booking committed", // errors: [] as ServerError, // }; }), });