feat: add lastEdited field update

This commit is contained in:
Kirill Siukhin 2025-07-16 19:36:32 +05:00
parent b3d7eb99eb
commit 0e1ff2b415
2 changed files with 124 additions and 51 deletions

View File

@ -3,7 +3,7 @@
import { revalidatePath } from "next/cache"; import { revalidatePath } from "next/cache";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { db } from "@/lib/db"; import { db } from "@/lib/db";
import { blocksTable, IBlock } from "@/lib/db/schema"; import { blocksTable, IBlock, notesTable } from "@/lib/db/schema";
import { requireAuth } from "./auth"; import { requireAuth } from "./auth";
import { assertNoteOwner } from "./notes"; import { assertNoteOwner } from "./notes";
@ -14,24 +14,31 @@ export async function assertBlockOwner(blockId: string): Promise<boolean> {
where: eq(blocksTable.id, blockId), where: eq(blocksTable.id, blockId),
with: { note: true }, with: { note: true },
}); });
if (!block) { if (!block) return false;
return false;
}
return block.note.authorId === user.id; return block.note.authorId === user.id;
} }
export async function createBlock(formData: FormData) { export async function createBlock(formData: FormData) {
const noteId = formData.get("noteId") as string; const noteId = formData.get("noteId") as string;
const isAllowed = await assertNoteOwner(noteId); const isAllowed = await assertNoteOwner(noteId);
if (!isAllowed) return; if (!isAllowed) return;
const blocks = await getBlocks(noteId); const blocks = await getBlocks(noteId);
const lastBlock = blocks.pop(); const lastBlock = blocks.pop();
const order = lastBlock === undefined ? 1 : lastBlock.order + 1; const order = lastBlock === undefined ? 1 : lastBlock.order + 1;
await db
.insert(blocksTable) await db.transaction(async (tx) => {
.values({ noteId, order }); await tx
.insert(blocksTable)
.values({ noteId, order });
await tx
.update(notesTable)
.set({ lastEdited: new Date() })
.where(eq(notesTable.id, noteId));
});
revalidatePath("/notes/[id]", "page"); revalidatePath("/notes/[id]", "page");
} }
@ -43,11 +50,8 @@ async function getBlock(blockId: string): Promise<IBlock | null> {
.select() .select()
.from(blocksTable) .from(blocksTable)
.where(eq(blocksTable.id, blockId)); .where(eq(blocksTable.id, blockId));
if (blocks.length === 0) {
return null; return blocks.length === 0 ? null : blocks[0];
} else {
return blocks[0];
}
} }
export async function getBlocks(noteId: string): Promise<IBlock[]> { export async function getBlocks(noteId: string): Promise<IBlock[]> {
@ -62,57 +66,93 @@ export async function getBlocks(noteId: string): Promise<IBlock[]> {
export async function deleteBlock(formData: FormData) { export async function deleteBlock(formData: FormData) {
const blockId = formData.get("blockId") as string; const blockId = formData.get("blockId") as string;
const isAllowed = await assertBlockOwner(blockId); const isAllowed = await assertBlockOwner(blockId);
if (!isAllowed) return; if (!isAllowed) return;
await db
.delete(blocksTable) const block = await getBlock(blockId);
.where(eq(blocksTable.id, blockId)); if (!block) return;
await db.transaction(async (tx) => {
await tx
.delete(blocksTable)
.where(eq(blocksTable.id, blockId));
await tx
.update(notesTable)
.set({ lastEdited: new Date() })
.where(eq(notesTable.id, block.noteId));
});
revalidatePath("/notes/[id]", "page"); revalidatePath("/notes/[id]", "page");
} }
export async function changeLock(formData: FormData) { export async function changeLock(formData: FormData) {
const blockId = formData.get("blockId") as string; const blockId = formData.get("blockId") as string;
const isLocked = formData.get("isLocked") === null ? false : true; const isLocked = formData.get("isLocked") === null ? false : true;
const isAllowed = await assertBlockOwner(blockId); const isAllowed = await assertBlockOwner(blockId);
if (!isAllowed) return; if (!isAllowed) return;
await db
.update(blocksTable) const block = await getBlock(blockId);
.set({ isLocked }) if (!block) return;
.where(eq(blocksTable.id, blockId));
await db.transaction(async (tx) => {
await tx
.update(blocksTable)
.set({ isLocked })
.where(eq(blocksTable.id, blockId));
await tx
.update(notesTable)
.set({ lastEdited: new Date() })
.where(eq(notesTable.id, block.noteId));
});
revalidatePath("/notes/[id]", "page"); revalidatePath("/notes/[id]", "page");
} }
export async function addLine(formData: FormData) { export async function addLine(formData: FormData) {
const blockId = formData.get("blockId") as string; const blockId = formData.get("blockId") as string;
const isAllowed = await assertBlockOwner(blockId); const isAllowed = await assertBlockOwner(blockId);
if (!isAllowed) return; if (!isAllowed) return;
const blocks = await db
.select() const block = await getBlock(blockId);
.from(blocksTable) if (!block) return;
.where(eq(blocksTable.id, blockId));
if (blocks.length === 0) { await db.transaction(async (tx) => {
return; await tx
} .update(blocksTable)
const block = blocks[0]; .set({ lines: [...block.lines, ""] })
await db .where(eq(blocksTable.id, blockId));
.update(blocksTable) await tx
.set({ lines: [...block.lines, ""] }) .update(notesTable)
.where(eq(blocksTable.id, blockId)); .set({ lastEdited: new Date() })
.where(eq(notesTable.id, block.noteId));
});
revalidatePath("/notes/[id]", "page"); revalidatePath("/notes/[id]", "page");
} }
export async function deleteLine(formData: FormData) { export async function deleteLine(formData: FormData) {
const blockId = formData.get("blockId") as string; const blockId = formData.get("blockId") as string;
const block = await getBlock(blockId);
const isAllowed = await assertBlockOwner(blockId); const isAllowed = await assertBlockOwner(blockId);
if (!isAllowed) return; if (!isAllowed) return;
if (!block) {
return; const block = await getBlock(blockId);
} if (!block) return;
await db
.update(blocksTable) await db.transaction(async (tx) => {
.set({ lines: block.lines.slice(0, -1) }) await tx
.where(eq(blocksTable.id, blockId)); .update(blocksTable)
.set({ lines: block.lines.slice(0, -1) })
.where(eq(blocksTable.id, blockId));
await tx
.update(notesTable)
.set({ lastEdited: new Date() })
.where(eq(notesTable.id, block.noteId));
});
revalidatePath("/notes/[id]", "page"); revalidatePath("/notes/[id]", "page");
} }
@ -120,6 +160,7 @@ export async function moveUp(formData: FormData) {
const blockId = formData.get("blockId") as string; const blockId = formData.get("blockId") as string;
const isAllowed = await assertBlockOwner(blockId); const isAllowed = await assertBlockOwner(blockId);
if (!isAllowed) return; if (!isAllowed) return;
const block = await getBlock(blockId); const block = await getBlock(blockId);
if (!block) return; if (!block) return;
@ -139,6 +180,10 @@ export async function moveUp(formData: FormData) {
.update(blocksTable) .update(blocksTable)
.set({ order: block.order }) .set({ order: block.order })
.where(eq(blocksTable.id, prevBlock.id)); .where(eq(blocksTable.id, prevBlock.id));
await tx
.update(notesTable)
.set({ lastEdited: new Date() })
.where(eq(notesTable.id, block.noteId));
}); });
revalidatePath("/notes/[id]", "page"); revalidatePath("/notes/[id]", "page");
@ -148,6 +193,7 @@ export async function moveDown(formData: FormData) {
const blockId = formData.get("blockId") as string; const blockId = formData.get("blockId") as string;
const isAllowed = await assertBlockOwner(blockId); const isAllowed = await assertBlockOwner(blockId);
if (!isAllowed) return; if (!isAllowed) return;
const block = await getBlock(blockId); const block = await getBlock(blockId);
if (!block) return; if (!block) return;
@ -167,6 +213,10 @@ export async function moveDown(formData: FormData) {
.update(blocksTable) .update(blocksTable)
.set({ order: block.order }) .set({ order: block.order })
.where(eq(blocksTable.id, nextBlock.id)); .where(eq(blocksTable.id, nextBlock.id));
await tx
.update(notesTable)
.set({ lastEdited: new Date() })
.where(eq(notesTable.id, block.noteId));
}); });
revalidatePath("/notes/[id]", "page"); revalidatePath("/notes/[id]", "page");
@ -175,17 +225,37 @@ export async function moveDown(formData: FormData) {
export async function setLines(blockId: string, lines: string[]) { export async function setLines(blockId: string, lines: string[]) {
const isAllowed = await assertBlockOwner(blockId); const isAllowed = await assertBlockOwner(blockId);
if (!isAllowed) return; if (!isAllowed) return;
await db
.update(blocksTable) const block = await getBlock(blockId);
.set({ lines }) if (!block) return;
.where(eq(blocksTable.id, blockId));
await db.transaction(async (tx) => {
await tx
.update(blocksTable)
.set({ lines })
.where(eq(blocksTable.id, blockId));
await tx
.update(notesTable)
.set({ lastEdited: new Date() })
.where(eq(notesTable.id, block.noteId));
});
} }
export async function setTag(blockId: string, tag: string) { export async function setTag(blockId: string, tag: string) {
const isAllowed = await assertBlockOwner(blockId); const isAllowed = await assertBlockOwner(blockId);
if (!isAllowed) return; if (!isAllowed) return;
await db
.update(blocksTable) const block = await getBlock(blockId);
.set({ tag }) if (!block) return;
.where(eq(blocksTable.id, blockId));
await db.transaction(async (tx) => {
await tx
.update(blocksTable)
.set({ tag })
.where(eq(blocksTable.id, blockId));
await tx
.update(notesTable)
.set({ lastEdited: new Date() })
.where(eq(notesTable.id, block.noteId));
});
} }

View File

@ -13,9 +13,7 @@ export async function assertNoteOwner(noteId: string): Promise<boolean> {
const note = await db.query.notesTable.findFirst({ const note = await db.query.notesTable.findFirst({
where: eq(notesTable.id, noteId), where: eq(notesTable.id, noteId),
}); });
if (!note) { if (!note) return false;
return false;
}
return note.authorId === user.id; return note.authorId === user.id;
} }
@ -61,9 +59,14 @@ export async function deleteNote(formData: FormData) {
export async function setTitle(noteId: string, title: string) { export async function setTitle(noteId: string, title: string) {
if (title === "") return; if (title === "") return;
const isAllowed = await assertNoteOwner(noteId);
if (!isAllowed) return;
await db await db
.update(notesTable) .update(notesTable)
.set({ title }) .set({ title, lastEdited: new Date() })
.where(eq(notesTable.id, noteId)); .where(eq(notesTable.id, noteId));
revalidatePath("/notes/[id]", "page"); revalidatePath("/notes/[id]", "page");
} }