From eddaf0282485a8fde59bda199f229a4879bcc38c Mon Sep 17 00:00:00 2001 From: themodrnhakr Date: Mon, 29 Sep 2025 21:13:26 -0500 Subject: [PATCH] Add method to intelligently insert/update. The `upsert()` method can both create and update tasks. The method checks for an `id` propery to determine whether to `INSERT` or `UPDATE`. A successful operation returns a `ServiceResponse` object with the inserted task `id`, which can be used to fetch updated information if needed. The `NewTask` type is exported for use in form actions, etc. --- src/lib/server/services/tasks.ts | 33 ++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/lib/server/services/tasks.ts b/src/lib/server/services/tasks.ts index 47142ea..19cb0a4 100644 --- a/src/lib/server/services/tasks.ts +++ b/src/lib/server/services/tasks.ts @@ -1,7 +1,7 @@ import { type DB, db } from "$lib/server/db/db"; -import type { tasks, taskTypes } from "$lib/server/db/schema/tasks"; +import { tasks, type taskTypes } from "$lib/server/db/schema/tasks"; import type { ServiceResponse } from "$lib/server/services/service.types"; -import type { InferSelectModel } from "drizzle-orm"; +import { eq, type InferSelectModel } from "drizzle-orm"; import logger from "../logger"; export type Task = InferSelectModel & { @@ -12,6 +12,8 @@ export type TaskOrNull = InferSelectModel & { type: InferSelectModel | null; }; +export type NewTask = typeof tasks.$inferInsert; + class TasksService { private db: DB; private caller: "internal" | "api"; @@ -90,6 +92,33 @@ class TasksService { }) ); } + + public async upsert(taskData: NewTask): Promise> { + try { + if (taskData.id) { + const updated = await this.db.update(tasks) + .set(taskData) + .where(eq(tasks.id, taskData.id)) + .returning({ id: tasks.id }); + if (updated.length === 0) { + return { status: "failure", code: "VALIDATION_ERROR", error: `Task with ID ${taskData.id} not found for update.` }; + } + return { status: "ok", data: { id: updated[0].id } }; + } else { + const created = await this.db.insert(tasks) + .values(taskData) + .returning({ id: tasks.id }); + if (created.length === 0) { + throw new Error("Insert operation failed to return the new task."); + } + return { status: "ok", data: { id: created[0].id } }; + } + } + catch (error) { + logger.error({ msg: "Error upserting task.", error }); + return { status: "failure", error: "An internal server error occurred while saving the task.", code: "INTERNAL_ERROR" }; + } + } } export default TasksService;