4.7 KiB
4.7 KiB
AGENTS.md - Coding Guidelines for AI Agents
Build / Test / Lint Commands
Python Backend
# 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
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 annotationsfor forward references when needed
Type Hints:
- All functions must have type hints (enforced by mypy)
- Use
| Noneinstead ofOptional[...](Python 3.10+) - Use
list[str]instead ofList[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_underscorefor 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
detailsdict
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:
camelCasewithuseprefix (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
typeoverinterfacefor 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.tsor{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
- Add route in
backend/web/api/v1/ - Define Pydantic schema in
backend/web/schemas/ - Implement service logic in
backend/web/services/ - Add tests in
tests/web/
Frontend: Adding a New Component
- Create component in
frontend/src/components/ - Export from
frontend/src/components/index.tsif shared - Add types to
frontend/src/api/types.tsif API-related - Add tests co-located with component
Error Handling
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
from shared.data.repositories import DocumentRepository
repo = DocumentRepository()
doc = repo.get_by_id(doc_id)