(bookmark: InsertBookmark)
| 1662 | } |
| 1663 | |
| 1664 | async createBookmark(bookmark: InsertBookmark): Promise<Bookmark> { |
| 1665 | // Cast needed: drizzle-zod's InsertBookmark resolves to {} due to .omit() type issue |
| 1666 | const bk = bookmark as { userId?: string; entityType: string; entityId?: number | null; searchQuery?: string | null; label?: string | null }; |
| 1667 | const [created] = await db.insert(bookmarks).values(bookmark) |
| 1668 | .onConflictDoNothing() |
| 1669 | .returning(); |
| 1670 | if (!created) { |
| 1671 | // Duplicate bookmark — return the existing one |
| 1672 | const existing = await db.select().from(bookmarks).where( |
| 1673 | bk.searchQuery |
| 1674 | ? and( |
| 1675 | eq(bookmarks.userId, bk.userId ?? "anonymous"), |
| 1676 | eq(bookmarks.entityType, bk.entityType), |
| 1677 | eq(bookmarks.searchQuery, bk.searchQuery), |
| 1678 | ) |
| 1679 | : and( |
| 1680 | eq(bookmarks.userId, bk.userId ?? "anonymous"), |
| 1681 | eq(bookmarks.entityType, bk.entityType), |
| 1682 | eq(bookmarks.entityId, bk.entityId!), |
| 1683 | ) |
| 1684 | ); |
| 1685 | return existing[0]; |
| 1686 | } |
| 1687 | return created; |
| 1688 | } |
| 1689 | |
| 1690 | async deleteBookmark(id: number): Promise<boolean> { |
| 1691 | const result = await db.delete(bookmarks).where(eq(bookmarks.id, id)).returning(); |
nothing calls this directly
no outgoing calls
no test coverage detected