From 8062fdb7f3ddcd55c9a4431383b29975955377d8 Mon Sep 17 00:00:00 2001 From: kenneth Date: Sun, 21 Sep 2025 22:24:24 +0000 Subject: [PATCH] wip: directory/file move name conflict check --- packages/convex/model/directories.ts | 37 ++++++++++++++++++++++++++++ packages/convex/model/error.ts | 5 ++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/convex/model/directories.ts b/packages/convex/model/directories.ts index 9ee7f39..a007989 100644 --- a/packages/convex/model/directories.ts +++ b/packages/convex/model/directories.ts @@ -171,6 +171,43 @@ export async function move( sourceDirectories: DirectoryHandle[] }, ): Promise { + const conflictCheckResults = await Promise.allSettled( + sourceDirectories.map((directory) => + ctx.db.get(directory.id).then((d) => { + if (!d) { + throw Err.create( + Err.Code.DirectoryNotFound, + `Directory ${directory.id} not found`, + ) + } + return ctx.db + .query("directories") + .withIndex("uniqueDirectoryInDirectory", (q) => + q + .eq("userId", ctx.user._id) + .eq("parentId", targetDirectory.id) + .eq("name", d.name) + .eq("deletedAt", undefined), + ) + .first() + }), + ), + ) + + const errors: Err.ApplicationError[] = [] + for (const result of conflictCheckResults) { + if (result.status === "fulfilled" && result.value) { + errors.push( + Err.create( + Err.Code.Conflict, + `Directory ${targetDirectory.id} already contains a directory with name ${result.value.name}`, + ), + ) + } else if (result.status === "rejected") { + errors.push(Err.create(Err.Code.Internal)) + } + } + await Promise.all( sourceDirectories.map((directory) => ctx.db.patch(directory.id, { parentId: targetDirectory.id }), diff --git a/packages/convex/model/error.ts b/packages/convex/model/error.ts index 87821d5..6347bc8 100644 --- a/packages/convex/model/error.ts +++ b/packages/convex/model/error.ts @@ -1,6 +1,7 @@ import { ConvexError } from "convex/values" export enum Code { + Conflict = "Conflict", DirectoryExists = "DirectoryExists", DirectoryNotFound = "DirectoryNotFound", FileExists = "FileExists", @@ -8,13 +9,13 @@ export enum Code { Unauthenticated = "Unauthenticated", } -export type ApplicationError = ConvexError<{ code: Code; message: string }> +export type ApplicationError = ConvexError<{ code: Code; message?: string }> export function isApplicationError(error: unknown): error is ApplicationError { return error instanceof ConvexError && "code" in error.data } -export function create(code: Code, message?: string) { +export function create(code: Code, message?: string): ApplicationError { return new ConvexError({ code, message: