bookmark เรียงตามลำดับหน้า (N5) + ค้นหา bookmark พร้อมเงื่อนไข คำค้น/ช่วงหน้า/ผู้บันทึก/ช่วงวันที่ พร้อม bookmarks.user_name (N6) + UX audit sidebar 2026-09-16: เมนู ⋯ แทนไอคอนชุดติดกัน, มุมมองรอง ตามหน้า หัวกลุ่มหุบได้, focus ring, ปุ่ม sidebar จิ้มง่าย >=32px, Escape ปิด dialog ประวัติ + แผนใหม่ docs/PLAN-BOOKMARK.md + agent ui-ux-designer แทน ui-designer + skill frontend-design

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-09-16 13:24:33 +07:00
parent 79b38fa152
commit a020e96bda
14 changed files with 2029 additions and 362 deletions

View file

@ -168,6 +168,9 @@ export const bookmarks = pgTable(
.references(() => files.id, { onDelete: "cascade" }),
pageIndex: integer("page_index").notNull(),
userId: text("user_id").notNull(),
/** N6: ชื่อผู้บันทึก (mirror annotations — เดิมมีแค่ user_id จนกรองตามผู้บันทึกแล้วไม่มีชื่อแสดง);
* '' = row เดิมก่อน backfill → UI แสดง "ไม่ทราบชื่อ" */
userName: text("user_name").notNull().default(""),
title: text("title").notNull(),
/** N2: bookmark แม่ (NULL = หมุดหัวข้อใหญ่ระดับบนสุด) — ไม่ทำ FK เพราะลบแม่ต้อง re-parent ลูกขึ้น root ก่อนใน tx เดียวกัน */
parentId: uuid("parent_id"),
@ -254,6 +257,8 @@ export type BookmarkDTO = {
fileId: string;
pageIndex: number;
userId: string;
/** N6 — '' = ไม่ทราบชื่อ (row เดิมก่อน backfill) */
userName: string;
title: string;
/** N2: NULL = ระดับบนสุด / มีค่า = sub ของ bookmark นั้น */
parentId: string | null;
@ -309,6 +314,7 @@ export function toBookmarkDTO(row: BookmarkRow): BookmarkDTO {
fileId: row.fileId,
pageIndex: row.pageIndex,
userId: row.userId,
userName: row.userName,
title: row.title,
parentId: row.parentId,
note: row.note,