# AGENTS.md - Coding Guidelines for AI Agents ## Build / Test / Lint Commands ### Python Backend ```bash # Install packages (editable mode) pip install -e packages/shared pip install -e packages/training pip install -e packages/backend # Run all tests DB_PASSWORD=xxx pytest tests/ -q # Run single test file DB_PASSWORD=xxx pytest tests/path/to/test_file.py -v # Run with coverage DB_PASSWORD=xxx pytest tests/ --cov=packages --cov-report=term-missing # Format code black packages/ tests/ ruff check packages/ tests/ # Type checking mypy packages/ ``` ### Frontend ```bash cd frontend # Install dependencies npm install # Development server npm run dev # Build npm run build # Run tests npm run test # Run single test npx vitest run src/path/to/file.test.ts # Watch mode npm run test:watch # Coverage npm run test:coverage ``` ## Code Style Guidelines ### Python **Imports:** - Use absolute imports within packages: `from shared.pdf.extractor import PDFDocument` - Group imports: stdlib → third-party → local (separated by blank lines) - Use `from __future__ import annotations` for forward references when needed **Type Hints:** - All functions must have type hints (enforced by mypy) - Use `| None` instead of `Optional[...]` (Python 3.10+) - Use `list[str]` instead of `List[str]` (Python 3.10+) **Naming:** - Classes: `PascalCase` (e.g., `PDFDocument`, `InferencePipeline`) - Functions/variables: `snake_case` (e.g., `extract_text`, `get_db_connection`) - Constants: `UPPER_SNAKE_CASE` (e.g., `DEFAULT_DPI`, `DATABASE`) - Private: `_leading_underscore` for internal use **Error Handling:** - Use custom exceptions from `shared.exceptions` - Base exception: `InvoiceExtractionError` - Specific exceptions: `PDFProcessingError`, `OCRError`, `DatabaseError`, etc. - Always include context in exceptions via `details` dict **Docstrings:** - Use Google-style docstrings - All public functions/classes must have docstrings - Include Args/Returns sections for complex functions **Code Organization:** - Maximum line length: 100 characters (black config) - Target Python: 3.10+ - Keep files under 800 lines, ideally 200-400 lines ### TypeScript / React Frontend **Imports:** - Use path alias `@/` for project imports: `import { Button } from '@/components/Button'` - Group: React → third-party → local (@/) → relative **Naming:** - Components: `PascalCase` (e.g., `Dashboard.tsx`, `InferenceDemo.tsx`) - Hooks: `camelCase` with `use` prefix (e.g., `useDocuments.ts`) - Types/Interfaces: `PascalCase` (e.g., `DocumentListResponse`) - API endpoints: `camelCase` (e.g., `documentsApi`) **TypeScript:** - Strict mode enabled - Use explicit return types on exported functions - Prefer `type` over `interface` for simple shapes - Use enums for fixed sets of values **React Patterns:** - Functional components with hooks - Use React Query for server state - Use Zustand for client state (if needed) - Props interfaces named `{ComponentName}Props` **Styling:** - Use Tailwind CSS exclusively - Custom colors: `warm-*` theme (e.g., `bg-warm-text-secondary`) - Component variants defined as objects (see Button.tsx pattern) **Testing:** - Use Vitest + React Testing Library - Test files: `{name}.test.ts` or `{name}.test.tsx` - Co-locate tests with source files when possible ## Project Structure ``` packages/ shared/ # Shared utilities (PDF, OCR, storage, config) training/ # Training service (GPU, CLI commands) backend/ # Web API + inference (FastAPI) frontend/ # React + TypeScript + Vite tests/ # Test suite migrations/ # Database SQL migrations ``` ## Key Configuration - **DPI:** 150 (must match between training and inference) - **Database:** PostgreSQL (configured via env vars) - **Storage:** Abstracted (Local/Azure/S3 via storage.yaml) - **Python:** 3.10+ (3.11 recommended, 3.10 for RTX 50 series) ## Environment Variables Required: `DB_PASSWORD` Optional: `DB_HOST`, `DB_PORT`, `DB_NAME`, `DB_USER`, `STORAGE_BASE_PATH` ## Common Patterns ### Python: Adding a New API Endpoint 1. Add route in `backend/web/api/v1/` 2. Define Pydantic schema in `backend/web/schemas/` 3. Implement service logic in `backend/web/services/` 4. Add tests in `tests/web/` ### Frontend: Adding a New Component 1. Create component in `frontend/src/components/` 2. Export from `frontend/src/components/index.ts` if shared 3. Add types to `frontend/src/api/types.ts` if API-related 4. Add tests co-located with component ### Error Handling ```python from shared.exceptions import DatabaseError try: result = db.query(...) except Exception as e: raise DatabaseError(f"Failed to fetch document: {e}", details={"doc_id": doc_id}) ``` ### Database Access ```python from shared.data.repositories import DocumentRepository repo = DocumentRepository() doc = repo.get_by_id(doc_id) ```