Skip to main content

Architecture Overview

This section contains architecture diagrams and documentation for etchblok test api.

Available Diagrams

Bookmark Management System Context

The Bookmark Management System is a Bookmark Management System Context built with Flask that provides a REST API for managing bookmarks, tags, and collections. It follows a layered architecture where the BookmarkService orchestrates business logic, validation, and interactions with external systems. The system persists data in a Data Persistence (PostgreSQL-like), utilizes an Overview of the Search System for full-text search across bookmark metadata, and employs a Cache Service (LRU) to optimize bookmark retrieval performance. Users and client applications interact with the system via standard HTTP/REST endpoints.

Key Architectural Findings:

  • Layered Architecture: The codebase is organized into routes, services, repositories, and models, ensuring a clean separation of concerns.
  • Persistent Storage: Uses a repository pattern to abstract data access to a PostgreSQL-compatible database (pagemark).
  • Full-Text Search: Implements an inverted index for searching bookmark titles and descriptions, designed to be replaced by external services like Elasticsearch or Typesense.
  • Performance Optimization: Features an internal LRU cache to reduce database load for frequently accessed bookmarks.
  • RESTful API: Provides a comprehensive set of endpoints for CRUD operations on bookmarks, tags, and collections, with health and readiness probes for monitoring.

Layered Architecture Components

The diagram illustrates the layered architecture of the Pagemark API, showing how requests flow from the external API layer down to the data persistence layer.

  • API Layer: app.routes.bookmarks contains Flask Blueprints (bookmarks, tags, collections) that handle incoming HTTP requests. These routes do not contain business logic; instead, they delegate all operations to the service layer.
  • Service Layer: The app.services.bookmark_service (implemented as a BookmarkService singleton) acts as the central orchestrator. It manages validation, cache invalidation, and coordinates between the repository and the search index.
  • Search & Cache: The app.services.search_service (SearchIndex) provides full-text search capabilities by maintaining an inverted index of bookmark content. The app.services._cache (LRUCache) provides an internal, fixed-size cache to speed up bookmark retrieval.
  • Data Layer: The app.db.repository (BookmarkRepository) provides an in-memory abstraction for data storage, isolating the rest of the application from the underlying storage mechanism.
  • Domain Layer: app.models.bookmark and other models define the core data structures used across all layers of the application.

The flow typically starts with a user request to a route, which calls a method on the BookmarkService. The service then interacts with the cache, repository, and search index as needed to fulfill the request, using domain models to pass data between components.

Key Architectural Findings:

  • BookmarkService is a singleton facade that orchestrates all business logic and cross-component operations.
  • The architecture follows a strict layered pattern where routes delegate to services, and services interact with repositories.
  • SearchIndex maintains an inverted index and depends on the BookmarkRepository to fetch full bookmark objects during search.
  • LRUCache is an internal component of the service layer used specifically for bookmark retrieval performance.
  • The BookmarkRepository implements an in-memory data access pattern, providing a clean boundary for future database integration.

Bookmark Lifecycle States

The state diagram illustrates the lifecycle of a Bookmark entity within the Etchblok API.

Key States:

  • Active: The initial state of a bookmark upon creation. It is visible in the main list and searchable.
  • Archived: A state for bookmarks that are no longer active but preserved for reference. They can be filtered out of the main view.
  • Trashed: A soft-deleted state. Bookmarks in this state are typically hidden from the user but can be restored or permanently archived.

Transitions and Triggers:

  • Creation: A bookmark starts in the Active state when created via the create_bookmark service method (triggered by POST /api/bookmarks/).
  • Archival: Moving a bookmark to the Archived state is triggered by the archive_bookmark method (POST /api/bookmarks/<id>/archive). This can be done from either the Active or Trashed states.
  • Soft Deletion: Moving a bookmark to the Trashed state is triggered by the delete_bookmark method (DELETE /api/bookmarks/<id>). This can be done from either the Active or Archived states.
  • Restoration: A bookmark in the Archived or Trashed state can be returned to the Active state using the restore_bookmark method (POST /api/bookmarks/<id>/restore).

The diagram reflects the actual implementation in app/models/bookmark.py and app/services/bookmark_service.py, where status changes are handled by explicit methods that update the BookmarkStatus enum. Notably, while the repository layer supports hard deletion, the service layer currently only implements soft deletion via the Trashed state.

Key Architectural Findings:

  • The Bookmark entity uses a BookmarkStatus enum with three values: ACTIVE, ARCHIVED, and TRASHED.
  • New bookmarks are initialized with the ACTIVE status by default in the Bookmark dataclass.
  • The delete_bookmark service method performs a soft delete by transitioning the bookmark to the TRASHED state.
  • The restore_bookmark service method transitions a bookmark from either ARCHIVED or TRASHED back to the ACTIVE state.
  • Transitions between ARCHIVED and TRASHED are possible through their respective service methods without intermediate steps.
  • The repository layer contains a hard-delete method (delete_bookmark) that is currently unused by the service layer.