Generiert HTML- und Bild-Reports aus Kimai Zeiterfassungsdaten.
- Tages-, Wochen-, Monats- und Jahresberichte
- Matrix-Darstellung: Personen x Projekte
- HTML-Reports mit Open Graph Meta-Tags (Vorschau in Discord/Telegram/etc.)
- PNG-Bilder der Reports
- Geheime URLs (nicht erratbar)
- Discord Webhook Benachrichtigungen
- Batch-Generierung aller fehlenden Reports
# Repository klonen
git clone <repository-url>
cd stundenzettel
# Dependencies installieren
npm install
# Konfiguration erstellen
cp .env.template .envBearbeite die .env Datei:
# Erforderlich
KIMAI_URL=https://kimai.example.com
KIMAI_API_TOKEN=dein-api-token
# Optional: Basis-URL für absolute Links und Open Graph
BASE_URL=https://example.com
# Optional: Discord Webhook (erfordert BASE_URL)
DISCORD_WEBHOOK=https://discord.com/api/webhooks/...- In Kimai einloggen
- Profil -> API-Zugriff
- Neuen Token erstellen
- Token in
.enveintragen
# Tagesbericht
npm run dev -- d 2025-01-26
# Wochenbericht (KW 5, 2025)
npm run dev -- w 5 2025
# Monatsbericht (Januar 2025)
npm run dev -- m 1 2025
# Jahresbericht
npm run dev -- y 2025npm run generate-all -- 2025-01-01Generiert alle fehlenden Reports vom Startdatum bis heute (nur abgeschlossene Zeiträume).
Die folgende Konfiguration liefert den reports/ Ordner unter https://example.com/reports/ aus:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Reports ausliefern
location /reports/ {
alias /pfad/zu/stundenzettel/reports/;
# Verzeichnislisting deaktivieren (Sicherheit)
autoindex off;
# Cache-Header für Bilder
location ~* \.(png|jpg|jpeg|gif)$ {
expires 7d;
add_header Cache-Control "public, immutable";
}
# HTML ohne Cache (für aktuelle Open Graph Daten)
location ~* \.html$ {
expires 1h;
add_header Cache-Control "public";
}
}
}Nginx neu laden:
nginx -t && nginx -s reload- Crontab bearbeiten:
crontab -e- Cronjob hinzufügen (täglich um 02:00 Uhr):
# Kimai Reports generieren (täglich um 02:00)
0 2 * * * cd /pfad/zu/stundenzettel && /usr/bin/npm run generate-all -- 2025-01-01 >> /var/log/kimai-reports.log 2>&1Alternativ mit explizitem Node-Pfad:
0 2 * * * cd /pfad/zu/stundenzettel && PATH=/usr/local/bin:$PATH npm run generate-all -- 2025-01-01 >> /var/log/kimai-reports.log 2>&1- Crond starten (falls nicht aktiv):
# Crond starten
rc-service crond start
# Crond beim Boot starten
rc-update add crond- Log-Datei erstellen:
touch /var/log/kimai-reports.log
chmod 644 /var/log/kimai-reports.log# Manuell ausführen
cd /pfad/zu/stundenzettel && npm run generate-all -- 2025-01-01
# Cronjob-Logs prüfen
tail -f /var/log/kimai-reports.logstundenzettel/
├── src/
│ ├── kimai-report.ts # Haupt-Script
│ └── generate-all.ts # Batch-Generierung
├── reports/
│ ├── daily/ # Tagesberichte
│ │ └── 2025-01-26_<secret>/
│ │ ├── report.html
│ │ └── report.png
│ ├── weekly/ # Wochenberichte
│ ├── monthly/ # Monatsberichte
│ └── yearly/ # Jahresberichte
├── .env # Konfiguration (nicht committen!)
├── .env.template # Konfigurations-Vorlage
├── package.json
└── tsconfig.json
Der Kimai-Benutzer benötigt folgende Berechtigung, um alle Zeiteinträge zu sehen:
view_other_timesheet
Diese kann unter System -> Rollen aktiviert werden.
Für eine korrekte Bildgenerierung:
apk add fontconfig ttf-freefont
fc-cache -f
Dependencies für npm install
apk add --no-cache \
nodejs \
npm \
python3 \
make \
g++ \
cairo-dev \
jpeg-dev \
pango-dev \
giflib-dev \
pixman-dev