7a34807fa0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
145 lines
5.2 KiB
Markdown
145 lines
5.2 KiB
Markdown
# 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/<category>/` 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
|