7a34807fa0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.6 KiB
3.6 KiB
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
AIProvidermethods areasync def pytest-asynciowithasyncio_mode=auto(set inpytest.ini)
Type Hints
- Used on public function signatures in
ai/layer andservices/ - Dataclass used for
ClassificationResult(@dataclasswithfield(default_factory=...)) - Not used consistently in
api/routers (rely on FastAPI/Pydantic implicit validation)
Error Handling
extractor.pywraps all extraction intry/except Exceptionand 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.pyandtest_classifier.py; absent elsewhere
JavaScript / Vue Conventions (Frontend)
Naming
- Vue files:
PascalCase.vue(e.g.,DocumentCard.vue,AppSidebar.vue) - Pinia stores:
camelCasefilename matching store ID (e.g.,documents.js→useDocumentsStore) - Views:
<Name>View.vuesuffix - 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-ifused directly in templates
Pinia Pattern
- Each store encapsulates
state,getters, andactions - Actions call
src/api/client.js— components never importclient.jsdirectly - Stores are the single source of truth; views read from store state
API Client
src/api/client.jsis 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
<style>blocks observed in component list - Global styles in
src/style.css
API Design Conventions (Backend)
- All endpoints prefixed
/api/(set per router) - JSON responses; multipart for file upload
- HTTP verbs follow REST: GET list, GET by ID, POST create, PUT/PATCH update, DELETE remove
- No versioning (
/api/v1/) — flat namespace
Configuration
- Runtime paths controlled entirely by
DATA_DIRenv var (defaults to/app/data) - AI settings persisted in
data/settings.json— no env var overrides at runtime for provider config (exceptANTHROPIC_API_KEY/OPENAI_API_KEYnoted in.env.example) - No
.envloading in backend code — env vars passed via Docker Composeenvironment:block
Gaps / Unknowns
- No ESLint, Prettier, Black, or Ruff configuration committed
- No pre-commit hooks
- No consistent JSDoc or Python docstring coverage