Skip to main content

Data Models

The application's architecture is built upon a set of fundamental data models designed to efficiently store and manage user-curated web content. These models—Bookmark, Collection, and Tag—represent the core entities, each serving a distinct purpose in organizing and retrieving information. Their design emphasizes clarity, flexibility, and the ability to form rich interconnections, allowing users to categorize and discover content in various ways.

Core Entities

Bookmark

The Bookmark model is the central entity, representing a single saved web link. It encapsulates all essential information about a bookmarked item.

class Bookmark:
url: str
title: str
description: str = ""
tags: List[str] = field(default_factory=list)
status: BookmarkStatus = BookmarkStatus.ACTIVE
id: str = field(default_factory=lambda: uuid.uuid4().hex[:12])
created_at: datetime = field(default_factory=datetime.utcnow)
updated_at: datetime = field(default_factory=datetime.utcnow)
metadata: Dict[str, Any] = field(default_factory=dict)

Key attributes include:

  • url: The actual web address of the bookmark.
  • title: A human-readable title for the bookmark.
  • description: An optional longer text providing more context.
  • tags: A list of IDs referencing associated Tag objects, enabling multi-tagging.
  • status: Indicates the current state of the bookmark (e.g., active, archived, trashed), managed by the BookmarkStatus Enum.
  • id, created_at, updated_at: Standard fields for unique identification and temporal tracking.
  • metadata: A flexible dictionary for storing arbitrary key-value pairs, allowing for future extensibility without altering the core schema.

The Bookmark model also provides methods like archive(), trash(), and restore() to manage its lifecycle, and add_tag() and remove_tag() to handle its associations with tags.

Collection

A Collection serves as a named grouping mechanism for bookmarks. Collections can be either manual, where users explicitly add bookmarks, or smart, where bookmarks are automatically included based on a defined filter rule.

class Collection:
name: str
collection_type: CollectionType = CollectionType.MANUAL
bookmark_ids: List[str] = field(default_factory=list)
filter_rule: str = ""
is_pinned: bool = False
id: str = field(default_factory=lambda: uuid.uuid4().hex[:10])
created_at: datetime = field(default_factory=datetime.utcnow)

Important attributes are:

  • name: A descriptive name for the collection.
  • collection_type: Defines whether the collection is MANUAL or SMART, controlled by the CollectionType Enum.
  • bookmark_ids: An ordered list of bookmark IDs explicitly included in manual collections.
  • filter_rule: A query string used by smart collections to automatically select bookmarks.
  • is_pinned: A boolean indicating if the collection should appear at the top of the sidebar.
  • id, created_at: Standard identification and timestamp fields.

Collections provide methods such as add_bookmark(), remove_bookmark(), and reorder() for managing manual collections, and is_smart() to determine its type. They also include pin() and unpin() for UI organization.

Tag

The Tag model provides a lightweight, keyword-based categorization system for bookmarks, now with enhanced visual and descriptive capabilities.

class Tag:
name: str
color: TagColor = TagColor.GRAY
description: str = ""
id: str = field(default_factory=lambda: uuid.uuid4().hex[:8])
usage_count: int = 0

Key attributes include:

  • name: The keyword or term itself, which must be unique per user.
  • color: A visual color for UI rendering, managed by the TagColor Enum (e.g., TagColor.GRAY).
  • description: An optional longer text describing the tag's purpose.
  • usage_count: An integer tracking the number of bookmarks currently associated with this tag.
  • id: A unique identifier.

Tags are intended for quick, informal categorization. They offer methods like rename(), increment_usage(), and decrement_usage() to manage their properties and track their application across bookmarks.

Associated Enums

To ensure data integrity and provide clear, constrained choices for certain attributes, the application utilizes several Enums:

BookmarkStatus

The BookmarkStatus Enum defines the possible states a Bookmark can be in.

class BookmarkStatus(Enum):
ACTIVE = "active"
ARCHIVED = "archived"
TRASHED = "trashed"
  • ACTIVE: The bookmark is currently visible and in regular use.
  • ARCHIVED: The bookmark is no longer actively used but is retained for historical purposes.
  • TRASHED: The bookmark has been moved to a temporary deletion state.

This Enum provides a clear, explicit way to manage the lifecycle and visibility of bookmarks.

CollectionType

The CollectionType Enum dictates how a Collection manages its bookmarks.

class CollectionType(Enum):
MANUAL = "manual"
SMART = "smart"
  • MANUAL: Bookmarks are explicitly added and removed by the user.
  • SMART: Bookmarks are automatically included based on a filter_rule.

This allows for flexible and dynamic organization of bookmarks within collections.

TagColor

The TagColor Enum provides a predefined set of colors for visual representation of tags in the user interface. While the full definition is not available, an example value is TagColor.GRAY. This allows for consistent and aesthetically pleasing categorization.

Relationships and Operations

The data models are designed to be interconnected, forming a flexible graph-like structure. A Bookmark can be associated with multiple Tag objects through its tags attribute, which stores a list of tag IDs. Collection objects explicitly manage their associated Bookmarks via the bookmark_ids list for manual collections, or implicitly through a filter_rule for smart collections. This many-to-many relationship between bookmarks and tags/collections is a fundamental design choice, allowing for highly flexible content organization.

Common operations across these models include:

  • Creation: Instantiating new Bookmark, Collection, or Tag objects.
  • Retrieval: Fetching existing objects by their unique id or by querying based on other attributes (e.g., all bookmarks with a specific tag, or all bookmarks within a collection).
  • Update: Modifying attributes of an existing object (e.g., changing a bookmark's title, a collection's description, or a tag's color).
  • Deletion: Removing objects from the system.
  • Association Management: For Bookmarks, methods like add_tag() and remove_tag() facilitate dynamic linking and unlinking with Tag objects. For Collections, methods like add_bookmark(), remove_bookmark(), and reorder() manage the explicit inclusion of bookmarks.

The design prioritizes a clear separation of concerns, with each model focusing on its specific domain, while providing the necessary hooks for inter-model relationships. This modularity simplifies maintenance and allows for independent evolution of each data structure.