# STRUCTURE — document-scanner _Last updated: 2026-05-21_ ## Summary The project is a monorepo with two top-level service directories (`backend/`, `frontend/`) and Docker Compose at the root. Backend is a Python/FastAPI app; frontend is a Vue 3 SPA built with Vite. All persistent data lives under `backend/data/`. --- ## Top-Level Layout ``` document_scanner/ ├── backend/ Python FastAPI service ├── frontend/ Vue 3 SPA ├── docker-compose.yml Two-service compose (backend + frontend) ├── .env.example Optional env vars (API keys) └── .claude/ Claude Code settings ``` --- ## Backend ``` backend/ ├── main.py FastAPI app: CORS, lifespan, router registration ├── config.py Path constants, DEFAULT_SETTINGS, ensure_data_dirs() ├── requirements.txt Python dependencies ├── pytest.ini pytest config (asyncio_mode=auto) ├── Dockerfile │ ├── api/ FastAPI routers (thin HTTP layer) │ ├── documents.py Upload, list, get, delete, reclassify endpoints │ ├── topics.py Topic CRUD endpoints │ └── settings.py AI provider settings endpoints │ ├── ai/ AI provider abstraction │ ├── base.py AIProvider ABC + ClassificationResult dataclass │ ├── __init__.py get_provider() factory │ ├── anthropic_provider.py │ ├── openai_provider.py │ ├── ollama_provider.py extends OpenAIProvider │ └── lmstudio_provider.py extends OpenAIProvider │ ├── services/ Business logic (no FastAPI dependency) │ ├── extractor.py Text extraction: PDF/DOCX/image/text dispatch │ ├── classifier.py Orchestrates AI call + topic auto-creation │ └── storage.py Flat-file JSON CRUD + filelock │ ├── data/ Runtime data (volume-mounted in Docker) │ ├── uploads/ Uploaded document files │ ├── metadata/ Per-document JSON metadata files │ ├── topics.json Global topic list │ └── settings.json Active AI provider + system prompt config │ └── tests/ ├── conftest.py Fixtures: isolated tmp data dir, TestClient, sample files ├── test_health.py ├── test_documents.py ├── test_topics.py ├── test_settings.py ├── test_extractor.py ├── test_classifier.py └── test_lmstudio.py ``` --- ## Frontend ``` frontend/ ├── index.html Vite entry HTML ├── vite.config.js Vite config (Vue plugin, /api proxy) ├── tailwind.config.js ├── postcss.config.js ├── package.json Vue 3, Vue Router 4, Pinia; no test framework ├── Dockerfile │ └── src/ ├── main.js App bootstrap: Vue + Pinia + Router ├── App.vue Root component (sidebar layout wrapper) ├── style.css Global Tailwind imports │ ├── api/ │ └── client.js fetch wrapper; all API calls go through here │ ├── stores/ Pinia stores (data + actions layer) │ ├── documents.js Document list, upload, classify state │ ├── topics.js Topic list CRUD state │ └── settings.js AI provider settings state │ ├── router/ │ └── index.js Routes: /, /topics, /topics/:name, /document/:id, /settings │ ├── views/ Page-level components (one per route) │ ├── HomeView.vue │ ├── TopicsView.vue │ ├── DocumentView.vue │ └── SettingsView.vue │ └── components/ Reusable UI components ├── layout/ │ └── AppSidebar.vue ├── documents/ │ └── DocumentCard.vue ├── topics/ │ ├── TopicBadge.vue │ └── TopicManager.vue └── upload/ ├── DropZone.vue └── UploadProgress.vue ``` --- ## Key Entry Points | File | Purpose | |---|---| | `backend/main.py` | FastAPI app instantiation, middleware, router registration | | `backend/config.py` | All path constants and default settings — change storage paths here | | `backend/ai/__init__.py` | Add a new AI provider here | | `frontend/src/main.js` | Vue app bootstrap | | `frontend/src/api/client.js` | All HTTP calls originate here | --- ## Where to Add New Code - **New API endpoint**: add router in `backend/api/`, register in `backend/main.py` - **New AI provider**: implement `AIProvider` ABC in `backend/ai/`, add case in `get_provider()` - **New document type**: add extraction branch in `backend/services/extractor.py` - **New frontend page**: add view in `src/views/`, add route in `src/router/index.js` - **New shared UI component**: add to relevant `src/components//` subdirectory --- ## Gaps / Unknowns - No `src/components/settings/` subdirectory — settings UI is entirely in `SettingsView.vue` - No migration or schema versioning for `topics.json` / `settings.json` flat files