From 5bc27f606140a0562a9283600109bf92007284d0 Mon Sep 17 00:00:00 2001 From: themodrnhakr Date: Mon, 29 Sep 2025 21:13:26 -0500 Subject: [PATCH] Improve typing and internal abstraction. The only breaking change here is the 'tasks' field is now 'data'. All other changes were made to improve TypeScripts ability to infer complex types or internal abstractions that don't affect client consumption. --- src/lib/server/services/tasks.ts | 66 +++++++++++++++++++------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/src/lib/server/services/tasks.ts b/src/lib/server/services/tasks.ts index 1da6c2d..9f467c3 100644 --- a/src/lib/server/services/tasks.ts +++ b/src/lib/server/services/tasks.ts @@ -1,6 +1,17 @@ import { type DB, db } from "$lib/server/db/db"; +import type { tasks, taskTypes } from "$lib/server/db/schema/tasks"; +import type { ServiceResponse } from "$lib/server/services/service.types"; +import type { InferSelectModel } from "drizzle-orm"; import logger from "../logger"; +type Task = InferSelectModel & { + type: InferSelectModel; +}; + +type TaskOrNull = InferSelectModel & { + type: InferSelectModel | null; +}; + class TasksService { private db: DB; private caller: "internal" | "api"; @@ -10,22 +21,33 @@ class TasksService { this.caller = caller; } - public async getAll() { - logger.info("Fetching all task records..."); + private async _executeQuery( + query: () => Promise, + ): Promise> { try { - const tasks = await this.db.query.tasks.findMany({ - with: { - type: true, - }, - }); - logger.debug(`Found ${tasks.length} records.`); - return { tasks, status: "ok" }; + const tasks = await query(); + + if (tasks.some(x => x.type === null)) { + const badTaskIds = tasks.filter(t => t.type === null).map(t => t.id); + logger.error(`Data integrity issue: The following tasks have invalid type IDs: ${badTaskIds.join(", ")}`); + return { + status: "failure", + error: "One or more tasks are invalid because they are not associated with a type.", + code: "DATA_INTEGRITY_VIOLATION", + }; + } + return { data: tasks as Task[], status: "ok" }; } catch (error) { logger.error({ msg: "Error querying the database.", error }); - return { status: "failed", error }; + return { status: "failure", error: "An internal server error occurred.", code: "INTERNAL_ERROR" }; } } + public async getAll() { + logger.info("Fetching all task records..."); + return this._executeQuery(() => this.db.query.tasks.findMany({ with: { type: true } })); + } + public async getByTaskId(taskIds: Array) { const mappedTasks = taskIds.map(x => { const prefix = x.slice(0, 2); @@ -41,30 +63,22 @@ class TasksService { : `${taskIds.length} records` }.`, ); - try { - const tasks = await db.query.tasks.findMany({ + return this._executeQuery(() => + this.db.query.tasks.findMany({ with: { type: true }, where: (tasks, { inArray }) => inArray(tasks.taskId, mappedTasks.map(x => x.task_id)), - }); - return { tasks, status: "ok" }; - } catch (error) { - logger.error({ msg: "Error querying the database.", error }); - return { status: "failed", error }; - } + }) + ); } public async getByDbId(ids: Array) { logger.info(`Fetching ${ids.length} records.`); - try { - const tasks = await db.query.tasks.findMany({ + return this._executeQuery(() => + this.db.query.tasks.findMany({ with: { type: true }, where: (tasks, { inArray }) => inArray(tasks.id, ids), - }); - return { tasks, status: "ok" }; - } catch (error) { - logger.error({ msg: "Error querying the database.", error }); - return { status: "failed", error }; - } + }) + ); } }