import Foundation struct Bookmark: Codable, Identifiable, Sendable, Hashable { let id: Int var url: String var title: String var description: String var tagNames: [String] var dateAdded: Date var dateModified: Date var isArchived: Bool var unread: Bool var shared: Bool var websiteTitle: String? var websiteDescription: String? var faviconUrl: String? var previewImageUrl: String? // AI-enriched fields stored locally var aiSummary: String? var aiTags: [String]? enum CodingKeys: String, CodingKey { case id, url, title, description, unread, shared case tagNames = "tag_names" case dateAdded = "date_added" case dateModified = "date_modified" case isArchived = "is_archived" case websiteTitle = "website_title" case websiteDescription = "website_description" case faviconUrl = "favicon_url" case previewImageUrl = "preview_image_url" } var displayTitle: String { if !title.isEmpty { return title } if let t = websiteTitle, !t.isEmpty { return t } return url } var domain: String { URL(string: url)?.host ?? url } } struct BookmarkResponse: Codable, Sendable { let count: Int let next: String? let previous: String? let results: [Bookmark] } struct BookmarkCreate: Codable, Sendable { let url: String let title: String let tagNames: [String] let isArchived: Bool let unread: Bool let shared: Bool enum CodingKeys: String, CodingKey { case url, title, unread, shared case tagNames = "tag_names" case isArchived = "is_archived" } } struct BookmarkUpdate: Codable, Sendable { var url: String var title: String var description: String var tagNames: [String] var unread: Bool var shared: Bool enum CodingKeys: String, CodingKey { case url, title, description, unread, shared case tagNames = "tag_names" } } struct SmartCollection: Identifiable, Sendable { let id = UUID() let name: String let description: String let bookmarkIds: [Int] }