# HXBooks Project Guidelines ## Project Overview HXBooks is a personal book library management application with both web (Flask + HTMX) and CLI interfaces. It provides advanced book searching, reading tracking, and library management without heavy JavaScript frameworks. **Core Technologies:** - **Backend**: Flask 3.1+ with SQLAlchemy 2.0 (modern `Mapped[]` annotations) - **Frontend**: HTMX + Alpine.js + Bootstrap (minimal JavaScript approach) - **Validation**: Pydantic 2.x with modern `Annotated` types for composable validation - **Templates**: Jinja2 with fragments for partial page updates - **Database**: SQLite with proper normalized schema (no JSON columns for core entities) - **Package Manager**: UV with Python 3.14 - **CLI**: Click-based comprehensive command interface ## Architecture **Service Layer Pattern:** - Flask app factory in [src/hxbooks/app.py](src/hxbooks/app.py) - Service layer: [src/hxbooks/library.py](src/hxbooks/library.py) - business logic shared between web and CLI - Web routes: [src/hxbooks/main.py](src/hxbooks/main.py) - Flask blueprint handling HTTP requests - CLI commands: [src/hxbooks/cli.py](src/hxbooks/cli.py) - Click command groups **Key Components:** - [src/hxbooks/models.py](src/hxbooks/models.py): SQLAlchemy models with proper normalization and relationships - [src/hxbooks/library.py](src/hxbooks/library.py): Core business logic (create_book, search_books_advanced, etc.) - [src/hxbooks/search.py](src/hxbooks/search.py): Advanced query parser with pyparsing - [src/hxbooks/gbooks.py](src/hxbooks/gbooks.py): Google Books API integration - [src/hxbooks/templates/](src/hxbooks/templates/): Jinja2 templates with HTMX fragments ## Build and Development **Setup & Run:** ```bash uv sync # Install dependencies python -m hxbooks # Dev server with livereload (port 5000) hxbooks --help # CLI interface (after uv sync) ``` **CLI Commands:** ```bash hxbooks book add "Title" --authors "Author1,Author2" --genres "Fiction" hxbooks book search "author:tolkien genre:fantasy rating>=4" hxbooks reading start hxbooks reading finish --rating 5 --comments "Excellent!" hxbooks wishlist add ``` **Development Server:** - CLI command `hxbooks serve`: Livereload server watching templates - VS Code debugging: Flask app factory in [src/hxbooks/app.py](src/hxbooks/app.py) - Config: Instance folder pattern (`instance/config.py` for local overrides) **Testing:** ```bash pytest # Run all tests with verbose output pytest tests/test_cli.py # Test CLI commands pytest tests/test_search.py # Test query parser ``` **Production Deployment:** - Dockerfile uses Gunicorn on port 8080 - **Note**: Current Dockerfile expects `requirements.txt` but project uses `pyproject.toml` ## Code Style **Python Conventions:** - **Types**: Modern annotations (`str | Response`, `Mapped[str]`, `Optional[Type]`) - **Naming**: snake_case functions/vars, PascalCase classes, UPPERCASE constants - **SQLAlchemy**: Use `mapped_column()` and `relationship()` with `back_populates` - **Validation**: Pydantic schemas with `{Entity}FormData` pattern **Pydantic 2.x Patterns:** - **Composable types**: `Annotated[str, StringConstraints(strip_whitespace=True)]` - **Custom validators**: `BeforeValidator()` for preprocessing (strip, empty-to-None) - **Reusable aliases**: `StrOrNone`, `TextareaList`, `ISBNOrNone` in [src/hxbooks/main.py](src/hxbooks/main.py) - **Modern syntax**: `str | None` not `Optional[str]`, `model_validate()` not `parse_obj()` **Flask Patterns:** - Blueprints with `@bp.route()` decorators - `@login_required` decorator for protected routes - Response types: `str | Response` (template string or redirect) - Error handling: Dict mapping for template display `{field: error_msg}` **Testing Conventions:** - **pytest**: Class-based organization (`TestBookAddCommand`, `TestFieldFilters`) - **Parametrized tests**: `@pytest.mark.parametrize` for multiple scenario testing - **Type hints**: Full annotations on test methods and fixtures - **Assertions**: Include context with f-strings for debugging **Frontend (HTMX + Alpine.js):** - Templates: `.j2` extension, fragments for partial updates - HTMX: Dynamic updates with `hx-get`, `hx-post`, `hx-target` - Alpine.js: Minimal state management (`x-data`, `x-show`, `@click`) - Styling: Bootstrap CSS classes ## Key Files **Entry Points:** - [src/hxbooks/__main__.py](src/hxbooks/__main__.py): Development server - [main.py](main.py): Unused placeholder - [.vscode/launch.json](.vscode/launch.json): Debug configuration **Core Application:** - [src/hxbooks/app.py](src/hxbooks/app.py): Flask app factory - [src/hxbooks/db.py](src/hxbooks/db.py): SQLAlchemy setup with auto-table creation - [src/hxbooks/models.py](src/hxbooks/models.py): Database models **Feature Modules:** - [src/hxbooks/main.py](src/hxbooks/main.py): Web routes and form handling - [src/hxbooks/library.py](src/hxbooks/library.py): Business logic service layer - [src/hxbooks/cli.py](src/hxbooks/cli.py): Click CLI commands - [src/hxbooks/search.py](src/hxbooks/search.py): Query parser and search logic - [src/hxbooks/gbooks.py](src/hxbooks/gbooks.py): Google Books API integration **Testing Infrastructure:** - [tests/conftest.py](tests/conftest.py): Pytest fixtures and test configuration - [tests/test_cli.py](tests/test_cli.py): CLI command tests - [tests/test_search.py](tests/test_search.py): Query parser and search tests ## Conventions **Database Patterns:** - Normalized schema: `Author` and `Genre` as separate entities with many-to-many relationships - Cascade deletes for dependent entities - Foreign key constraints explicitly defined **Search Implementation:** - Advanced query parser using pyparsing with field filters (`author:tolkien`, `rating>=4`) - Complex query builder returning `Select` statements - Support for negation (`-genre:romance`) and special operators (`is:reading`) **HTMX Integration:** - Partial page updates using Jinja2-Fragments - Search results rendered as blocks without full page reload - Form validation errors returned as template fragments **Development Notes:** - Testing framework: pytest with parametrized tests for comprehensive coverage - Linting/formatting: ruff configured with strict rules - Instance folder for environment-specific config (gitignored) - Production requires either `requirements.txt` generation or Dockerfile updates for UV