# Contributing to Doof Backend Thank you for your interest in contributing! This document provides guidelines and workflows for contributing to the project. ## Getting Started ### First-time setup 1. Clone the repository 2. Run the setup script: ```bash make install ``` This will: - Create a virtual environment in `.venv` - Install all dependencies - Install pre-commit hooks 3. Activate the virtual environment: ```bash source .venv/bin/activate # On Windows: .venv\Scripts\activate ``` 4. Run tests to verify everything works: ```bash make test ``` ## Development Workflow ### Running the application Start the development server: ```bash make dev ``` The server will run at `http://localhost:8000` with auto-reload enabled. ### Code Quality Before committing, ensure your code passes all checks: ```bash make all-checks ``` This runs: - `ruff check` - Linting - `ruff format --check` - Format verification - `mypy` - Type checking - `pytest` - Tests - OpenAPI export Individual checks can be run separately: ```bash make format # Auto-format code make lint # Lint code make typecheck # Type check make test # Run tests ``` ### Pre-commit Hooks Pre-commit hooks are automatically installed with `make install`. They run on every commit to: - Format code with ruff - Lint code with ruff - Type check with mypy - Fix trailing whitespace - Ensure files end with a newline If pre-commit fails, fix the issues and commit again. To run pre-commit manually: ```bash pre-commit run --all-files ``` ## Code Style - **Formatting**: We use [ruff](https://docs.astral.sh/ruff/) for both linting and formatting - **Line length**: 100 characters (configured in `pyproject.toml`) - **Type hints**: Use type hints where possible; mypy is configured for basic type checking - **Imports**: Organized automatically by ruff (isort-style) ## Testing - All tests live in the `tests/` directory - We use `pytest` as the test runner - Tests use in-memory SQLite for fast, hermetic execution - HTTP requests are mocked using fixtures in `tests/httpx_mocks.py` ### Writing tests ```python import unittest from db import connect, create class TestMyFeature(unittest.IsolatedAsyncioTestCase): async def asyncSetUp(self): self.conn = await connect(":memory:") await create(self.conn) # Add test data if needed return await super().asyncSetUp() async def asyncTearDown(self): await self.conn.close() return await super().asyncTearDown() async def test_something(self): # Your test here pass ``` Run tests: ```bash make test ``` ## Project Structure ``` . ├── api/ # FastAPI routers and endpoints ├── ingredients/ # Ingredient models and repository ├── meals/ # Meal models, repository, and service logic ├── persons/ # Person models and repository ├── products/ # Product models, repository, and scrapers ├── recipes/ # Recipe models, repository, and scraping ├── shopping/ # Shopping list models and repository ├── scripts/ # Utility scripts (e.g., OpenAPI export) ├── tests/ # Test suite ├── main.py # FastAPI application entry point ├── db.py # Database connection and schema bootstrap └── settings.py # Configuration and environment variables ``` ## Environment Variables Copy `.env.example` to `.env` and customize: ```bash cp .env.example .env ``` Key variables: - `DOOF_DB` - Database file path (default: `./data/doof.sqlite`) - `DOOF_PROD` - Production mode flag (default: `false`) - `FRONTEND_DEV_URL` - Frontend dev server URL for reverse proxy ## OpenAPI Schema Export the OpenAPI schema: ```bash make openapi ``` This generates `openapi.json` from the FastAPI application. ## Commit Guidelines - Write clear, descriptive commit messages - Keep commits focused and atomic - Reference issue numbers if applicable - Pre-commit hooks will enforce code quality Example commit message: ``` Add meal duplication detection - Implement get_duplicates function in meals service - Add test coverage for duplicate detection - Update API endpoint to return duplicates Fixes #123 ``` ## Need Help? - Check the [README.md](README.md) for basic setup and usage - Review [tooling-spec.md](tooling-spec.md) for tooling details - Open an issue for bugs or feature requests ## License By contributing, you agree that your contributions will be licensed under the same license as the project.