Architecture Overview
This section contains architecture diagrams and documentation for etchblok-test-api.
Available Diagrams
Bookmark Management System Context
The Bookmark Management System Context diagram illustrates the interactions between the Bookmark API Internal Component Structure and its surrounding environment. At the center is the Bookmark API, a Flask-based web service that provides RESTful endpoints for managing bookmarks, tags, and collections.
End Users interact with the system through these API endpoints to perform CRUD operations and search. A Monitoring System (such as a load balancer or health check service) interacts with internal diagnostic endpoints to ensure the service is healthy and ready to serve traffic.
For data persistence, the API communicates with a Database System (abstracted via a repository pattern), which stores the core domain models. To optimize performance, the system utilizes a Cache Provider (implemented as an LRU cache) to store frequently accessed bookmark data. Full-text search capabilities are provided by an External Search Service (implemented as an inverted index), which allows users to find bookmarks based on their title and description content.
While the current implementation uses in-memory stubs for the database, cache, and search components, the architecture is designed to integrate with external systems like PostgreSQL, Redis, and Elasticsearch in a production environment.
Key Architectural Findings:
- The system is a Flask-based REST API organized into routes, services, and repositories.
- Data persistence is handled by a BookmarkRepository, which currently uses an in-memory store but is designed for database integration (referencing PostgreSQL defaults).
- An internal LRUCache is used by the BookmarkService to improve retrieval performance for bookmarks.
- Full-text search is implemented via a SearchIndex service that maintains an inverted index of bookmark titles and descriptions.
- Internal health and readiness probes are provided for integration with monitoring systems and load balancers.
- The system manages three primary domain entities: Bookmarks, Tags, and Collections.
Bookmark API Internal Component Structure
The Bookmark API follows a layered architecture designed for maintainability and separation of concerns.
At the top, the API Layer consists of Flask Blueprints that handle HTTP requests and delegate business logic to the service layer.
The Service Layer is centered around the [BookmarkService](/api_ref/app/services/bookmark/service/bookmarkservice), which acts as a facade and orchestrator. It is implemented as a singleton to ensure consistent state across the application. It coordinates between the Persistence Layer, the Search Index, and an internal LRU Cache.
The Persistence Layer uses the [BookmarkRepository](/api_ref/app/db/repository/bookmarkrepository) to abstract data access. While currently implemented in-memory, the repository pattern allows for future migration to a persistent database without affecting the service layer.
The Domain Models ([Bookmark](/api_ref/app/models/bookmark/bookmark), Tag, Collection) are shared across all layers and encapsulate both state and entity-specific logic.
Finally, the Configuration module provides environment-specific settings that drive the application's behavior, such as page sizes and secret keys.
Key Architectural Findings:
- The application uses a layered architecture: API -> Service -> Repository -> Models.
- BookmarkService is a singleton facade that orchestrates business logic, caching, and search indexing.
- SearchIndex provides an inverted index for full-text search, rebuilt from the repository and updated incrementally.
- LRUCache is an internal utility used by the service layer to optimize frequent bookmark lookups.
- BookmarkRepository implements the repository pattern, currently providing in-memory storage for all domain entities.
- Domain models (Bookmark, Tag, Collection) are rich objects that handle their own state transitions (e.g., archiving, trashing).
Bookmark Domain Entity Relationship Diagram
The data model for the Bookmark Domain is centered around three core entities: Bookmark, Collection, and Tag.
- Bookmark: The primary entity representing a saved URL. It maintains its own state (Active, Archived, Trashed) and metadata. It has a many-to-many relationship with Tags, stored internally as a list of Tag IDs.
- Tag: A label used to categorize bookmarks. It includes a color attribute and tracks its own usage count across bookmarks.
- Collection: A grouping mechanism for bookmarks. Collections can be "manual" (explicitly managed) or "smart" (populated via a filter rule). It maintains an ordered list of Bookmark IDs.
The relationships are many-to-many in nature, although the implementation uses ID lists within the entities rather than separate join tables, reflecting the in-memory repository pattern used in the codebase.
Note: While the system classification and some docstrings mention "users", no User entity or user-specific fields (like user_id) were found in the current implementation. The API appears to be designed for a single-user context or handles multi-tenancy outside the domain model.
Key Architectural Findings:
- The data model is implemented using Python dataclasses and Enums, managed by an in-memory repository.
- Bookmarks have a many-to-many relationship with Tags, implemented via a list of Tag IDs in the Bookmark entity.
- Collections have a many-to-many relationship with Bookmarks, implemented via a list of Bookmark IDs in the Collection entity.
- Enums are used for BookmarkStatus (ACTIVE, ARCHIVED, TRASHED), CollectionType (MANUAL, SMART), and TagColor (RED, BLUE, GREEN, etc.).
- No User entity or user-related foreign keys were found in the codebase, despite mentions in documentation.
Bookmark Entity Lifecycle
The state diagram illustrates the lifecycle of a Bookmark entity within the Etchblok API.
A bookmark begins its lifecycle in the Active state upon creation via a POST request. From there, it can be moved to the Archived state for long-term storage or to the Trashed state via a soft-delete operation (triggered by a DELETE request).
The system allows for full mobility between these states:
- Restoration: Any bookmark in the Archived or Trashed state can be returned to the Active state using the
/restoreendpoint. - Archiving: Even a Trashed bookmark can be moved directly to the Archived state.
- Trashing: An Archived bookmark can be moved to the Trashed state by deleting it.
Every transition between these states triggers an internal _touch() method which updates the updated_at timestamp of the entity. Notably, the API implements a soft-delete pattern; while the repository layer supports hard deletion, it is not exposed through the service or routing layers, meaning bookmarks remain in the Trashed state until manually restored or archived.
Key Architectural Findings:
- Bookmarks are initialized to the 'active' status by default upon creation.
- The 'DELETE' endpoint performs a soft-delete, transitioning the bookmark to the 'trashed' status rather than removing it from the database.
- The 'archive' and 'restore' operations provide explicit transitions between 'active', 'archived', and 'trashed' states.
- All state transitions are accompanied by a timestamp update via the private '_touch()' helper method.
- The state machine is fully connected, allowing transitions between any two statuses (Active, Archived, Trashed) via the appropriate API endpoints.