153 lines
4.2 KiB
Markdown
153 lines
4.2 KiB
Markdown
# PlantPlan – Architektur
|
||
|
||
**Datum:** 16. April 2026
|
||
|
||
---
|
||
|
||
## 1. Überblick
|
||
|
||
PlantPlan ist eine hybride Webanwendung für technische Gleisplan-Skizzen. Das iPad dient als Eingabegerät (PWA im Safari), ein Python-Backend übernimmt Bibliotheksverwaltung, Normalisierung und Export.
|
||
|
||
```
|
||
┌─────────────────────────┐ ┌─────────────────────────┐
|
||
│ client/ │ │ server/ │
|
||
│ (tldraw + React + Vite) │ HTTP │ (FastAPI + Python) │
|
||
│ │────────▶│ │
|
||
│ - Canvas & Zeichnung │ JSON │ - Symbolbibliothek │
|
||
│ - Custom Shapes │◀────────│ - Normalisierung │
|
||
│ - Snap-to-Grid │ │ - JSON/SVG Export │
|
||
└─────────────────────────┘ └─────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Projektstruktur
|
||
|
||
```
|
||
plantplan/
|
||
├── bin/ Skripte (setenv, install, activate)
|
||
├── cfg/ Konfigurationsdateien
|
||
├── client/ Frontend – wird auf Server deployed
|
||
│ ├── src/
|
||
│ │ ├── main.tsx React Entry Point
|
||
│ │ └── App.tsx tldraw Canvas
|
||
│ ├── index.html
|
||
│ ├── package.json
|
||
│ ├── tsconfig.json
|
||
│ └── vite.config.ts Dev-Proxy /api → localhost:8000
|
||
├── server/ Backend – wird auf Server kopiert
|
||
│ ├── catalog/
|
||
│ │ └── symbols.json Symbolbibliothek
|
||
│ ├── main.py FastAPI Anwendung
|
||
│ └── requirements.txt Python-Abhängigkeiten
|
||
├── doc/ Dokumentation
|
||
├── lib/ Python-Bibliotheken (eigene Module)
|
||
├── tests/ Tests
|
||
└── examples/ Beispieldaten
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Client (Frontend)
|
||
|
||
| Aspekt | Detail |
|
||
|---|---|
|
||
| Framework | React 18 + TypeScript |
|
||
| Canvas | tldraw v2 |
|
||
| Bundler | Vite |
|
||
| Dev-Server | `localhost:5173` |
|
||
| Build-Output | `client/dist/` (statische Dateien) |
|
||
|
||
Der Vite Dev-Server leitet `/api/*`-Requests per Proxy an das lokale Backend weiter. Im Produktivbetrieb liefert nginx die statischen Dateien aus und proxied API-Calls.
|
||
|
||
---
|
||
|
||
## 4. Server (Backend)
|
||
|
||
| Aspekt | Detail |
|
||
|---|---|
|
||
| Framework | FastAPI |
|
||
| ASGI-Server | Uvicorn |
|
||
| Python | >= 3.11 |
|
||
| Dev-Server | `localhost:8000` |
|
||
|
||
### API-Endpunkte
|
||
|
||
| Methode | Pfad | Beschreibung |
|
||
|---|---|---|
|
||
| GET | `/symbols` | Symbolbibliothek als JSON ausliefern |
|
||
| POST | `/normalize` | Koordinaten auf Grid snappen |
|
||
| POST | `/export` | Finales JSON/SVG-Projektfile erzeugen |
|
||
|
||
### Datenmodell (Request)
|
||
|
||
```json
|
||
{
|
||
"shapes": [
|
||
{
|
||
"id": "shape:abc",
|
||
"type": "weiche",
|
||
"x": 100,
|
||
"y": 200,
|
||
"props": { "radius": 300, "direction": "left" }
|
||
}
|
||
],
|
||
"grid_size": 10
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Lokale Entwicklung
|
||
|
||
Beide Komponenten laufen parallel auf einer Maschine:
|
||
|
||
```
|
||
Terminal 1 (Server):
|
||
cd server
|
||
pip install -r requirements.txt
|
||
uvicorn main:app --reload
|
||
|
||
Terminal 2 (Client):
|
||
cd client
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
Kein externer Server nötig. Der Vite-Proxy sorgt dafür, dass Frontend und Backend nahtlos kommunizieren.
|
||
|
||
---
|
||
|
||
## 6. Deployment (Hetzner)
|
||
|
||
Beim Deployment werden zwei Teile auf den Server kopiert:
|
||
|
||
| Was | Wohin | Wie |
|
||
|---|---|---|
|
||
| `client/dist/` (nach `npm run build`) | nginx Document Root | Statische Dateien |
|
||
| `server/` | Python-Umgebung | uvicorn hinter nginx reverse proxy |
|
||
|
||
```
|
||
nginx
|
||
├── / → client/dist/ (statische Dateien)
|
||
└── /api/* → proxy_pass http://127.0.0.1:8000
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Umgebungsvariablen (setenv.bat / setenv.sh)
|
||
|
||
| Variable | Pfad |
|
||
|---|---|
|
||
| `PROJECT` | Projekt-Root |
|
||
| `PV_CLIENT` | `client/` |
|
||
| `PV_SERVER` | `server/` |
|
||
| `PV_BIN` | `bin/` |
|
||
| `PV_LIB` | `lib/` |
|
||
| `PV_CFG` | `cfg/` |
|
||
| `PV_DATA` | `data/` |
|
||
| `PV_LOG` | `log/` |
|
||
| `PV_RESULTS` | `results/` |
|
||
| `PV_EXAMPLES` | `examples/` |
|
||
| `PV_TESTS` | `tests/` |
|