298 lines
16 KiB
Markdown
298 lines
16 KiB
Markdown
# Workforce Planner – Zielarchitektur
|
||
|
||
## 1. Architekturdiagramm
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ CLIENTS │
|
||
│ │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
|
||
│ │ Desktop App │ │ Web App │ │ MedWork Plugin │ │
|
||
│ │ (tkinter) │ │(React/Vue/…) │ │ (Integration) │ │
|
||
│ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
|
||
│ │ │ │ │
|
||
│ └──────────────────┼─────────────────────┘ │
|
||
│ │ │
|
||
│ HTTPS / REST API │
|
||
└────────────────────────────┼────────────────────────────────────┘
|
||
│
|
||
┌────────────────────────────┼────────────────────────────────────┐
|
||
│ API GATEWAY │
|
||
│ │
|
||
│ ┌─────────────────────────┴────────────────────────────────┐ │
|
||
│ │ FastAPI Server │ │
|
||
│ │ │ │
|
||
│ │ ┌─────────┐ ┌────────────┐ ┌──────────┐ ┌────────┐ │ │
|
||
│ │ │ Auth │ │ CORS │ │ Audit │ │ Rate │ │ │
|
||
│ │ │Middleware│ │ Middleware │ │Middleware │ │Limiter │ │ │
|
||
│ │ └─────────┘ └────────────┘ └──────────┘ └────────┘ │ │
|
||
│ │ │ │
|
||
│ │ ┌────────────────────────────────────────────────────┐ │ │
|
||
│ │ │ API Routes │ │ │
|
||
│ │ │ /employees /absences /balance /practices │ │ │
|
||
│ │ │ /auth /reports /health /audit │ │ │
|
||
│ │ └────────────────────────┬───────────────────────────┘ │ │
|
||
│ └───────────────────────────┼───────────────────────────────┘ │
|
||
└──────────────────────────────┼──────────────────────────────────┘
|
||
│
|
||
┌──────────────────────────────┼──────────────────────────────────┐
|
||
│ SERVICE LAYER │
|
||
│ (Businesslogik) │
|
||
│ │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
|
||
│ │ Employee │ │ Absence │ │ Approval │ │
|
||
│ │ Service │ │ Service │ │ Workflow │ │
|
||
│ └──────┬───────┘ └──────┬───────┘ └──────────┬───────────┘ │
|
||
│ │ │ │ │
|
||
│ │ ┌────────────┴──────────┐ │ │
|
||
│ │ │ Business Rules │ │ │
|
||
│ │ │ • Überschneidung │ │ │
|
||
│ │ │ • Kontingentprüfung │ │ │
|
||
│ │ │ • Mindestbesetzung │ │ │
|
||
│ │ └───────────────────────┘ │ │
|
||
│ │ │ │
|
||
└─────────┼────────────────────────────────────────┼──────────────┘
|
||
│ │
|
||
┌─────────┼────────────────────────────────────────┼──────────────┐
|
||
│ │ REPOSITORY LAYER │ │
|
||
│ │ (Datenzugriff) │ │
|
||
│ │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
|
||
│ │ Employee │ │ Absence │ │ Balance │ │
|
||
│ │ Repository │ │ Repository │ │ Repository │ │
|
||
│ └──────┬───────┘ └──────┬───────┘ └──────────┬───────────┘ │
|
||
└─────────┼─────────────────┼─────────────────────┼──────────────┘
|
||
│ │ │
|
||
└─────────────────┼──────────────────────┘
|
||
│
|
||
┌──────┴──────┐
|
||
│ SQLAlchemy │
|
||
│ ORM │
|
||
└──────┬──────┘
|
||
│
|
||
┌────────────┴────────────┐
|
||
│ │
|
||
┌──────┴──────┐ ┌───────┴──────┐
|
||
│ SQLite │ │ PostgreSQL │
|
||
│ (Dev) │ │ (Produktion)│
|
||
└─────────────┘ └──────────────┘
|
||
```
|
||
|
||
## 2. Komponentenbeschreibung
|
||
|
||
### Client Layer
|
||
| Komponente | Beschreibung |
|
||
|---|---|
|
||
| **Desktop App** | Bestehende tkinter-App. Wird umgebaut: statt lokaler JSON-Dateien ruft sie die REST API auf. Gleiche Benutzeranmeldung wie Web. |
|
||
| **Web App** | Modernes Web-Frontend (React/Vue/Svelte). Nutzt dieselbe API. Responsive für Tablet/Desktop. |
|
||
| **MedWork Plugin** | Adapter der MedWork-Daten (Patienten, Termine) mit dem Arbeitsplan verknüpft. Eigener API-Endpunkt. |
|
||
|
||
### API Layer
|
||
| Komponente | Beschreibung |
|
||
|---|---|
|
||
| **FastAPI Server** | Zentraler Einstiegspunkt. Stellt REST-Endpunkte bereit. Auto-generierte OpenAPI-Doku. |
|
||
| **Auth Middleware** | JWT-basierte Authentifizierung. Gleiche Tokens für Desktop + Web. |
|
||
| **Audit Middleware** | Protokolliert jede schreibende Aktion (wer, was, wann, alte/neue Werte). |
|
||
| **CORS Middleware** | Erlaubt Cross-Origin-Zugriffe für Web-Client. |
|
||
|
||
### Service Layer (Businesslogik)
|
||
| Komponente | Beschreibung |
|
||
|---|---|
|
||
| **EmployeeService** | Mitarbeiter anlegen/bearbeiten/deaktivieren. E-Mail-Duplikat-Check. |
|
||
| **AbsenceService** | Abwesenheiten erstellen mit Regelprüfung. Kontingent berechnen. |
|
||
| **Business Rules** | `check_no_overlap` – keine überlappenden Einträge. `check_balance` – genug Ferientage? `check_min_staffing` – Mindestbesetzung gewährleistet? |
|
||
| **Approval Workflow** | Pending → Approved/Rejected Workflow mit Genehmiger-Zuweisung. |
|
||
|
||
### Repository Layer
|
||
| Komponente | Beschreibung |
|
||
|---|---|
|
||
| **EmployeeRepository** | CRUD für Mitarbeiter. Einziger Code der direkt SQL ausführt. |
|
||
| **AbsenceRepository** | CRUD + Spezialabfragen (Überschneidungen, Abwesende pro Tag). |
|
||
| **BalanceRepository** | Ferientage-Kontingent pro Mitarbeiter/Jahr. |
|
||
|
||
### Data Layer
|
||
| Komponente | Beschreibung |
|
||
|---|---|
|
||
| **SQLAlchemy ORM** | Abstrahiert Datenbank. Identischer Code für SQLite und PostgreSQL. |
|
||
| **Practice (Mandant)** | Multi-Tenant: jede Praxis hat eigene Mitarbeiter/Abwesenheiten. |
|
||
| **AuditLog** | Unveränderliches Änderungsprotokoll mit JSON-Diff. |
|
||
|
||
## 3. Technologie-Stack
|
||
|
||
| Schicht | Technologie | Begründung |
|
||
|---|---|---|
|
||
| **Backend** | Python 3.11+ | Bestehende Codebasis, grosses Ökosystem |
|
||
| **API Framework** | FastAPI | Async, Auto-Docs, Pydantic-Integration, modern |
|
||
| **ORM** | SQLAlchemy 2.0 | Industriestandard, DB-agnostisch |
|
||
| **Validierung** | Pydantic v2 | Schemas für API + Clients, schnell |
|
||
| **Auth** | JWT (python-jose) | Stateless, Desktop + Web kompatibel |
|
||
| **Passwörter** | passlib + bcrypt | Industriestandard |
|
||
| **DB (Dev)** | SQLite | Kein Setup nötig, lokales Testen |
|
||
| **DB (Prod)** | PostgreSQL 16 | ACID, JSON-Support, skalierbar |
|
||
| **Desktop** | tkinter (→ später Qt) | Bestehend, HTTP-Client wird ergänzt |
|
||
| **Web** | React oder Vue.js | SPA, nutzt dieselbe API |
|
||
| **Deployment** | Docker + Docker Compose | Einfach, reproduzierbar |
|
||
| **Reverse Proxy** | nginx / Caddy | HTTPS, Load Balancing |
|
||
|
||
## 4. Datenfluss
|
||
|
||
### Abwesenheit eintragen (von jedem Client)
|
||
|
||
```
|
||
Client (Desktop/Web)
|
||
│
|
||
▼
|
||
POST /api/v1/absences
|
||
{ employee_id, category, start_date, end_date, reason }
|
||
│
|
||
▼
|
||
Auth Middleware ──── JWT prüfen ──── 401 wenn ungültig
|
||
│
|
||
▼
|
||
AbsenceService.create_absence()
|
||
│
|
||
├─→ EmployeeRepository.get_by_id() → Mitarbeiter existiert?
|
||
├─→ rules.check_no_overlap() → Überschneidung?
|
||
├─→ rules.check_balance() → Genug Ferientage?
|
||
├─→ rules.check_min_staffing() → Mindestbesetzung OK?
|
||
│
|
||
├─→ AbsenceRepository.create() → DB INSERT
|
||
├─→ AuditLog.log_action() → Protokollierung
|
||
├─→ db.commit()
|
||
│
|
||
▼
|
||
Response: 201 Created
|
||
{ id, employee_id, category, status, business_days, ... }
|
||
│
|
||
▼
|
||
Client aktualisiert Kalenderansicht
|
||
```
|
||
|
||
### Login-Flow (Desktop + Web identisch)
|
||
|
||
```
|
||
Client
|
||
│
|
||
▼
|
||
POST /api/v1/auth/login
|
||
{ email, password }
|
||
│
|
||
▼
|
||
verify_password(plain, hashed)
|
||
│
|
||
├─→ Falsch: 401 Unauthorized
|
||
├─→ Richtig: create_access_token(employee_id, role)
|
||
│
|
||
▼
|
||
Response: { access_token, token_type, employee }
|
||
│
|
||
▼
|
||
Client speichert Token → sendet bei jedem Request als
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
### Multi-Tenant Datenfluss
|
||
|
||
```
|
||
Praxis A (ID: praxis_a) Praxis B (ID: praxis_b)
|
||
│ │
|
||
▼ ▼
|
||
Mitarbeiter mit Mitarbeiter mit
|
||
practice_id = praxis_a practice_id = praxis_b
|
||
│ │
|
||
▼ ▼
|
||
Abwesenheiten nur Abwesenheiten nur
|
||
für Praxis A sichtbar für Praxis B sichtbar
|
||
|
||
Admin-Benutzer mit role=ADMIN kann praxisübergreifend zugreifen.
|
||
```
|
||
|
||
## 5. Deployment-Konzept
|
||
|
||
### Entwicklung (lokal)
|
||
|
||
```
|
||
┌─────────────────────────────────────────┐
|
||
│ Entwickler-PC │
|
||
│ │
|
||
│ uvicorn workforce_planner.api.app:app │
|
||
│ │ │
|
||
│ └──→ SQLite (workforce_planner.db)│
|
||
│ │
|
||
│ Desktop App (tkinter) → localhost:8000 │
|
||
└─────────────────────────────────────────┘
|
||
```
|
||
|
||
### Produktion (Docker)
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────┐
|
||
│ Server / VPS / Cloud │
|
||
│ │
|
||
│ ┌────────────┐ │
|
||
│ │ nginx │ ◄── HTTPS (Let's Encrypt) │
|
||
│ │ :443/:80 │ │
|
||
│ └─────┬──────┘ │
|
||
│ │ │
|
||
│ ┌─────┴──────┐ ┌──────────────────────────────┐ │
|
||
│ │ FastAPI │ │ PostgreSQL │ │
|
||
│ │ :8000 ├──►│ :5432 │ │
|
||
│ │ (2 Worker) │ │ Volume: /data/postgres │ │
|
||
│ └────────────┘ └──────────────────────────────┘ │
|
||
│ │
|
||
│ docker-compose.yml orchestriert alles │
|
||
└──────────────────────────────────────────────────────┘
|
||
|
||
Desktop Clients ──────► server.praxis.ch:443/api/v1/
|
||
Web Clients ──────► server.praxis.ch:443/
|
||
```
|
||
|
||
### docker-compose.yml (Ziel)
|
||
|
||
```yaml
|
||
services:
|
||
api:
|
||
build: .
|
||
ports: ["8000:8000"]
|
||
environment:
|
||
WP_DATABASE_URL: postgresql://wp:secret@db:5432/workforce
|
||
WP_SECRET_KEY: ${SECRET_KEY}
|
||
depends_on: [db]
|
||
|
||
db:
|
||
image: postgres:16-alpine
|
||
volumes: [pgdata:/var/lib/postgresql/data]
|
||
environment:
|
||
POSTGRES_DB: workforce
|
||
POSTGRES_USER: wp
|
||
POSTGRES_PASSWORD: secret
|
||
|
||
nginx:
|
||
image: nginx:alpine
|
||
ports: ["443:443", "80:80"]
|
||
volumes: [./nginx.conf:/etc/nginx/conf.d/default.conf]
|
||
depends_on: [api]
|
||
|
||
volumes:
|
||
pgdata:
|
||
```
|
||
|
||
## Aktueller Stand
|
||
|
||
| Komponente | Status |
|
||
|---|---|
|
||
| Datenmodelle (Employee, Absence, BalanceAccount, Practice, AuditLog) | ✅ Fertig |
|
||
| Enums (AbsenceCategory, EmployeeRole, AbsenceStatus) | ✅ Fertig |
|
||
| Pydantic Schemas (Create/Update/Read) | ✅ Fertig |
|
||
| Database Setup (SQLite/PostgreSQL) | ✅ Fertig |
|
||
| Repository Layer (Employee, Absence, Balance) | ✅ Fertig |
|
||
| Service Layer + Business Rules | ✅ Fertig |
|
||
| FastAPI Routen (Employees, Absences, Balance) | ✅ Fertig |
|
||
| JWT Auth + Rollen | ✅ Fertig |
|
||
| Audit Logging | ✅ Fertig |
|
||
| Multi-Tenant (Practice) | ✅ Modell fertig |
|
||
| Desktop-Client Umstellung auf API | ⬜ Nächster Schritt |
|
||
| Web-Frontend | ⬜ Geplant |
|
||
| MedWork-Integration | ⬜ Geplant |
|
||
| Docker Deployment | ⬜ Geplant |
|