design final
This commit is contained in:
parent
a0d2188f6f
commit
99a690972e
1414 changed files with 2389 additions and 1455 deletions
144
.github/copilot-instructions.md
vendored
Normal file
144
.github/copilot-instructions.md
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
# Copilot Instructions for Studio EinsZwoVier Web Application
|
||||
|
||||
## Project Overview
|
||||
This is a **FastAPI-based web application** serving as a multi-service hub for Studio EinsZwoVier, a collaborative print studio. The main app provides a PDF print cost calculator with automated ink coverage analysis, integrated with a Matrix server for order collection and payment tracking.
|
||||
|
||||
## Architecture & Service Boundaries
|
||||
|
||||
### Core FastAPI Application (`main.py`, port 80→8000)
|
||||
- **Landing page** (`/`) with presence state management (studio open/closed indicator)
|
||||
- **Cost calculator** (`/cost`) for PDF analysis and price estimation
|
||||
- **About page** (`/about`)
|
||||
- **Order submission** via Matrix integration
|
||||
|
||||
### Multi-Container Stack (Docker Compose)
|
||||
The application orchestrates 7+ containerized services:
|
||||
- **web**: FastAPI app (this repo's code)
|
||||
- **synapse**: Matrix server for print job collection (port 8008)
|
||||
- **ollama**: Local LLM inference (port 11434)
|
||||
- **open-webui**: LLM chat interface (port 8080)
|
||||
- **bookstack + mariadb**: Documentation wiki
|
||||
- **docmost + postgres + redis**: Knowledge management system
|
||||
- **watchtower**: Auto-updates all containers every 24h
|
||||
|
||||
### PDF Processing Pipeline (`cost_calculator.py`)
|
||||
1. **Upload** → Validate `.pdf` extension only
|
||||
2. **Page-by-page analysis**:
|
||||
- Extract dimensions from `CropBox` (preferred) or `MediaBox`
|
||||
- Convert PDF points to meters: `(points / 72.0) * 0.0254`
|
||||
- Render at 150 DPI using `pdf2image`
|
||||
- Calculate ink coverage: pixels with RGB < 250 = ink
|
||||
- Detect color vs B&W: HSV saturation analysis (>0.1% pixels with sat>10 = color)
|
||||
3. **Cost calculation**: area (m²) × rate (from env vars `RATE_PER_M2_BLACK`/`COLOR`)
|
||||
|
||||
### Matrix Integration (`mailer.py`)
|
||||
- Uses `matrix-nio` async client to send orders
|
||||
- **Critical**: Must set `MATRIX_USER`, `MATRIX_PASS`, `MATRIX_HOMESERVER` env vars
|
||||
- Sends structured summary (German language) + PDF upload to hardcoded room ID
|
||||
- **Synchronous wrapper** `send_order_sync()` bridges async/sync contexts for FastAPI
|
||||
|
||||
## Developer Workflows
|
||||
|
||||
### Local Development
|
||||
```bash
|
||||
# Option 1: Direct Python execution (auto-reload)
|
||||
python run_app.py
|
||||
|
||||
# Option 2: Full stack with Docker Compose
|
||||
docker-compose up --build -d
|
||||
|
||||
# Access at: http://localhost (or einszwovier.local in local network)
|
||||
```
|
||||
|
||||
### Environment Configuration
|
||||
Create `.env` file with:
|
||||
```bash
|
||||
# Print rates (€/m²)
|
||||
RATE_PER_M2_BLACK=4.0
|
||||
RATE_PER_M2_COLOR=5.0
|
||||
|
||||
# Matrix integration
|
||||
MATRIX_USER=@bot:homeserver
|
||||
MATRIX_PASS=secret
|
||||
MATRIX_HOMESERVER=http://einszwovier.local:8008
|
||||
|
||||
# Service ports
|
||||
SYNAPSE_PORT=8008
|
||||
OLLAMA_PORT=11434
|
||||
OPENWEBUI_PORT=8080
|
||||
BOOKSTACK_PORT=6875
|
||||
|
||||
# BookStack/DB configs (see docker-compose.yml for full list)
|
||||
```
|
||||
|
||||
### Debugging Matrix Integration
|
||||
Use `get_room_id.py` to discover Matrix room IDs:
|
||||
```python
|
||||
# Connects to local Matrix server, joins room, prints room IDs
|
||||
python get_room_id.py
|
||||
```
|
||||
Then update the hardcoded room ID in `main.py` line 127: `room_id="!eFW..."`
|
||||
|
||||
## Project-Specific Conventions
|
||||
|
||||
### Presence State Management
|
||||
- In-memory global `presence_state` dict tracks studio open/closed status
|
||||
- API endpoints: `GET /presence`, `POST /presence`, `POST /presence/toggle`
|
||||
- Background task `update_presence_periodically()` runs every 5 min (currently no-op placeholder)
|
||||
|
||||
### German UI/UX
|
||||
- Templates use German language exclusively
|
||||
- Error/success messages in German (e.g., "Dein Auftrag wurde erfolgreich gesendet!")
|
||||
- Cost calculator displays "S/W" (Schwarz/Weiß) vs "Farbe" (color)
|
||||
|
||||
### File Organization
|
||||
- **Uploads persist** in `data/uploads/` (mounted volume in Docker)
|
||||
- **Templates** in `templates/` (Jinja2, extending `base.html`)
|
||||
- **Static assets** in `static/` (CSS, fonts, images)
|
||||
- **Service data** in dedicated dirs: `bookstack/`, `docmost/`, `matrix/`, `ollama/`, `open-webui/`
|
||||
|
||||
### Docker Production Command
|
||||
The `Dockerfile` uses **Gunicorn with Uvicorn workers** for production:
|
||||
```bash
|
||||
gunicorn main:app -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --workers 4 --timeout 120
|
||||
```
|
||||
But `docker-compose.yml` overrides with `--reload` for dev convenience.
|
||||
|
||||
## Critical Integration Points
|
||||
|
||||
### PDF Analysis Return Structure
|
||||
`analyze_pdf()` returns:
|
||||
```python
|
||||
{
|
||||
"filename": str,
|
||||
"pages": [{"page": int, "width_m": float, "height_m": float,
|
||||
"area_m2": float, "ink_pct": float, "is_color": bool, "cost": float}],
|
||||
"total_area_black": float,
|
||||
"total_area_color": float,
|
||||
"total_cost_black": float,
|
||||
"total_cost_color": float,
|
||||
"grand_total": float
|
||||
}
|
||||
```
|
||||
|
||||
### Matrix Room ID Hardcoding
|
||||
⚠️ **Known technical debt**: Room ID is hardcoded in `send_order_endpoint()`. Update when Matrix server changes or for different deployment environments.
|
||||
|
||||
### Async/Sync Bridge Pattern
|
||||
Matrix client is async, but FastAPI endpoint is sync. Pattern used:
|
||||
```python
|
||||
def send_order_sync(...):
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(send_order(...))
|
||||
loop.close()
|
||||
```
|
||||
|
||||
## External Dependencies
|
||||
- **Poppler** (system): Required for `pdf2image` (installed in Dockerfile)
|
||||
- **OpenCV** (system): Requires `libgl1`, `libglib2.0-0` (installed in Dockerfile)
|
||||
- **Font files**: Custom fonts in `static/fonts/` (BauPro, HealTheWebA/B, SISTEMAS)
|
||||
|
||||
## Testing & Utilities
|
||||
- `test_send_pdf.py`: Manual test script for Matrix integration
|
||||
- No automated test suite currently implemented
|
||||
Loading…
Add table
Add a link
Reference in a new issue