feat: add server error logging and tighten workspace isolation

This commit is contained in:
2026-08-10 12:41:46 +00:00
parent 6449f6b4cc
commit 1059512888
48 changed files with 1096 additions and 229 deletions
+17 -8
View File
@@ -165,6 +165,10 @@ const tools: ToolDefinition[] = [
required: ["task_id"],
},
handler: async (params, auth) => {
const [existing] = await db.select().from(tasks).where(and(eq(tasks.id, params.task_id as string), isNull(tasks.deletedAt))).limit(1);
if (!existing) throw new JsonRpcErrorResponse(JSONRPC_INTERNAL_ERROR, "Task not found");
await verifyDomainAccess(existing.domainId, auth.userId);
const updateData: Record<string, unknown> = {};
if (params.title !== undefined) updateData.title = params.title;
if (params.description !== undefined) updateData.description = params.description;
@@ -178,8 +182,6 @@ const tools: ToolDefinition[] = [
.where(and(eq(tasks.id, params.task_id as string), isNull(tasks.deletedAt)))
.returning();
if (!task) throw new JsonRpcErrorResponse(JSONRPC_INTERNAL_ERROR, "Task not found");
await recordActivity({
actor: auth.userName,
action: "updated",
@@ -201,13 +203,15 @@ const tools: ToolDefinition[] = [
required: ["task_id"],
},
handler: async (params, auth) => {
const [existing] = await db.select().from(tasks).where(and(eq(tasks.id, params.task_id as string), isNull(tasks.deletedAt))).limit(1);
if (!existing) throw new JsonRpcErrorResponse(JSONRPC_INTERNAL_ERROR, "Task not found");
await verifyDomainAccess(existing.domainId, auth.userId);
const [task] = await db.update(tasks)
.set({ deletedAt: new Date(), updatedAt: new Date() })
.where(and(eq(tasks.id, params.task_id as string), isNull(tasks.deletedAt)))
.returning();
if (!task) throw new JsonRpcErrorResponse(JSONRPC_INTERNAL_ERROR, "Task not found");
await recordActivity({
actor: auth.userName,
action: "deleted",
@@ -228,13 +232,15 @@ const tools: ToolDefinition[] = [
required: ["task_id"],
},
handler: async (params, auth) => {
const [existing] = await db.select().from(tasks).where(and(eq(tasks.id, params.task_id as string), isNull(tasks.deletedAt))).limit(1);
if (!existing) throw new JsonRpcErrorResponse(JSONRPC_INTERNAL_ERROR, "Task not found");
await verifyDomainAccess(existing.domainId, auth.userId);
const [task] = await db.update(tasks)
.set({ status: "done", completedAt: new Date(), updatedAt: new Date() })
.where(and(eq(tasks.id, params.task_id as string), isNull(tasks.deletedAt)))
.returning();
if (!task) throw new JsonRpcErrorResponse(JSONRPC_INTERNAL_ERROR, "Task not found");
await recordActivity({
actor: auth.userName,
action: "completed",
@@ -313,6 +319,7 @@ const tools: ToolDefinition[] = [
handler: async (params, auth) => {
const [habit] = await db.select().from(habits).where(and(eq(habits.id, params.habit_id as string), isNull(habits.deletedAt))).limit(1);
if (!habit) throw new JsonRpcErrorResponse(JSONRPC_INTERNAL_ERROR, "Habit not found");
await verifyDomainAccess(habit.domainId, auth.userId);
const [completion] = await db.insert(habitCompletions).values({
habitId: params.habit_id as string,
@@ -444,6 +451,10 @@ const tools: ToolDefinition[] = [
required: ["note_id"],
},
handler: async (params, auth) => {
const [existing] = await db.select().from(notes).where(and(eq(notes.id, params.note_id as string), isNull(notes.deletedAt))).limit(1);
if (!existing) throw new JsonRpcErrorResponse(JSONRPC_INTERNAL_ERROR, "Note not found");
await verifyDomainAccess(existing.domainId, auth.userId);
const updateData: Record<string, unknown> = { updatedAt: new Date() };
if (params.title !== undefined) updateData.title = params.title;
if (params.content !== undefined) updateData.content = params.content;
@@ -453,8 +464,6 @@ const tools: ToolDefinition[] = [
.where(and(eq(notes.id, params.note_id as string), isNull(notes.deletedAt)))
.returning();
if (!note) throw new JsonRpcErrorResponse(JSONRPC_INTERNAL_ERROR, "Note not found");
await recordActivity({
actor: auth.userName,
action: "updated",