# CONVENTIONS — document-scanner _Last updated: 2026-05-21_ ## Summary The codebase follows standard Python and Vue 3 conventions without heavy tooling enforcement. Backend uses async/await throughout with type hints on public interfaces. Frontend uses Vue Options API with Pinia stores as the data layer. No linter or formatter configuration is committed. --- ## Python Conventions (Backend) ### Naming - Files: `snake_case.py` - Classes: `PascalCase` (e.g., `AnthropicProvider`, `ClassificationResult`) - Functions/variables: `snake_case` - Constants: `UPPER_SNAKE_CASE` (e.g., `MAX_STORED_CHARS`, `DATA_DIR`) - Private helpers: leading underscore (e.g., `_extract_pdf`, `_parse_classification`) ### Async - All API endpoint functions are `async def` - All `AIProvider` methods are `async def` - `pytest-asyncio` with `asyncio_mode=auto` (set in `pytest.ini`) ### Type Hints - Used on public function signatures in `ai/` layer and `services/` - Dataclass used for `ClassificationResult` (`@dataclass` with `field(default_factory=...)`) - Not used consistently in `api/` routers (rely on FastAPI/Pydantic implicit validation) ### Error Handling - `extractor.py` wraps all extraction in `try/except Exception` and returns error strings (never raises) - AI providers raise on hard failures; caller (`classifier.py`) is responsible for propagating - No global exception handler registered in `main.py` ### Imports - Standard library first, then third-party, then local — not enforced by isort - Heavy library imports (`fitz`, `pytesseract`, `docx`) are deferred inside functions to avoid import-time cost when unused ### Module Docstrings - Present on `extractor.py` and `test_classifier.py`; absent elsewhere --- ## JavaScript / Vue Conventions (Frontend) ### Naming - Vue files: `PascalCase.vue` (e.g., `DocumentCard.vue`, `AppSidebar.vue`) - Pinia stores: `camelCase` filename matching store ID (e.g., `documents.js` → `useDocumentsStore`) - Views: `View.vue` suffix - Components grouped by domain in subdirectories: `documents/`, `topics/`, `upload/`, `layout/` ### Vue Style - Options API used throughout (not Composition API) - Props defined with type and default; no `defineProps` (Options API syntax) - `v-model`, `v-for`, `v-if` used directly in templates ### Pinia Pattern - Each store encapsulates `state`, `getters`, and `actions` - Actions call `src/api/client.js` — components never import `client.js` directly - Stores are the single source of truth; views read from store state ### API Client - `src/api/client.js` is the sole HTTP adapter - All paths are prefixed `/api/` (proxied to backend in dev via Vite config) ### Styling - Tailwind CSS utility classes used directly in templates - No scoped `