773 lines
18 KiB
Markdown
773 lines
18 KiB
Markdown
# Zeiterfassungssystem für pädagogische Mitarbeiter
|
|
|
|
Eine vollständige Webanwendung zur Erfassung und Verwaltung von Flexistunden für pädagogische Mitarbeiter (PM) an Schulen.
|
|
|
|
## 📋 Inhaltsverzeichnis
|
|
|
|
- [Überblick](#überblick)
|
|
- [Funktionen](#funktionen)
|
|
- [Technologie-Stack](#technologie-stack)
|
|
- [Voraussetzungen](#voraussetzungen)
|
|
- [Installation](#installation)
|
|
- [Konfiguration](#konfiguration)
|
|
- [Verwendung](#verwendung)
|
|
- [API-Dokumentation](#api-dokumentation)
|
|
- [Architektur](#architektur)
|
|
- [Sicherheit](#sicherheit)
|
|
- [Backup & Wartung](#backup--wartung)
|
|
- [Fehlerbehebung](#fehlerbehebung)
|
|
|
|
## 🎯 Überblick
|
|
|
|
Diese Anwendung wurde entwickelt, um die Erfassung von Flexistunden (zusätzliche Arbeitsstunden) für pädagogische Mitarbeiter an Schulen zu vereinfachen. Sie ermöglicht:
|
|
|
|
- **Mitarbeitern**: Wöchentliche Zeiterfassung anhand eines vorkonfigurierten Stundenplans
|
|
- **Administratoren**: Vollständige Verwaltung von Benutzern, Stundenplänen, Schuljahren und Zeiteinträgen
|
|
|
|
Das System arbeitet mit ISO-Kalenderwochen und unterstützt schuljahrbezogene Auswertungen.
|
|
|
|
## ✨ Funktionen
|
|
|
|
### Für Mitarbeiter
|
|
|
|
- **Wochenbasierte Zeiterfassung**: Auswahl der gearbeiteten Zeiten aus dem Stundenplan
|
|
- **Kalenderwochen-Navigation**: Einfaches Vor- und Zurückblättern zwischen Wochen
|
|
- **Jahresübersicht**: Anzeige der geleisteten vs. Soll-Arbeitsstunden
|
|
- **Responsive Design**: Optimiert für Desktop, Tablet und Mobile
|
|
|
|
### Für Administratoren
|
|
|
|
- **Benutzerverwaltung**:
|
|
- Benutzer anlegen, bearbeiten und löschen
|
|
- Jahresarbeitsstunden pro Benutzer festlegen (Standard: 1800h)
|
|
- Passwörter zurücksetzen
|
|
- **Stundenplan-Management**:
|
|
- Wochenstundenplan mit Unterrichts- und Pausenzeiten erstellen
|
|
- Unterrichtsstunden und Pausen unterscheiden
|
|
- Zeiten mit Titeln versehen (z.B. "Mathematik", "Pause")
|
|
|
|
- **Schuljahrverwaltung**:
|
|
- Schuljahre mit Start- und Enddatum definieren
|
|
- Aktives Schuljahr setzen
|
|
- Jahresberechnungen basierend auf aktivem Schuljahr
|
|
|
|
- **Zeiteintrags-Verwaltung**:
|
|
- Alle Zeiteinträge einsehen und bearbeiten
|
|
- Manuelle Stundeneintragungen (positiv = Abzug, negativ = Hinzurechnung)
|
|
- Einzelne Einträge korrigieren oder löschen
|
|
|
|
- **Berichtswesen**:
|
|
- Jahresübersicht aller Mitarbeiter
|
|
- PDF-Export der Jahresübersicht
|
|
- Wochenweise Stundenauswertung
|
|
|
|
## 🛠 Technologie-Stack
|
|
|
|
### Frontend
|
|
|
|
- **Elm 0.19**: Funktionale Programmiersprache für type-safe UI
|
|
- **Bulma CSS**: Modernes CSS-Framework
|
|
- **Font Awesome**: Icons
|
|
- **LocalStorage**: Client-seitige Datenpersistenz für Authentifizierung
|
|
|
|
### Backend
|
|
|
|
- **Go (Golang)**: Performante Backend-Sprache
|
|
- **Echo Framework**: Web-Framework für Go
|
|
- **SQLite**: Embedded SQL-Datenbank
|
|
- **JWT**: Token-basierte Authentifizierung
|
|
- **bcrypt**: Passwort-Hashing
|
|
- **gofpdf**: PDF-Generierung
|
|
|
|
### Deployment
|
|
|
|
- **Docker**: Containerisierung
|
|
- **Docker Compose**: Orchestrierung
|
|
|
|
## 📦 Voraussetzungen
|
|
|
|
### Für Docker-Deployment (empfohlen)
|
|
|
|
- Docker (Version 20.10+)
|
|
- Docker Compose (Version 1.29+)
|
|
|
|
### Für lokale Entwicklung
|
|
|
|
- Go 1.21+
|
|
- Elm 0.19
|
|
- Node.js 16+ (für Elm-Tooling)
|
|
- SQLite3
|
|
|
|
## 🚀 Installation
|
|
|
|
### Option 1: Docker Compose (Produktion)
|
|
|
|
1. **Repository klonen**
|
|
|
|
```bash
|
|
git clone <repository-url>
|
|
cd zeiterfassung
|
|
```
|
|
|
|
2. **Umgebungsvariablen konfigurieren**
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
nano .env
|
|
```
|
|
|
|
Wichtige Variablen in `.env`:
|
|
|
|
```env
|
|
PORT=8080
|
|
DB_PATH=/data/timetracking.db
|
|
JWT_SECRET=ihr-sicheres-geheimnis-hier-ändern
|
|
TZ=Europe/Berlin
|
|
```
|
|
|
|
3. **Anwendung starten**
|
|
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
4. **Anwendung aufrufen**
|
|
|
|
```
|
|
http://localhost:8080
|
|
```
|
|
|
|
**Standard-Anmeldedaten:**
|
|
|
|
- Benutzername: `admin`
|
|
- Passwort: `admin123`
|
|
|
|
⚠️ **WICHTIG**: Ändern Sie das Admin-Passwort sofort nach der ersten Anmeldung!
|
|
|
|
### Option 2: Lokale Entwicklung
|
|
|
|
1. **Backend kompilieren**
|
|
|
|
```bash
|
|
go mod download
|
|
go build -o timetracking
|
|
```
|
|
|
|
2. **Frontend kompilieren**
|
|
|
|
```bash
|
|
cd static
|
|
elm make Main.elm --output=elm.js --optimize
|
|
cd ..
|
|
```
|
|
|
|
3. **Umgebungsvariablen setzen**
|
|
|
|
```bash
|
|
export PORT=8080
|
|
export DB_PATH=./timetracking.db
|
|
export JWT_SECRET=development-secret
|
|
```
|
|
|
|
4. **Anwendung starten**
|
|
|
|
```bash
|
|
./timetracking
|
|
```
|
|
|
|
## ⚙️ Konfiguration
|
|
|
|
### Umgebungsvariablen
|
|
|
|
| Variable | Beschreibung | Standard | Erforderlich |
|
|
| ------------- | ------------------------------- | ------------------- | ------------ |
|
|
| `PORT` | HTTP-Server Port | `8080` | Nein |
|
|
| `DB_PATH` | Pfad zur SQLite-Datenbank | `./timetracking.db` | Nein |
|
|
| `JWT_SECRET` | Geheimnis für JWT-Token | - | **Ja** |
|
|
| `TZ` | Zeitzone | `Europe/Berlin` | Nein |
|
|
| `ENVIRONMENT` | `production` für HTTPS-Redirect | - | Nein |
|
|
|
|
### Docker-Volumes
|
|
|
|
Das Docker-Setup erstellt ein persistentes Volume für die Datenbank:
|
|
|
|
```yaml
|
|
volumes:
|
|
timetracking-data:
|
|
driver: local
|
|
```
|
|
|
|
Die Datenbank wird unter `/data/timetracking.db` im Container gespeichert.
|
|
|
|
## 📖 Verwendung
|
|
|
|
### Ersteinrichtung als Administrator
|
|
|
|
1. **Anmelden** mit den Standard-Credentials (admin/admin123)
|
|
|
|
2. **Admin-Passwort ändern**:
|
|
- Gehe zu "Benutzer" Tab
|
|
- Klicke auf "PW Reset" beim Admin-Benutzer
|
|
- Neues sicheres Passwort eingeben
|
|
|
|
3. **Schuljahr erstellen**:
|
|
- Wechsle zum "Schuljahre" Tab
|
|
- Erstelle ein Schuljahr (z.B. "2024/2025")
|
|
- Startdatum: 01.08.2024
|
|
- Enddatum: 31.07.2025
|
|
- Klicke auf "Aktivieren"
|
|
|
|
4. **Stundenplan erstellen**:
|
|
- Wechsle zum "Stundenplan" Tab
|
|
- Füge Unterrichtsstunden hinzu:
|
|
- Wochentag auswählen
|
|
- Start- und Endzeit eingeben
|
|
- Typ: "Unterricht" oder "Pause"
|
|
- Titel vergeben (z.B. "Mathematik 1a")
|
|
|
|
5. **Mitarbeiter anlegen**:
|
|
- Wechsle zum "Benutzer" Tab
|
|
- "Benutzer anlegen"
|
|
- Benutzername und Passwort eingeben
|
|
- Jahresarbeitsstunden festlegen (Standard: 1800h)
|
|
- Admin-Rechte nur für weitere Administratoren
|
|
|
|
### Zeiterfassung als Mitarbeiter
|
|
|
|
1. **Anmelden** mit persönlichen Zugangsdaten
|
|
|
|
2. **Wochenansicht**:
|
|
- Zeigt aktuelle Kalenderwoche mit Datumsbereich
|
|
- Navigation: "Vorherige Woche" / "Nächste Woche"
|
|
|
|
3. **Stunden erfassen**:
|
|
- Klicke auf die Zeitslots, die du gearbeitet hast
|
|
- Ausgewählte Zeiten werden grün markiert
|
|
- Klicke "Speichern" zum Übernehmen
|
|
|
|
4. **Woche bearbeiten**:
|
|
- Falls bereits erfasst, erscheint "Bearbeiten"-Button
|
|
- Aktiviert Bearbeitungsmodus
|
|
- "Einträge löschen" entfernt alle Einträge der Woche
|
|
- Neue Auswahl treffen und "Änderungen speichern"
|
|
|
|
5. **Jahresübersicht prüfen**:
|
|
- Unten auf der Seite: "Jahresgesamtzeit"
|
|
- Zeigt: Soll-Stunden, Geleistete Stunden, Verbleibende Stunden
|
|
- Fortschrittsbalken visualisiert den Status
|
|
|
|
### Administrative Aufgaben
|
|
|
|
#### Manuelle Stundeneintragung
|
|
|
|
Für Korrekturen oder Sonderfälle:
|
|
|
|
1. Gehe zu "Zeiteinträge" Tab
|
|
2. Sektion "Manuelle Stundeneintragung"
|
|
3. Mitarbeiter auswählen
|
|
4. Datum eingeben
|
|
5. Stunden eingeben:
|
|
- **Positive Werte** (z.B. `2.5`): Werden **abgezogen** (z.B. Krankheit, Urlaub)
|
|
- **Negative Werte** (z.B. `-3.0`): Werden **hinzugerechnet** (z.B. Nachholung, Sondereinsatz)
|
|
|
|
#### Zeiteinträge bearbeiten
|
|
|
|
1. Gehe zu "Zeiteinträge" Tab
|
|
2. Liste aller Einträge mit Bearbeitungsmöglichkeit
|
|
3. "Bearbeiten" klicken:
|
|
- Datum ändern
|
|
- Start-/Endzeit anpassen
|
|
- Typ ändern (Unterricht/Pause/Manuell)
|
|
4. Speichern oder Löschen
|
|
|
|
#### PDF-Export
|
|
|
|
1. Gehe zu "Zeiteinträge" Tab
|
|
2. Sektion "Jahresübersicht"
|
|
3. Klicke "PDF exportieren"
|
|
4. PDF enthält:
|
|
- Schuljahrname und Zeitraum
|
|
- Alle Mitarbeiter mit Soll/Ist/Differenz
|
|
- Generierungsdatum
|
|
|
|
## 🔌 API-Dokumentation
|
|
|
|
### Authentifizierung
|
|
|
|
Alle geschützten Endpunkte erfordern einen JWT-Token im Header:
|
|
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Öffentliche Endpunkte
|
|
|
|
#### `POST /api/login`
|
|
|
|
Benutzer-Anmeldung
|
|
|
|
**Request:**
|
|
|
|
```json
|
|
{
|
|
"username": "admin",
|
|
"password": "admin123"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"token": "eyJhbGc...",
|
|
"username": "admin",
|
|
"is_admin": true
|
|
}
|
|
```
|
|
|
|
### Geschützte Endpunkte (Benutzer)
|
|
|
|
#### `GET /api/schedules`
|
|
|
|
Alle Stundenpläne abrufen
|
|
|
|
#### `GET /api/my-time-entries`
|
|
|
|
Eigene Zeiteinträge abrufen
|
|
|
|
#### `POST /api/time-entries/batch`
|
|
|
|
Mehrere Zeiteinträge auf einmal erstellen
|
|
|
|
**Request:**
|
|
|
|
```json
|
|
{
|
|
"entries": [
|
|
{
|
|
"schedule_id": 1,
|
|
"date": "2024-11-04",
|
|
"type": "lesson",
|
|
"start_time": "08:00",
|
|
"end_time": "09:00"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### `DELETE /api/my-time-entries/week?year=2024&week=45`
|
|
|
|
Alle eigenen Einträge einer Woche löschen
|
|
|
|
#### `GET /api/week-dates?year=2024&week=45`
|
|
|
|
Datumsbereich einer Kalenderwoche abrufen
|
|
|
|
#### `GET /api/week-has-entries?year=2024&week=45`
|
|
|
|
Prüfen, ob für eine Woche bereits Einträge existieren
|
|
|
|
#### `GET /api/yearly-hours-summary`
|
|
|
|
Jahresübersicht für alle Benutzer
|
|
|
|
#### `GET /api/my-info`
|
|
|
|
Eigene Benutzerinformationen abrufen
|
|
|
|
#### `GET /api/school-year/active`
|
|
|
|
Aktives Schuljahr abrufen
|
|
|
|
### Admin-Endpunkte
|
|
|
|
#### Stundenplan-Verwaltung
|
|
|
|
- `POST /api/admin/schedules` - Stundenplan erstellen
|
|
- `DELETE /api/admin/schedules/delete?id=1` - Stundenplan löschen
|
|
|
|
#### Benutzerverwaltung
|
|
|
|
- `POST /api/admin/users` - Benutzer erstellen
|
|
- `GET /api/admin/users/list` - Alle Benutzer auflisten
|
|
- `PUT /api/admin/users/:id` - Benutzer bearbeiten (Arbeitsstunden)
|
|
- `PUT /api/admin/users/:id/reset-password` - Passwort zurücksetzen
|
|
- `DELETE /api/admin/users/delete?id=2` - Benutzer löschen
|
|
|
|
#### Zeiteintrags-Verwaltung
|
|
|
|
- `GET /api/admin/time-entries` - Alle Zeiteinträge
|
|
- `PUT /api/admin/time-entries/:id` - Zeiteintrag bearbeiten
|
|
- `DELETE /api/admin/time-entries/:id` - Zeiteintrag löschen
|
|
- `POST /api/admin/time-entry` - Manueller Zeiteintrag
|
|
|
|
#### Schuljahrverwaltung
|
|
|
|
- `GET /api/admin/school-years` - Alle Schuljahre
|
|
- `POST /api/admin/school-years` - Schuljahr erstellen
|
|
- `PUT /api/admin/school-years/:id/activate` - Schuljahr aktivieren
|
|
- `DELETE /api/admin/school-years/:id` - Schuljahr löschen
|
|
|
|
#### Berichte
|
|
|
|
- `GET /api/admin/yearly-summary/pdf` - Jahresübersicht als PDF
|
|
|
|
## 🏗 Architektur
|
|
|
|
### Backend-Struktur
|
|
|
|
```
|
|
.
|
|
├── main.go # Einstiegspunkt, Server-Setup
|
|
├── handlers.go # HTTP-Handler für alle Endpunkte
|
|
├── middleware.go # JWT-Auth, Admin-Check, Rate-Limiting
|
|
├── database.go # Datenbanklogik und Queries
|
|
├── models.go # Datenstrukturen
|
|
├── pdf.go # PDF-Generierung
|
|
├── docker-compose.yml # Docker-Orchestrierung
|
|
└── Dockerfile # Container-Image
|
|
```
|
|
|
|
### Frontend-Struktur
|
|
|
|
```
|
|
static/
|
|
├── Main.elm # Elm-Hauptanwendung
|
|
│ ├── Model # Anwendungszustand
|
|
│ ├── Update # Zustandsänderungen
|
|
│ ├── View # UI-Rendering
|
|
│ └── Subscriptions # Event-Handling
|
|
├── index.html # HTML-Wrapper
|
|
└── elm.js # Kompilierte Elm-Anwendung
|
|
```
|
|
|
|
### Datenbank-Schema
|
|
|
|
#### Tabelle: `users`
|
|
|
|
```sql
|
|
id INTEGER PRIMARY KEY
|
|
username TEXT UNIQUE NOT NULL
|
|
password TEXT NOT NULL (bcrypt-hashed)
|
|
is_admin BOOLEAN DEFAULT 0
|
|
yearly_hours REAL DEFAULT 1800.0
|
|
created_at DATETIME
|
|
```
|
|
|
|
#### Tabelle: `schedules`
|
|
|
|
```sql
|
|
id INTEGER PRIMARY KEY
|
|
day_of_week INTEGER (0=Montag, 4=Freitag)
|
|
start_time TEXT (HH:MM)
|
|
end_time TEXT (HH:MM)
|
|
type TEXT (lesson/break)
|
|
title TEXT
|
|
created_at DATETIME
|
|
```
|
|
|
|
#### Tabelle: `time_entries`
|
|
|
|
```sql
|
|
id INTEGER PRIMARY KEY
|
|
user_id INTEGER (FK -> users)
|
|
schedule_id INTEGER (FK -> schedules)
|
|
date TEXT (YYYY-MM-DD)
|
|
type TEXT (lesson/break/manual)
|
|
start_time TEXT
|
|
end_time TEXT
|
|
created_at DATETIME
|
|
```
|
|
|
|
#### Tabelle: `school_years`
|
|
|
|
```sql
|
|
id INTEGER PRIMARY KEY
|
|
name TEXT UNIQUE
|
|
start_date DATE
|
|
end_date DATE
|
|
is_active BOOLEAN DEFAULT 0
|
|
created_at DATETIME
|
|
```
|
|
|
|
#### Tabelle: `audit_logs`
|
|
|
|
```sql
|
|
id INTEGER PRIMARY KEY
|
|
user_id INTEGER
|
|
action TEXT
|
|
details TEXT
|
|
created_at DATETIME
|
|
```
|
|
|
|
### Stundenberechnung
|
|
|
|
Die Anwendung berechnet Arbeitsstunden nach folgenden Regeln:
|
|
|
|
1. **Unterrichtsstunden** (`type: "lesson"`): **1,0 Stunde** (fest)
|
|
2. **Pausen** (`type: "break"`): Differenz zwischen End- und Startzeit
|
|
3. **Manuelle Einträge** (`type: "manual"`):
|
|
- Positive Werte werden abgezogen
|
|
- Negative Werte werden hinzugerechnet
|
|
|
|
**Beispiel:**
|
|
|
|
```
|
|
Unterricht 08:00-09:00 → 1,0h
|
|
Pause 09:00-09:15 → 0,25h
|
|
Manueller Eintrag: 2.5 → -2,5h (Abzug)
|
|
Manueller Eintrag: -1.0 → +1,0h (Zuschlag)
|
|
```
|
|
|
|
### ISO-Kalenderwochen
|
|
|
|
Die Anwendung verwendet ISO 8601 Kalenderwochen:
|
|
|
|
- Woche beginnt am Montag
|
|
- Erste Woche des Jahres enthält den 4. Januar
|
|
- 52 oder 53 Wochen pro Jahr
|
|
|
|
## 🔒 Sicherheit
|
|
|
|
### Implementierte Sicherheitsmaßnahmen
|
|
|
|
1. **Passwort-Hashing**: bcrypt mit Default-Cost (10 Runden)
|
|
2. **JWT-Authentifizierung**: HMAC-SHA256 mit 2h Ablaufzeit
|
|
3. **CORS-Protection**: Konfigurierbare Origins
|
|
4. **Rate Limiting**: 5 Login-Versuche pro Minute pro IP
|
|
5. **SQL-Injection-Schutz**: Prepared Statements
|
|
6. **Admin-Schutz**: Admin-Benutzer (ID=1) kann nicht gelöscht werden
|
|
7. **Input-Validierung**: Server- und clientseitig
|
|
|
|
### Best Practices
|
|
|
|
1. **JWT_SECRET ändern**: Verwenden Sie einen starken, zufälligen String (64+ Zeichen)
|
|
|
|
```bash
|
|
openssl rand -base64 64
|
|
```
|
|
|
|
2. **HTTPS verwenden**: In Produktion immer TLS/SSL aktivieren
|
|
|
|
```env
|
|
ENVIRONMENT=production
|
|
```
|
|
|
|
3. **Regelmäßige Backups**: Sichern Sie die Datenbank täglich
|
|
|
|
4. **Starke Passwörter**: Mindestens 12 Zeichen, Mix aus Groß-/Kleinbuchstaben, Zahlen, Sonderzeichen
|
|
|
|
5. **Updates**: Halten Sie Dependencies aktuell
|
|
```bash
|
|
go get -u ./...
|
|
docker-compose pull
|
|
```
|
|
|
|
## 💾 Backup & Wartung
|
|
|
|
### Datenbank-Backup
|
|
|
|
**Docker-Setup:**
|
|
|
|
```bash
|
|
# Backup erstellen
|
|
docker exec school-timetracking sqlite3 /data/timetracking.db ".backup '/data/backup-$(date +%Y%m%d).db'"
|
|
docker cp school-timetracking:/data/backup-$(date +%Y%m%d).db ./backups/
|
|
|
|
# Backup wiederherstellen
|
|
docker cp ./backups/backup-20241108.db school-timetracking:/data/timetracking.db
|
|
docker-compose restart
|
|
```
|
|
|
|
**Lokales Setup:**
|
|
|
|
```bash
|
|
# Backup
|
|
sqlite3 timetracking.db ".backup 'backup-$(date +%Y%m%d).db'"
|
|
|
|
# Wiederherstellen
|
|
cp backup-20241108.db timetracking.db
|
|
```
|
|
|
|
### Automatisches Backup (Cron)
|
|
|
|
Erstellen Sie ein Backup-Script `backup.sh`:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
BACKUP_DIR="/path/to/backups"
|
|
DATE=$(date +%Y%m%d-%H%M%S)
|
|
|
|
docker exec school-timetracking sqlite3 /data/timetracking.db ".backup '/data/backup-$DATE.db'"
|
|
docker cp school-timetracking:/data/backup-$DATE.db $BACKUP_DIR/
|
|
|
|
# Alte Backups löschen (älter als 30 Tage)
|
|
find $BACKUP_DIR -name "backup-*.db" -mtime +30 -delete
|
|
```
|
|
|
|
Crontab-Eintrag (täglich um 3 Uhr):
|
|
|
|
```
|
|
0 3 * * * /path/to/backup.sh
|
|
```
|
|
|
|
### Log-Rotation
|
|
|
|
Docker Compose Log-Größe begrenzen:
|
|
|
|
```yaml
|
|
services:
|
|
timetracking:
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
```
|
|
|
|
### Updates durchführen
|
|
|
|
```bash
|
|
# Repository aktualisieren
|
|
git pull
|
|
|
|
# Neue Images bauen
|
|
docker-compose build
|
|
|
|
# Container neu starten
|
|
docker-compose down
|
|
docker-compose up -d
|
|
|
|
# Logs prüfen
|
|
docker-compose logs -f
|
|
```
|
|
|
|
## 🐛 Fehlerbehebung
|
|
|
|
### Anwendung startet nicht
|
|
|
|
**Problem**: Container startet nicht
|
|
|
|
```bash
|
|
docker-compose logs timetracking
|
|
```
|
|
|
|
**Häufige Ursachen:**
|
|
|
|
- `JWT_SECRET` nicht gesetzt → Setzen Sie die Variable in `.env`
|
|
- Port 8080 bereits belegt → Ändern Sie `PORT` in `.env`
|
|
- Datenbank-Berechtigungen → Prüfen Sie Volume-Permissions
|
|
|
|
### Login funktioniert nicht
|
|
|
|
**Problem**: "Invalid credentials" trotz korrekten Passworts
|
|
|
|
**Lösung:**
|
|
|
|
```bash
|
|
# Admin-Passwort zurücksetzen
|
|
docker exec -it school-timetracking /bin/sh
|
|
sqlite3 /data/timetracking.db
|
|
|
|
# In SQLite:
|
|
UPDATE users SET password = '$2a$10$...' WHERE username = 'admin';
|
|
.exit
|
|
```
|
|
|
|
Generieren Sie einen neuen bcrypt-Hash:
|
|
|
|
```bash
|
|
# Mit Go
|
|
echo -n 'neues-passwort' | go run -e 'import "golang.org/x/crypto/bcrypt"; pass, _ := bcrypt.GenerateFromPassword([]byte(os.Args[1]), bcrypt.DefaultCost); fmt.Println(string(pass))'
|
|
```
|
|
|
|
### Zeiteinträge werden nicht gespeichert
|
|
|
|
**Problem**: Fehler beim Speichern von Zeiteinträgen
|
|
|
|
**Prüfen:**
|
|
|
|
1. Browser-Konsole auf JavaScript-Fehler prüfen
|
|
2. Backend-Logs prüfen: `docker-compose logs -f`
|
|
3. JWT-Token gültig? → Neu anmelden
|
|
4. Datenbank-Speicherplatz verfügbar?
|
|
|
|
### PDF-Export schlägt fehl
|
|
|
|
**Problem**: "Failed to generate PDF"
|
|
|
|
**Lösung:**
|
|
|
|
```bash
|
|
# Container-Logs prüfen
|
|
docker-compose logs timetracking | grep -i pdf
|
|
|
|
# Häufig: Fehlende Schriftarten
|
|
# → Rebuilden Sie das Image
|
|
docker-compose build --no-cache
|
|
```
|
|
|
|
### Responsive Layout funktioniert nicht
|
|
|
|
**Problem**: Mobile Ansicht nicht korrekt
|
|
|
|
**Lösung:**
|
|
|
|
- Browser-Cache leeren
|
|
- Elm neu kompilieren:
|
|
```bash
|
|
cd static
|
|
elm make Main.elm --output=elm.js --optimize
|
|
```
|
|
|
|
### Datenbankfehler nach Update
|
|
|
|
**Problem**: "Database schema error"
|
|
|
|
**Lösung:**
|
|
|
|
```bash
|
|
# Backup erstellen
|
|
docker cp school-timetracking:/data/timetracking.db ./backup-pre-migration.db
|
|
|
|
# Migration manuell durchführen
|
|
docker exec -it school-timetracking sqlite3 /data/timetracking.db
|
|
|
|
# Fehlende Spalten hinzufügen (Beispiel)
|
|
ALTER TABLE users ADD COLUMN yearly_hours REAL DEFAULT 1800.0;
|
|
.exit
|
|
```
|
|
|
|
## 📝 Häufig gestellte Fragen (FAQ)
|
|
|
|
**Q: Wie ändere ich die Standard-Arbeitsstunden?**
|
|
A: Als Admin unter "Benutzer" → Benutzer auswählen → "Arbeitszeit" klicken → Neue Stundenzahl eingeben.
|
|
|
|
**Q: Können Mitarbeiter vergangene Wochen bearbeiten?**
|
|
A: Ja, über die Wochen-Navigation können alle Wochen bearbeitet werden (sofern im aktuellen Schuljahr).
|
|
|
|
**Q: Wie funktioniert die Schuljahr-Berechnung?**
|
|
A: Das System berechnet Stunden nur für Einträge innerhalb des aktiven Schuljahres (Start- bis Enddatum).
|
|
|
|
**Q: Was passiert bei 53-Wochen-Jahren?**
|
|
A: Das System unterstützt ISO-Kalenderwochen inklusive Woche 53 automatisch.
|
|
|
|
**Q: Kann ich mehrere Schuljahre parallel nutzen?**
|
|
A: Es kann immer nur ein Schuljahr aktiv sein. Berechnungen basieren auf diesem Zeitraum.
|
|
|
|
**Q: Wie funktionieren negative Stunden?**
|
|
A: Negative Werte bei manuellen Einträgen werden **zum** Stundenkonto **hinzugerechnet** (für Zusatzleistungen).
|
|
|
|
## 📄 Lizenz
|
|
|
|
Todo
|
|
|
|
## 👥 Kontakt & Support
|
|
|
|
Todo
|
|
|
|
---
|
|
|
|
**Version**: 1.0.0
|
|
**Letztes Update**: November 2024
|
|
**Entwickelt für**: Schulen zur Verwaltung von Flexistunden pädagogischer Mitarbeiter
|