Synaplan
Open-source AI platform for companies: self-hosted AI agents, GDPR-compliant chatbot widget, RAG knowledge base, WhatsApp and Outlook AI, MCP, multi-model routing. Docker, Kubernetes or hosted in Germ
Termine planen, Zusagen einholen, Anwesenheit und ehrenamtliche Arbeitszeit erfassen: für Vereine, quelloffen und selbst gehostet.
Translation pending
BusinessPHP · JavaScriptGitHub @mcmaierOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Zeit- und Anwesenheitserfassung fürs Ehrenamt (Vereine und Co)
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Moderne Zeit- und Anwesenheitserfassung für ehrenamtliche Organisationen Entwickelt für gemeinnützige Organisationen, wie z.B. Musikvereine, Sportvereine, ... Kostenlos unter AGPL-3.0 nutzbar. Einsatz ist EhrenSache! Und jetzt einfach und überall erfassbar ohne Zettel und Stift. Egal ob jeder sich eigenverantwortlich anmeldet oder der Schriftführer die Anwesenheit prüft. EhrenSache ermöglicht Terminplanung, erfasst Anwesenheit und Entschuldigungen inklusive nachträglicher Korrekturmöglichkeit und kann auch Arbeitszeiten messen.Read the full README ↗
Moderne Zeit- und Anwesenheitserfassung für ehrenamtliche Organisationen
Entwickelt für gemeinnützige Organisationen, wie z.B. Musikvereine, Sportvereine, ... Kostenlos unter AGPL-3.0 nutzbar.
💼 Kommerziell nutzen? Siehe Lizenzierung
Einsatz ist EhrenSache!
Und jetzt einfach und überall erfassbar ohne Zettel und Stift. Egal ob jeder sich eigenverantwortlich anmeldet oder der Schriftführer die Anwesenheit prüft. EhrenSache ermöglicht Terminplanung, erfasst Anwesenheit und Entschuldigungen inklusive nachträglicher Korrekturmöglichkeit und kann auch Arbeitszeiten messen.
Jeder kann seine Statistik einsehen und prüfen, ob alles erfasst wurde. Inklusive Ankunftszeit, für alle die Pünktlichkeit belohnen wollen.
X-Content-Type-Options, X-Frame-Options, Referrer-Policy[!NOTE] Alle Oberflächen außer den Assistenten für Installation und Update liefern eine Content-Security-Policy aus (
script-src 'self', die öffentlichen Seiten ohne jedes Skript). Eingeschleustes Skript wird dadurch auch dann nicht ausgeführt, wenn es an der Maskierung vorbei ins Markup gelangt. Hintergrund: OI-17 in docs/OPEN-ITEMS.md.
EhrenSache verarbeitet personenbezogene Daten. Als Betreiber sind Sie Verantwortlicher im Sinne der DSGVO und müssen eigenständig für datenschutzkonforme Nutzung sorgen.
Betreiber-Pflichten:
Der Entwickler:
📄 Ausführliche Informationen: DATENSCHUTZ.md
⚖️ Haftungsausschluss: DISCLAIMER.md
Konsultieren Sie vor Inbetriebnahme einen Datenschutzbeauftragten oder Fachanwalt für IT-Recht, um die DSGVO-Konformität sicherzustellen.
Backend:
public/api/api.php)Frontend:
/checkin/) und virtuelle Station (/station/)IoT-Integration (WIP):
requires in version.json; Installer und
Update-Assistent prüfen sieHeader … setifempty) mit mod_headers; AllowOverride muss
die Header-Direktiven zulassen (FileInfo). Ohne mod_headers fehlen die Sicherheits-Header samt
Content-Security-Policy aus den .htaccess-Dateien stillmod_deflate und mod_filter. Damit kommen CSS, JS und HTML komprimiert an
(beim ersten Aufruf des Dashboards rund 210 statt 870 KB). Ohne die Module läuft alles,
nur langsamer im MobilfunkPaket besorgen — für den Betrieb die veröffentlichte Version:
⬇ Aktuelle Version herunterladen
Der Link führt immer auf das neueste Release. Wer mitentwickeln will, klont stattdessen:
git clone https://github.com/mcmaier/EhrenSache.git
Der Klon liefert denselben Stand — der Arbeitsstand liegt auf dem Branch dev und ist
nicht für den Betrieb gedacht.
[!WARNING] Die Web-Root der (Sub-)Domain muss auf den Ordner EhrenSache/public zeigen!
Ggf. Neue Datenbank erstellen.
Installer freischalten: Inhalt von public/install/.htaccess leeren oder die Datei umbenennen.
[!NOTE] Der Installer wird gesperrt ausgeliefert, damit er auf einem hochgeladenen, aber noch nicht eingerichteten Webspace nicht offen im Netz steht. Ohne diesen Schritt antwortet der Server mit
403 Forbidden. Nach abgeschlossener Installation sperrt sich der Installer automatisch wieder.
https://ehrensache.meine-domain.de/install
Während der Installation wird ein Admin-Account erstellt.
Siehe DATENSCHUTZ.md für Checkliste und Muster-Texte.
Ab 1.6.0 kann der Update-Assistent das Paket selbst von GitHub holen. Der Weg von Hand bleibt unverändert möglich — der Assistent prüft vorher, ob er die Dateien schreiben darf, und nennt den Grund, wenn nicht.
Jede Version lässt sich direkt von jedem älteren Stand aus einspielen — ein Zwischenschritt über eine bestimmte Version ist nicht nötig. Für den Weg über GitHub braucht die Installation einmal eine Version ab 1.6.0; auch dieser eine Upload von Hand kann gleich die neueste sein.
Update-Wizard freischalten: Inhalt von public/update/.htaccess leeren oder die Datei löschen.
Update-Wizard aufrufen:
https://ehrensache.meine-domain.de/update
Schritt 0 — Dateien: „Neueste Version abfragen", dann „Update einspielen". Der Assistent
lädt das Paket, prüft es und die Migrationskette, sichert jede ersetzte Datei nach
private/backup/ und tauscht die Dateien. Die Anwendung ist dabei einige Sekunden im
Wartungsmodus. Scheitert ein Schritt, spielt er die Sicherung zurück.
Von Hand stattdessen: Aktuelle Version herunterladen,
die Dateien auf den Server hochladen (bestehende überschreiben) und im Assistenten
„Dateien bereits hochgeladen" wählen. public/index.html und public/login.html dabei
zuletzt hochladen: Sie verweisen auf CSS und JS der neuen Version, und wer sie vorher
aufruft, bekäme alte Dateien unter der neuen Adresse — die dann lange im Browser liegen
bleiben. Der Assistent hält diese Reihenfolge beim Tausch selbst ein.
[!WARNING] Beim Hochladen von Hand
private/config/config.phpnicht überschreiben – sie enthält die Zugangsdaten der Installation! Der Assistent lässt sie beim Tausch unberührt.
Nach erfolgter Migration sperrt sich der Wizard automatisch wieder.
[!WARNING] Cloudflare als Proxy kann einen knapp bemessenen Hoster überlasten. Viele günstige Hoster sprechen direkt nur HTTP/1.1. Dabei öffnet der Browser höchstens sechs Verbindungen gleichzeitig, und die rund 50 Dateien des Dashboards kommen in Schüben. Hinter dem Proxy von Cloudflare (orange Wolke) spricht der Browser HTTP/2 und fordert alle Dateien auf einmal an. Fehlen sie im Zwischenspeicher von Cloudflare, etwa nach einem Update oder nach einer ruhigen Nacht, reicht Cloudflare die ganze Welle gleichzeitig an den Server weiter. Ein Hoster, der nur wenige gleichzeitige Anfragen zulässt, antwortet dann mit
503 Service Unavailable. Das Dashboard erscheint ungestylt oder leer, in der Browser-Konsole stehen Meldungen wie „Refused to apply style … MIME type ('text/html')“.Prüfen: die Seite einmal ohne Cloudflare aufrufen und in den Entwicklerwerkzeugen (Netzwerk, Spalte „Protokoll“) nachsehen. Steht dort
http/1.1, betrifft es diese Installation. Einfachste Abhilfe: den DNS-Eintrag in Cloudflare auf „DNS only“ (graue Wolke) stellen. Der Hoster braucht dann ein eigenes gültiges Zertifikat, undtrusted_proxies(unten) bleibt leer. Wer den Proxy behalten will, richtet den Zwischenspeicher wie unten beschrieben ein. Ganz verhindern lässt sich die Welle damit aber nicht.
[!TIP] Läuft die Installation hinter Cloudflare (oder einem anderen CDN), bleibt nach einem Update sonst bis zu vier Stunden altes CSS und JS im Browser: Das Dashboard erscheint ungestylt, oder Knöpfe tun nichts. EhrenSache verlangt für CSS und JS eine Nachfrage vor jeder Verwendung (
no-cache), Cloudflare ersetzt das in der Voreinstellung durch vier Stunden. In Cloudflare zwei Einstellungen, beide nötig:
- Caching → Configuration: Browser Cache TTL auf „Respect Existing Headers“ — der Browser fragt dann vor jeder Verwendung nach, aber bei Cloudflare.
- Caching → Cache Rules: eine Regel für die Dateiendungen
cssundjsmit Edge TTL „Ignore cache-control header“, mehrere Wochen (etwa 1 Monat); Browser TTL bleibt „Respect origin“. Bei nur einem Tag läuft der Zwischenspeicher auf wenig besuchten Installationen jede Nacht ab. Fehlerantworten (Statuscodes 500–599) in derselben Regel nicht zwischenspeichern. Ohne diese Regel reicht Cloudflare jede Nachfrage an den Server durch — rund 45 gleichzeitige Anfragen je Seitenaufruf, die günstige Hoster mit503 Service Unavailableabweisen; das Dashboard bleibt dann leer.- Caching → Tiered Cache: Smart Tiered Caching einschalten (kostenlos). Ein Standort von Cloudflare, dessen Zwischenspeicher leer ist, fragt dann zuerst einen zentralen Knoten statt den Server. Bei wenig besuchten Installationen verdrängt Cloudflare Dateien nämlich lange vor Ablauf der Edge TTL.
Nach jedem Update „Purge Everything“ auslösen. Wer den alten Stand schon im Browser hat, lädt einmal mit Strg+F5 neu. Dashboard und Anmeldeseite laden CSS und JS zwar unter einer Adresse mit der Version (
css/v<Version>/…), ein Update erzeugt also neue Adressen. Ruft aber während des Dateitauschs jemand auf, kann Cloudflare eine alte Datei unter der neuen Adresse speichern — der Purge räumt das ab.Außerdem in
private/config/config.phpuntertrusted_proxiesdie Adressbereiche von Cloudflare eintragen (cloudflare.com/ips). Sonst sieht EhrenSache statt der Besucher nur Cloudflare, und der Rate Limiter zählt alle Besucher gemeinsam. Vorlage und Beispiel inprivate/config/config_example.php.
[!NOTE] Bei Update von v1.0.0 → v1.1.x: Der Wizard ergänzt
config.phpautomatisch um das Prefix-Feld und benennt alle Tabellen entsprechend um. Es ist kein manueller Eingriff in die Konfiguration nötig.
[!NOTE] Bei Update auf v1.6.0: Der Wizard stellt
config.phpauf eine reine Datendatei um und legt vorher die Sicherungconfig.php.bak-1.5.1daneben. Nach einer erfolgreichen Anmeldung kann sie gelöscht werden — sie enthält die Zugangsdaten. Kann der Wizard die Datei nicht schreiben, läuft die Installation unverändert weiter, und das Dashboard weist Administratoren darauf hin.
EhrenSache fragt nicht von selbst nach Updates. In den Einstellungen gibt es unter „Updates" einen Knopf, der auf Wunsch GitHub fragt. Zuverlässig benachrichtigt wirst du, wenn du auf GitHub die Releases des Projekts abonnierst: Watch → Custom → Releases.
Dashboard-Zugriff:
Mitglieder verwalten:
Termine erstellen:
Anwesenheit prüfen:
Geräte verwalten:
public/station/README.mdManager haben eingeschränkten Zugriff:
Web-Dashboard:
Check-in Mobile (PWA):
Check-in an der virtuellen Station:
public/station/README.mdCheck-in NFC/IoT (geplant)
Ausnahmen beantragen:
Termine zu- oder absagen:
Seit Version 1.2.0 kann EhrenSache neben der Anwesenheit auch geleistete Arbeitszeit erfassen — gedacht für Vereine, die Arbeitsstunden nachweisen oder abrechnen müssen.
Die Funktion ist standardmäßig aus. Solange sie aus ist, werden keinerlei Arbeitszeitdaten erhoben, und der Bereich taucht in der Oberfläche nicht auf.
Einschalten: Dashboard → Einstellungen → Zeiterfassung → Zeiterfassung aktivieren. Dort lassen sich außerdem die maximale Dauer einer Sitzung und eine Notizpflicht festlegen.
Danach:
/station/) — Tablet statt ESP32public/.htaccess leitet seit 1.4.0 selbst auf
HTTPS um. Die Regel überspringt bewusst drei Fälle, damit sie keine Endlosschleife erzeugt:
TLS-Terminierung am Proxy (X-Forwarded-Proto), Port 443 und localhost für die lokale
Entwicklung. Wer die Umleitung nicht will, kommentiert den Block aus — beim nächsten Update
ist er allerdings wieder aktiv, weil die Datei zum Paket gehörtSicherheitslücke gefunden? Bitte kein öffentliches Issue eröffnen, sondern den Meldeweg in SECURITY.md nutzen. Bekannte, bewusst offene Punkte sind in docs/OPEN-ITEMS.md dokumentiert.
# XAMPP oder ähnliches installieren
# Projekt nach htdocs/ kopieren
# Datenbank erstellen
# In Browser: http://localhost/EhrenSache/public
EhrenSache/
├── version.json # Version und Build-Datum
├── private/ # Interne Dateien -- nie öffentlich erreichbar!
| ├── config/ # Zugangsdaten, Mail-Konfiguration
| ├── handlers/ # API-Endpunkt-Handler, je Ressource eine Datei
| ├── helpers/ # Auth, Arbeitszeit, Station, Mailer, TOTP
| ├── migrations/ # Update-Kette von Version zu Version
| ├── setup/ # Datenbankschema
| └── ...
└── public/ # Öffentlich zugänglich <-- Web Root!
├── api/ # REST-API, einziger Einstiegspunkt
├── checkin/ # PWA für den mobilen Check-in
├── station/ # PWA für die virtuelle Station (Kiosk)
├── install/ # Setup-Assistent (nach Installation gesperrt)
├── update/ # Update-Assistent (nach Migration gesperrt)
├── js/ # Frontend-JavaScript (ES6-Module)
├── css/ # Stylesheets
├── ...
└── index.html # Hauptanwendung
Das System verwendet ein jahresbasiertes Caching:
dataCache in public/js/modules/ui.js) und ist
nach jedem Neuladen leer — kein localStorageSiehe API Dokumentation
| Datei | Inhalt |
|---|---|
| CHANGELOG.md | Was sich in welcher Version geändert hat |
| API.md | Vollständige REST-Referenz |
| SECURITY.md | Meldeweg für Sicherheitslücken, unterstützte Versionen |
| DATENSCHUTZ.md | DSGVO-Pflichten, Löschfristen, Betroffenenrechte |
| DISCLAIMER.md | Haftungsausschluss |
| public/checkin/README.md | Check-in-PWA einrichten |
| public/station/README.md | Virtuelle Station (Kiosk) einrichten |
Bei Fragen oder Problemen bitte ein Issue auf GitHub erstellen.
EhrenSache ist unter einer dualen Lizenz verfügbar:
Gemeinnützige Vereine, Musikvereine, Sportvereine und andere ehrenamtliche Organisationen können EhrenSache kostenlos unter der AGPL-3.0-Lizenz nutzen.
Das bedeutet:
Für kommerzielle Nutzung ohne Offenlegungspflicht gemäß AGPL ist eine Kommerzielle Lizenz erforderlich.
Wann brauche ich eine kommerzielle Lizenz?
Lizenzmodelle:
Wir bieten flexible Einmal- und Jahreslizenzen, abgestimmt auf Ihr
Geschäftsmodell. Kontaktieren Sie uns für ein individuelles Angebot.
Copyright (c) 2026 Martin Maier
Made with ❤️ for the volunteer community