This commit is contained in:
2026-07-11 18:21:33 +02:00
parent cbea23083d
commit 92d94f1c95
129 changed files with 85783 additions and 11294 deletions
-322
View File
@@ -1,322 +0,0 @@
# Deployment Guide: Netcup Webspace & Code-Server Proxy
Diese Anleitung erklärt, wie die Kaffeekasse-SaaS-Anwendung sowohl auf einem Netcup Webspace als auch über code-server Proxy-Weiterleitung betrieben werden kann.
## Übersicht
Die Anwendung ist so entwickelt, dass sie automatisch erkennt, ob sie:
1. **Direkt** auf einem Webspace läuft (z.B. `https://example.com/`)
2. **Hinter einem Reverse Proxy** läuft (z.B. `https://code-server.example.com/proxy/8080/`)
## 1. Deployment auf Netcup Webspace
### Voraussetzungen
- PHP 8.0 oder höher
- MySQL/MariaDB Datenbank
- Apache mit mod_rewrite aktiviert
- HTTPS-Zertifikat (Let's Encrypt empfohlen)
### Schritte
1. **Dateien hochladen**
```bash
# Via FTP/SFTP alle Dateien hochladen
# Document Root sollte auf /public/ zeigen
```
2. **.env Datei konfigurieren**
```bash
cp .env.example .env
nano .env
```
Wichtige Einstellungen:
```env
APP_URL=https://ihre-domain.de
APP_BASE_PATH=
DB_HOST=localhost
DB_NAME=ihre_datenbank
DB_USER=ihr_benutzer
DB_PASS=ihr_passwort
MAIL_FROM=noreply@ihre-domain.de
PASSWORD_RESET_URL=https://ihre-domain.de/reset-password?token={{token}}
```
3. **Verzeichnisrechte setzen**
```bash
chmod 755 storage/
chmod 755 storage/cache/
chmod 755 storage/logs/
chmod 755 storage/uploads/
```
4. **Installation durchführen**
- Besuchen Sie `https://ihre-domain.de/install`
- Folgen Sie dem Setup-Assistenten
### Apache Virtual Host Konfiguration (falls nötig)
```apache
<VirtualHost *:443>
ServerName ihre-domain.de
DocumentRoot /var/www/kaffeekasse/public
<Directory /var/www/kaffeekasse/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# SSL Konfiguration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/ihre-domain.de/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/ihre-domain.de/privkey.pem
</VirtualHost>
```
## 2. Deployment mit Code-Server Proxy
### Voraussetzungen
- Code-Server läuft und ist erreichbar
- PHP 8.0+ CLI verfügbar
- SQLite oder MySQL/MariaDB
### Schritte
1. **.env Datei konfigurieren**
```env
APP_URL=http://localhost:8080
APP_BASE_PATH=/proxy/8080
# Für SQLite (einfacher für Entwicklung)
DB_HOST=sqlite
DB_NAME=/config/workspace/kaffeeliste-neustart/storage/database.sqlite
# Oder MySQL
DB_HOST=127.0.0.1
DB_NAME=kaffeekasse
DB_USER=root
DB_PASS=
```
2. **PHP Development Server starten**
```bash
cd /config/workspace/kaffeeliste-neustart
php -S 0.0.0.0:8080 -t public public/router.php
```
3. **Zugriff über Code-Server Proxy**
- Die Anwendung ist nun erreichbar über:
`https://ihr-code-server.de/proxy/8080/`
- Code-Server setzt automatisch den Header `X-Forwarded-Prefix`
- Die Anwendung erkennt dies und passt alle URLs an
### Automatischer Start (Optional)
Erstellen Sie ein Systemd-Service oder Screen-Session:
```bash
# Screen-Session
screen -dmS kaffeekasse bash -c 'cd /config/workspace/kaffeeliste-neustart && php -S 0.0.0.0:8080 -t public public/router.php'
# Später wieder verbinden
screen -r kaffeekasse
```
## 3. Wie funktioniert die automatische Erkennung?
### Base Path Detection
Die Funktion `base_path()` in `app/Support/helpers.php` prüft in dieser Reihenfolge:
1. **`$_SERVER['KAFFEEKASSE_PROXY_PREFIX']`** - Manuell gesetzter Prefix
2. **`$_SERVER['HTTP_X_FORWARDED_PREFIX']`** - Von Code-Server gesetzt
3. **`$_ENV['APP_BASE_PATH']`** - Aus .env Datei
```php
function base_path(): string
{
foreach ([
$_SERVER['KAFFEEKASSE_PROXY_PREFIX'] ?? null,
$_SERVER['HTTP_X_FORWARDED_PREFIX'] ?? null,
$_ENV['APP_BASE_PATH'] ?? null,
] as $prefix) {
$prefix = trim((string) $prefix);
if ($prefix !== '') {
return normalize_base_path($prefix);
}
}
return '';
}
```
### URL-Generierung
Alle URLs werden dynamisch generiert:
```php
// Beispiele
url('/') // → / oder /proxy/8080/
url('/admin/login') // → /admin/login oder /proxy/8080/admin/login
tenant_url('standort1', 'bookings') // → /t/standort1/bookings oder /proxy/8080/t/standort1/bookings
asset_url('app.css') // → /assets/app.css oder /proxy/8080/assets/app.css
```
### .htaccess Proxy-Unterstützung
Die `.htaccess` leitet HTTPS-Informationen vom Proxy weiter:
```apache
# Proxy-Unterstützung: X-Forwarded-* Header durchreichen
RewriteCond %{HTTP:X-Forwarded-Proto} ^https$
RewriteRule ^ - [E=HTTPS:on]
```
## 4. Troubleshooting
### Problem: URLs zeigen auf falschen Pfad
**Lösung:** Prüfen Sie die Base Path Detection:
```php
// Temporär in public/index.php hinzufügen zum Debuggen
var_dump([
'base_path' => base_path(),
'current_path' => current_path(),
'KAFFEEKASSE_PROXY_PREFIX' => $_SERVER['KAFFEEKASSE_PROXY_PREFIX'] ?? null,
'HTTP_X_FORWARDED_PREFIX' => $_SERVER['HTTP_X_FORWARDED_PREFIX'] ?? null,
'APP_BASE_PATH' => $_ENV['APP_BASE_PATH'] ?? null,
]);
```
### Problem: CSS/Assets werden nicht geladen
**Ursache:** Base Path wird nicht korrekt erkannt
**Lösung:** Setzen Sie `APP_BASE_PATH` explizit in der `.env`:
```env
# Für Code-Server Proxy auf Port 8080
APP_BASE_PATH=/proxy/8080
# Für Subdirectory-Installation
APP_BASE_PATH=/kaffeekasse
```
### Problem: Formular-Submissions funktionieren nicht
**Ursache:** CSRF-Token oder falsche Action-URLs
**Lösung:**
1. Prüfen Sie, ob Sessions funktionieren
2. Stellen Sie sicher, dass alle Forms `<?= csrf_field($csrf) ?>` enthalten
3. Verwenden Sie immer `url()` oder `tenant_url()` für Action-Attribute
### Problem: Redirect-Loops
**Ursache:** Proxy-Header werden nicht korrekt weitergeleitet
**Lösung für Nginx Reverse Proxy:**
```nginx
location /proxy/8080/ {
proxy_pass http://localhost:8080/;
proxy_set_header X-Forwarded-Prefix /proxy/8080;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
```
## 5. Sicherheitshinweise
### Für Netcup Webspace
1. **HTTPS erzwingen** - Fügen Sie in `.htaccess` hinzu:
```apache
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
```
2. **Verzeichnisse schützen**
- Stellen Sie sicher, dass nur `/public` öffentlich erreichbar ist
- Dateien außerhalb von `/public` sollten nicht direkt aufrufbar sein
3. **APP_KEY setzen**
```bash
# Generieren Sie einen sicheren Key
php -r "echo bin2hex(random_bytes(32)) . PHP_EOL;"
```
### Für Code-Server
1. **Nicht für Production verwenden**
- Code-Server Proxy ist für Entwicklung gedacht
- Für Production: Netcup Webspace oder dedizierter Server
2. **Zugriffsbeschränkung**
- Schützen Sie Code-Server mit starkem Passwort
- Verwenden Sie HTTPS
- Beschränken Sie IP-Zugriff wenn möglich
## 6. Migrations-Checkliste
### Von Code-Server zu Netcup
- [ ] Datenbank exportieren (falls SQLite → MySQL)
- [ ] `.env` Datei anpassen (APP_URL, APP_BASE_PATH, DB_*)
- [ ] Dateien via FTP/SFTP hochladen
- [ ] Verzeichnisrechte setzen
- [ ] Datenbank importieren
- [ ] Installation testen
- [ ] HTTPS-Zertifikat einrichten
- [ ] Cron-Jobs einrichten (falls benötigt)
### Von Netcup zu Code-Server
- [ ] Datenbank exportieren
- [ ] `.env` Datei anpassen (APP_BASE_PATH=/proxy/8080)
- [ ] PHP Development Server starten
- [ ] Über Proxy-URL testen
## 7. Performance-Optimierung
### Für Netcup Webspace
1. **OPcache aktivieren** (php.ini):
```ini
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
```
2. **Session-Speicher optimieren**:
```ini
session.save_handler=files
session.save_path=/tmp
```
### Für Code-Server
1. **SQLite für Entwicklung**:
- Schneller Setup
- Keine separate Datenbank nötig
- Gut für Tests
2. **Development Server Optionen**:
```bash
# Mit mehr Workers
php -S 0.0.0.0:8080 -t public public/router.php
```
## Support
Bei Problemen:
1. Prüfen Sie die Logs in `storage/logs/`
2. Aktivieren Sie Debug-Modus: `APP_DEBUG=1` in `.env`
3. Prüfen Sie PHP Error Logs
4. Konsultieren Sie die Hauptdokumentation in `DEPLOY.md`
-222
View File
@@ -1,222 +0,0 @@
# Go-Live-Checkliste fuer Netcup Webspace
Diese Checkliste ist fuer den ersten echten Betrieb auf Netcup Webspace gedacht.
Sie baut auf [DEPLOY.md](/config/workspace/kaffeeliste-neustart/DEPLOY.md),
[RUNBOOK.md](/config/workspace/kaffeeliste-neustart/RUNBOOK.md) und
[docs/production-blueprint.md](/config/workspace/kaffeeliste-neustart/docs/production-blueprint.md)
auf, ist aber absichtlich strenger und operativer.
## 1. Go-Live-Scope festziehen
- [ ] Entscheiden, ob der erste Livegang ein geschlossener Pilot oder ein oeffentliches SaaS-Launch ist.
- [ ] Fuer einen oeffentlichen Launch Registrierung absichern oder vorerst deaktivieren.
Das Repo nennt Mail-Verifikation, Passwort-Reset und Rate-Limits selbst als offene Punkte vor echtem Go-Live.
- [ ] Falls diese Punkte noch fehlen: nur mit eingeladenen Testkunden oder manuell freigeschalteten Mandanten live gehen.
- [ ] Einen Release-Owner und einen Restore-Owner benennen.
- [ ] Ein Wartungsfenster fuer den Erststart und fuer kuenftige Releases definieren.
## 2. Environment-Modell festlegen
Empfehlung fuer Netcup Webspace:
- [ ] `local`: Entwicklung lokal.
- [ ] `staging`: echte Netcup-Subdomain wie `staging.example.tld`, eigene DB, eigene `.env`.
- [ ] `production`: produktive Domain, eigene DB, eigene `.env`.
Pragmatisches Verzeichnislayout ohne Root-Zwang:
- [ ] `staging` unter `/apps/kaffeekasse-stage/current`
- [ ] `production` unter `/apps/kaffeekasse/current`
- [ ] Offsite- oder Backup-Artefakte nicht im Webroot ablegen.
Wichtig fuer dieses Repo:
- [ ] `public/` bleibt der einzige Webroot.
- [ ] `.env` wird aus dem Projektwurzelverzeichnis geladen.
- [ ] Der Browser-Installer schreibt `.env` in das Projektwurzelverzeichnis und `storage/installed.lock` in `storage/`.
- [ ] `bin/cron.php` schreibt `storage/cron.lock`.
- [ ] Deshalb muessen Projektwurzel und `storage/` mindestens fuer den Deployment-User, besser auch fuer den Webspace-User, sauber beschreibbar sein.
## 3. Netcup vorbereiten
- [ ] Domain oder Subdomain im CCP/WCP anlegen.
- [ ] DNS frueh setzen und Aufloesung pruefen.
- [ ] In Plesk/WCP pro Environment eine eigene Site mit eigenem Document Root anlegen.
- [ ] Document Root fuer jedes Environment auf `.../current/public` setzen.
- [ ] Pro Environment eine eigene MySQL-Datenbank und einen eigenen DB-User anlegen.
- [ ] PHP-Version im WCP fest auf 8.3 oder 8.4 pinnen und nicht auf "System Default" lassen.
- [ ] Dieselbe PHP-Hauptversion fuer Web und CLI verwenden.
## 4. Secrets und Konfiguration vorbereiten
Pflichtwerte laut App:
- [ ] `APP_URL`
- [ ] `APP_ENV`
- [ ] `APP_DEBUG=0`
- [ ] `APP_TIMEZONE`
- [ ] `APP_KEY`
- [ ] `DB_HOST`
- [ ] `DB_PORT`
- [ ] `DB_NAME`
- [ ] `DB_USER`
- [ ] `DB_PASS`
- [ ] `RFID_SHARED_SECRET`
Empfehlung:
- [ ] `staging` und `production` nie dieselben Secrets oder dieselbe DB teilen.
- [ ] Admin-Zugang fuer die Plattform separat dokumentieren und im Passwortsafe ablegen.
- [ ] Wenn der Browser-Installer verwendet wird: danach `.env` sichern und offsite ablegen.
- [ ] Wenn `.env` manuell gepflegt wird: `.env` vor dem ersten Deploy lokal erzeugen und erst dann hochladen.
## 5. Erstes Staging-Deployment
- [ ] Lokal oder in CI `scripts/build-release.sh` ausfuehren.
- [ ] Release-Artefakt sicher ablegen. Es ist Teil des Rollback-Pfads.
- [ ] Artefakt per FTPES oder SFTP nach Netcup hochladen.
- [ ] Paket in den festen Environment-Pfad entpacken.
- [ ] Pruefen, dass `.env`, `storage/uploads`, `storage/logs` und `storage/cache` nicht versehentlich ueberschrieben oder geloescht wurden.
Das Build-Skript schliesst diese Pfade aus dem Release aus.
- [ ] Falls der Browser-Installer genutzt wird: `/install` nur auf `staging` einmal durchlaufen.
- [ ] Falls manuell installiert wird: `.env` hochladen und danach
`/usr/local/php83/bin/php /apps/kaffeekasse-stage/current/bin/migrate.php`
oder die zu eurer PHP-Version passende Binary ausfuehren.
- [ ] Pruefen, dass `storage/installed.lock` angelegt wurde.
## 6. Staging-Smoketest vor Production
- [ ] Startseite laden.
- [ ] `/admin/login` erfolgreich testen.
- [ ] Einen Test-Mandanten anlegen.
- [ ] Tenant-Login pruefen.
- [ ] Eine Testbuchung und eine Test-Einzahlung anlegen.
- [ ] `/usr/local/php83/bin/php /apps/kaffeekasse-stage/current/bin/healthcheck.php` ausfuehren und JSON pruefen.
- [ ] `/usr/local/php83/bin/php /apps/kaffeekasse-stage/current/bin/cron.php` manuell ausfuehren.
- [ ] Pruefen, dass `cron.lock` nach dem Lauf wieder verschwindet.
## 7. SSL und HTTPS
- [ ] Erst SSL ausrollen, wenn DNS sauber auf Netcup zeigt.
- [ ] Im WCP fuer jede produktive Domain ein Let's-Encrypt-Zertifikat ausstellen.
- [ ] `www` nur dann mit absichern, wenn `www` auch wirklich genutzt werden soll.
- [ ] Fuer den ersten Go-Live kein Wildcard-Zertifikat verwenden, wenn es nicht zwingend noetig ist.
Bei Netcup werden Wildcard-Zertifikate nicht automatisch erneuert.
- [ ] HTTPS fuer die produktive Domain erzwingen.
- [ ] Nach Aktivierung pruefen, dass alle Logins und Formulare nur noch ueber HTTPS laufen.
- [ ] Session-Cookies unter HTTPS pruefen, weil `secure` in der App vom HTTPS-Kontext abhaengt.
## 8. Backup-Strategie produktionsreif machen
Minimum:
- [ ] Taegliches DB-Backup einrichten.
- [ ] Vor jedem Release ein frisches manuelles DB-Backup ziehen.
- [ ] `.env` offsite sichern.
- [ ] `storage/uploads` offsite sichern.
- [ ] Letztes stabiles Release-Artefakt offsite sichern.
Netcup-spezifisch:
- [ ] Falls euer Tarif den Backup Manager anbietet: wiederkehrendes Backup in WCP aktivieren.
- [ ] Backups regelmaessig herunterladen oder an einen zweiten Ort kopieren.
- [ ] Backup Manager nicht als einzigen Disaster-Recovery-Pfad betrachten.
Netcup dokumentiert, dass diese Backups nur auf demselben Hosting wiederhergestellt werden sollen.
## 9. Cron sauber einrichten
- [ ] In WCP eine geplante Aufgabe fuer `bin/cron.php` alle 5 Minuten anlegen.
- [ ] Dieselbe PHP-Version verwenden wie fuer die Website.
- [ ] Den Task vor dem Speichern mit "Run Now" testen.
- [ ] Wenn WCP auf eurem Tarif mit chroot oder relativen Pfaden zickt: den final funktionierenden Befehl direkt dokumentieren.
- [ ] Eine zweite geplante Aufgabe fuer `bin/healthcheck.php` einrichten, mindestens stuendlich oder taeglich.
- [ ] Task-Ausgaben in eine Mail oder Logdatei laufen lassen, statt sie still zu verwerfen.
Wichtige Einschraenkung dieses Repos:
- [ ] `bin/healthcheck.php` liefert JSON, setzt aber bei DB-Problemen derzeit keinen expliziten Exit-Code ungleich 0.
- [ ] Fuer Alarmierung deshalb nicht nur auf "Errors only" bei Scheduled Tasks vertrauen.
- [ ] Zusaetzlich einen externen HTTPS-Uptime-Check auf Startseite oder Login-Seite einrichten.
## 10. Monitoring-Minimum fuer den Start
- [ ] Externes Uptime-Monitoring auf die produktive HTTPS-URL aktivieren.
- [ ] Plesk-/PHP-Error-Logs in die Regelbetriebsroutine aufnehmen.
- [ ] Nach dem Go-Live taeglich Audit-Ereignisse fuer fehlgeschlagene Logins und Access-Denied pruefen.
- [ ] Wachstum der Tabellen `consumption_events`, `ledger_entries` und `audit_events` beobachten.
- [ ] Offene RFID-Ereignisse aus dem Cron-Output beobachten, falls RFID pilotiert wird.
- [ ] Einen klaren Empfaenger fuer Alarmmails hinterlegen.
## 11. Release-Prozess fuer echte Produktion festlegen
Empfohlener erster Produktionsprozess auf Netcup Webspace:
- [ ] Aenderungen auf `staging` komplett durchtesten.
- [ ] Release-Artefakt mit Zeitstempel bauen.
- [ ] Direkt vor dem Produktionsdeploy DB-Backup erstellen.
- [ ] `.env` und persistente `storage/`-Inhalte zusatzlich sichern.
- [ ] Release nach `production` hochladen.
- [ ] `bin/migrate.php` ausfuehren.
- [ ] `bin/healthcheck.php` ausfuehren.
- [ ] Admin-Login, Tenant-Login und Testbuchung sofort pruefen.
- [ ] Den naechsten automatischen Cron-Lauf beobachten.
- [ ] Erst danach das Release als "stabil" markieren.
Wichtige Einschraenkung dieses Repos:
- [ ] `bin/migrate.php` spielt nur `database/schema.sql` erneut ein.
- [ ] Das aktuelle `schema.sql` arbeitet mit `CREATE TABLE IF NOT EXISTS` und ist damit fuer Erstinstallation geeignet, aber kein vollwertiges inkrementelles Migrationssystem.
- [ ] Vor dem ersten Release mit DB-Schema-Aenderungen eine klare Migrationskonvention festlegen, zum Beispiel versionierte SQL-Dateien plus Runbook-Schritt.
## 12. Fallback und Restore vorher ueben
Rollback fuer einen fehlgeschlagenen Release:
- [ ] Letztes stabiles Release-Artefakt erneut deployen.
- [ ] Wenn noetig DB-Backup vom Start des Releases einspielen.
- [ ] `.env` und `storage/uploads` wiederherstellen.
- [ ] `bin/healthcheck.php` ausfuehren.
- [ ] Admin-Login, Tenant-Login und Testbuchung pruefen.
Restore fuer echten Ausfall:
- [ ] Zielreihenfolge dokumentieren: Code, `.env`, Uploads, DB, Healthcheck, Smoke-Test.
- [ ] Restore nicht nur theoretisch planen, sondern einmal auf `staging` ueben.
- [ ] Ziel-RTO und Ziel-RPO festlegen, auch wenn sie anfangs noch pragmatisch sind.
- [ ] Ansprechpartner und Zugangsdaten fuer Restore ausserhalb des Repos dokumentieren.
## 13. Finale Go-Live-Freigabe
Nur live schalten, wenn alles abgehakt ist:
- [ ] Production-Domain zeigt auf Netcup und loest korrekt auf.
- [ ] SSL ist gueltig und HTTPS wird erzwungen.
- [ ] `public/` ist einziger Webroot.
- [ ] `.env`, Backups, Dumps und `.git` sind nicht oeffentlich erreichbar.
- [ ] DB-Backup von heute existiert.
- [ ] Cron laeuft erfolgreich.
- [ ] Externes Monitoring prueft die Seite.
- [ ] Admin-Login und ein Test-Tenant funktionieren.
- [ ] Restore wurde mindestens einmal auf `staging` geprobt.
- [ ] Es gibt eine bewusste Entscheidung, ob offene Registrierung bereits verantwortbar ist.
## Quellen
- Repo-intern:
[DEPLOY.md](/config/workspace/kaffeeliste-neustart/DEPLOY.md),
[RUNBOOK.md](/config/workspace/kaffeeliste-neustart/RUNBOOK.md),
[docs/production-blueprint.md](/config/workspace/kaffeeliste-neustart/docs/production-blueprint.md),
[app/bootstrap.php](/config/workspace/kaffeeliste-neustart/app/bootstrap.php),
[config/app.php](/config/workspace/kaffeeliste-neustart/config/app.php),
[app/Services/SetupService.php](/config/workspace/kaffeeliste-neustart/app/Services/SetupService.php),
[bin/migrate.php](/config/workspace/kaffeeliste-neustart/bin/migrate.php),
[bin/cron.php](/config/workspace/kaffeeliste-neustart/bin/cron.php),
[bin/healthcheck.php](/config/workspace/kaffeeliste-neustart/bin/healthcheck.php),
[scripts/build-release.sh](/config/workspace/kaffeeliste-neustart/scripts/build-release.sh)
- Offizielle Doku:
https://www.netcup.com/en/helpcenter/documentation/web-hosting/php-shell
https://www.netcup.com/en/helpcenter/documentation/web-hosting/scheduled-tasks
https://www.netcup.com/en/helpcenter/documentation/web-hosting/enabling-ssl-tls
https://www.netcup.com/en/helpcenter/documentation/web-hosting/backup-manager
https://docs.plesk.com/en-US/obsidian/customer-guide/scheduling-tasks.65207/
https://www.plesk.com/kb/docs/managing-web-hosting-changing-the-document-root-directory/
-394
View File
@@ -1,394 +0,0 @@
# Go-to-Market 30-60-90 Tage
Stand: 2026-06-15
## Kurzfazit
Die naechsten 90 Tage sollten nicht mit breitem Marketing, sondern mit einem
scharfen Beachhead beginnen:
- Primaere Zielgruppe: Teams, Vereine und kleine Community-Standorte mit 10-50
aktiven Nutzern, die heute Papier, Excel oder lose Strichlisten verwenden.
- Sekundaere Zielgruppe: Coworking-Standorte nur als sales-assistierter Pilot,
nicht als Hauptbotschaft auf der allgemeinen Startseite.
- Kernversprechen: `Papier bleibt moeglich. Abrechnung wird sauber. RFID kommt,
wenn es sich wirklich lohnt.`
Das Ziel bis Tag 90 ist nicht Reichweite, sondern belastbares Marktfeedback:
- 10+ Discovery-Gespraeche
- 3-5 aktive Pilotkunden
- 2 zahlungsbereite Referenzen oder Verlangerungen
- ein belastbarer Preiskorridor
- ein sauber messbarer Lead-zu-Aktivierungs-Funnel
## Repo-basierte Diagnose
Das Produkt ist fuer fruehe Pilotkunden weiter als die Vermarktung.
- Die Startseite erklaert das System technisch stark, aber den operativen Nutzen
noch zu wenig. In [resources/views/home/index.php](../resources/views/home/index.php)
stehen aktuell `PHP/MySQL`, `Netcup-Webspace` und `RFID-Roadmap` sehr weit
vorne.
- Die CTA-Struktur ist zu hart fuer Erstkontakt. Auf der Startseite gibt es
aktuell primaer `Mandant starten`, aber keinen sichtbaren `Demo ansehen`,
`Pilot anfragen` oder `Kontakt`.
- Die Paketsektion nennt Pakete, aber keine oeffentlich validierte Preislogik,
keine Mitgliedergrenzen und keine Testzusage.
- Tracking ist in [docs/marketing-ops.md](./marketing-ops.md) sauber gedacht,
aber im Produkt noch nicht sichtbar umgesetzt.
- Gleichzeitig ist das Produkt onboardingfaehig:
[app/Services/TenantRegistrationService.php](../app/Services/TenantRegistrationService.php)
legt beim Signup bereits Owner, Standardprodukte, Quellen und Grundeinstellungen
an. Das ist eine gute Basis fuer Demo, Trial und Pilot.
## Positionierung
### Empfehlung
Nicht `Kaffeekasse fuer alle` vermarkten. Stattdessen ein klares Einstiegsproblem
verkaufen:
- `Wir ersetzen nicht eure Gewohnheit auf einen Schlag.`
- `Wir machen aus Papier, Nachtrag und Selbstbedienung eine saubere Abrechnung.`
- `Wenn ihr spaeter RFID wollt, muesst ihr nicht neu anfangen.`
### Empfohlene Marktansprache
- Primaer: Vereinsvorstand, Getraenkewart, Office Manager, Team-Admin,
Community Manager, die heute Fehler, Rueckfragen und fehlende Einzahlungen
manuell klaeren.
- Sekundaer: Coworking-Betreiber mit Community-Kueche oder Honesty Bar. Hier
ist das Produkt eher eine schlanke Beverage-Operations-Loesung als eine
komplette Coworking-Plattform.
### Messaging-Hierarchie
- Hauptclaim: `Die Kaffeekasse fuer Teams und Vereine, die noch nicht ganz auf
Papier verzichten wollen.`
- Unterclaim: `Digitale Buchungen, Papier-Nacherfassung und spaeter RFID - alles
in einer nachvollziehbaren Abrechnung.`
- Beweis 1: `Mitglieder, Produkte, Einzahlungen und Salden in einem Ablauf`
- Beweis 2: `Sofort startklar im Browser, Tablet oder Kiosk`
- Beweis 3: `RFID nicht heute noetig, aber morgen anschliessbar`
### Was nicht in die Hero-Message gehoert
- `PHP/MySQL`
- `Netcup`
- `mandantenfaehig`
- `Ledger`
Diese Begriffe sind sinnvoll fuer Betrieb, Doku und Technikvertrauen, aber nicht
fuer den ersten Kaufimpuls.
## Demo-Setup
### Warum das jetzt Prioritaet hat
Aktuelle Wettbewerber kombinieren sehr oft Demo oder Trial mit sehr einfacher
Preislogik. Stand 2026-06-15:
- Getraenkewart kommuniziert eine sofortige Demo und eine kostenlose kleine
Einstiegsstufe.
- Clubfridge stellt ein Testsystem und 30 Tage Gratis-Test in den Vordergrund.
- Cobot kombiniert `Try it for free` und `Schedule a demo`.
Die Lehre daraus: Frueher Markt will erst sehen, dann glauben, dann kaufen.
### Empfohlenes Demo-Setup
- Ein `Team-Demo` mit 12 Mitgliedern, 4 Produkten, 30 Buchungen und 3
Einzahlungen
- Ein `Verein-Demo` mit Papierliste als Entwurf plus verbuchter Papierliste
- Ein `Coworking-Demo` mit vorbereiteten RFID-Geraeten, Tags und Events, aber
ohne die RFID-Roadmap als Hauptverkaufspunkt zu missbrauchen
### Empfohlene Demo-Artefakte
- Oeffentliche Browser-Demo mit taeglichem oder stuendlichem Reset
- 7-Minuten-Live-Demo-Skript
- 90-Sekunden-Klickpfad fuer die Startseite:
`Mitglied anlegen -> Buchung erfassen -> Einzahlung buchen -> Papierliste
verbuchen`
- Einseitiges Pilot-PDF:
`Was wird in 14 Tagen gemeinsam getestet?`
### Demo-Story
- Problem: `Striche fehlen, Spaetzahler fehlen, niemand will am Monatsende
rechnen`
- Heute: `Papier bleibt erlaubt`
- Morgen: `Digitale Selbstbuchung spart Rueckfragen`
- Spaeter: `RFID ist ein Upgrade, kein Neuanfang`
## Landingpage-Verbesserungen
### Sofort priorisieren
- Hero von technischer auf operative Sprache drehen
- Primaere CTA auf `Demo ansehen` oder `Pilot anfragen`
- Sekundaere CTA auf `Kostenlos testen`
- Einen Abschnitt `Fuer wen ist das?` mit drei Kacheln:
`Team`, `Verein`, `Coworking-Kueche`
- Einen Abschnitt `So startet ihr in 1 Nachmittag`
- Einen Abschnitt `Papier heute, digital morgen, RFID spaeter`
### Danach
- Preissektion mit realen Stufen statt nur Paketnamen
- FAQ zu `Brauchen wir App-Downloads?`, `Kann Papier bleiben?`, `Was kostet
RFID spaeter?`, `Wie schnell sind wir live?`
- Vertrauenselemente:
`Hosting in DE/EU`, `Datenschutz`, `keine Kreditkarte fuer Pilot`, `persoenliche
Begleitung`
- Spater: Logos, Zitate und Mini-Case-Studies von echten Piloten
### Konkrete Copy-Richtung fuer die Hero
- Headline: `Die Kaffeekasse ohne Zettelchaos`
- Subline: `Erfasst Kaffee, Getraenke und Einzahlungen digital, fuehrt
Papierlisten weiter und haltet Salden sauber nachvollziehbar - fuer Teams,
Vereine und Community-Standorte.`
- CTA 1: `Demo ansehen`
- CTA 2: `Pilot starten`
## Lead-Funnel
### Zielbild
Nicht direkt von `Landing Visit` zu `voller Self-Service-Registrierung`
optimieren. Dazwischen braucht es eine niedrigere Huerde.
Empfohlener Funnel:
1. Landing Visit
2. CTA Klick auf `Demo ansehen` oder `Pilot anfragen`
3. Lead erfasst
4. Demo angesehen oder Termin gebucht
5. Pilot zugesagt
6. Tenant angelegt
7. Erste Buchung innerhalb von 24 Stunden
8. Erste Einzahlung oder erste Papierliste innerhalb von 7 Tagen
9. Verlaengerung oder Upgrade
### Minimaler Funnel fuer die ersten 90 Tage
- Kanal 1: Warmes Netzwerk
- Kanal 2: Direktansprache lokaler Vereine, Coworking-Spaces, Bueros,
Feuerwehren, Gemeinschaftsraeume
- Kanal 3: 2-3 kurze Content-Stuecke mit konkretem Problemfokus:
`Excel vs. Kaffeeliste`, `Papierliste sauber nacherfassen`, `Wann lohnt sich
RFID wirklich?`
### Tracking, das sofort noetig ist
Die Eventnamen existieren schon in [docs/marketing-ops.md](./marketing-ops.md).
Fuer die ersten 90 Tage reicht:
- `landing_view`
- `demo_clicked`
- `pilot_requested`
- `register_started`
- `tenant_registered`
- `first_consumption_recorded`
- `first_payment_recorded`
- `paper_sheet_created`
### CRM-Minimum
Noch kein grosses CRM-Projekt starten. Eine einfache Tabelle oder ein sehr
schlankes CRM reicht mit diesen Feldern:
- Organisation
- Segment
- Ansprechpartner
- Problem heute
- Anzahl Nutzer
- Heute Papier, digital oder gemischt
- Interesse an RFID spaeter: ja/nein
- Status: `neu`, `demo`, `pilot`, `aktiv`, `verloren`
- Grund fuer Verlust
## Pricing-Validierung
### Marktbeobachtung am 2026-06-15
- Getraenkewart kommuniziert eine einfache Preislogik von `20 Cent pro Mitglied
und Monat`, mit `0 EUR` fuer sehr kleine Teams und `5 EUR / Monat` fuer 25
Mitglieder.
- selbstbedienBar zeigt eine kostenlose Einstiegsstufe mit bis zu 5 Usern.
- Clubfridge bewirbt 30 Tage Gratis-Test und argumentiert ueber geringe
laufende Kosten und klare Einsparung von Verwaltungsaufwand.
- Cobot liegt als Coworking-Management-Plattform deutlich hoeher und eignet sich
eher als Referenz fuer den sales-assistierten Coworking-Pfad als fuer die
breite Preiserwartung im Vereins- und Teamsegment.
### Schlussfolgerung
Der Team-/Vereinsmarkt ist preissensibel. Eine `normale B2B-SaaS-Optik` mit
hohem Einstiegspreis wird dort frueh bremsen. Gleichzeitig ist Coworking als
Segment eher bereit, fuer operative Zuverlaessigkeit und spaetere Integrationen
mehr zu zahlen.
### Validierungsansatz
Nicht sofort eine endgueltige Preisarchitektur festschreiben. In den ersten
Piloten zwei Preislogiken testen:
- Variante A: flache Standortpreise
- Beispiel: `9 EUR`, `19 EUR`, `39 EUR`
- Variante B: faire Mitgliederlogik
- Beispiel: `0,20 EUR pro aktivem Mitglied/Monat` mit Mindestpreis
### Was oeffentlich sichtbar sein sollte
- 30 Tage Pilot oder Testphase
- Kein Kreditkarten-Zwang am Anfang
- RFID nicht oeffentlich festpreisen, sondern `auf Anfrage / Pilot`
- Klarer Satz: `Fuer groessere Standorte oder RFID-Szenarien sprechen wir kurz
direkt miteinander`
### Was in jedem Gespraech abgefragt werden sollte
- Wie viele aktive Nutzer gibt es wirklich?
- Wie viel Verwaltungszeit spart das pro Monat?
- Ist eher `pro Mitglied` oder `pro Standort` gefuehlt fair?
- Wuerde man ohne RFID schon zahlen?
- Ist Papier-Nacherfassung kaufentscheidend oder nur hilfreich?
## Erster Pilotkundenprozess
### Idealer Pilotkunde
- 10-50 aktive Nutzer
- klares heutiges Problem mit Papier, Excel oder Nachbuchungen
- ein verantwortlicher Owner
- Bereitschaft, 14 Tage aktiv zu testen
- Bereitschaft fuer 2 Feedback-Termine
### Pilotablauf
1. 20-Minuten-Qualifizierung
2. 30-Minuten-Demo entlang des echten Prozesses
3. Pilotzusage mit klarem Testziel
4. Tenant anlegen und Owner live einrichten
5. Binnen 24 Stunden erste echte Buchung
6. Tag 7: Check-in zu Aktivierung, Rueckfragen, Widerstaenden
7. Tag 14 oder 21: Review, Preisgespraech, Verlaengerung oder Abschluss
### Pilot-Erfolgskriterien
- Owner ist aktiv
- mindestens 5-10 Mitglieder angelegt
- mindestens 20 echte Buchungen
- mindestens 1 Einzahlung oder 1 Papierlisten-Posting
- kein schwerer Vertrauensbruch in Salden oder Nachvollziehbarkeit
- klare Aussage: `Wuerden wir dafuer zahlen?`
### Pilotangebot
- `Begleiteter Pilot fuer 14 oder 30 Tage`
- `Einrichtung gemeinsam in 30 Minuten`
- `Keine Datenmigration noetig`
- `Feedback gegen guenstige Early-Adopter-Konditionen`
## Priorisierte 30-60-90-Tage-Empfehlung
## Tage 1-30
Ziel: Message klaeren, Demo faehig machen, erste Gespraeche starten.
- Einen Beachhead final auswaehlen:
`Teams/Vereine mit Hybrid-Prozess` sollte aktuell gewinnen.
- Startseite sprachlich neu ausrichten und technische Begriffe aus der Hero nach
unten verschieben.
- Demo-Umgebung mit 2-3 vorbereiteten Tenants aufsetzen.
- CTA-Struktur erweitern:
`Demo ansehen`, `Pilot anfragen`, `Kostenlos testen`
- Minimales Tracking fuer Landing, Demo, Signup und Aktivierung einbauen.
- Outreach-Liste mit 50 passenden Erstkontakten aufbauen, zuerst warm, dann
lokal-kalt.
- 10 Discovery-Gespraeche fuehren.
- 3 Pilotkunden anbahnen.
Messbar bis Tag 30:
- 10 Gespraeche
- 3 qualifizierte Pilotkandidaten
- 1 funktionierende Browser-Demo
- 1 Landingpage-Version mit klarer Botschaft
## Tage 31-60
Ziel: Piloten aktivieren, Preissignale einsammeln, erste Beweise erzeugen.
- 2-3 Piloten live nehmen.
- Zwei Pricing-Frames in Gespraechen testen:
`pro Standort` vs. `pro Mitglied`
- Erste Landingpage-Variante nach Segment pruefen:
`Verein/Team` gegen `Coworking`
- Pilot-Onboarding standardisieren:
Checkliste, Demo-Skript, Follow-up-Mail, Tag-7-Review
- Ein erstes Mini-Case-Study-Format bauen:
Problem, Einfuehrung, erste Ergebnisse, Zitat
- Die haeufigsten Einwaende und Kaufgruende dokumentieren.
Messbar bis Tag 60:
- 2-3 aktive Piloten
- 70% der Piloten mit erster Buchung in 24 Stunden
- 2 belastbare Preisreaktionen pro Segment
- 1-2 verwertbare Kundenstimmen
## Tage 61-90
Ziel: Gewinner schaerfen, erste bezahlte Wiederholbarkeit bauen.
- Gewinner-Positionierung oeffentlich festziehen.
- Eine oeffentliche Preislogik veroeffentlichen, aber RFID weiter als
gesonderten Sales-Pfad lassen.
- Referenzen und Vertrauenselemente auf die Startseite bringen.
- Den Pilotprozess in einen wiederholbaren `Demo -> Pilot -> Paid` Ablauf
ueberfuehren.
- 2 Piloten in bezahlte Kunden oder verlaengerte Nutzung umwandeln.
- Entscheiden, ob Coworking eine eigene Unterseite und eigene Sales-Story
verdient oder vorerst nur Upside bleibt.
Messbar bis Tag 90:
- 3-5 aktive Pilotkunden insgesamt
- 2 zahlungsbereite oder zahlende Referenzkunden
- 1 veroeffentlichte Preislogik
- klarer Entscheid zur Rolle von Coworking im GTM
## Klare Priorisierung
Wenn nur wenig Kapazitaet da ist, dann in genau dieser Reihenfolge:
1. Positionierung fuer einen Beachhead
2. Demo und Pilotprozess
3. Landingpage-CTA und Tracking
4. Pricing-Validierung in echten Gespraechen
5. Erst danach breitere Content- oder Paid-Massnahmen
## Was ich explizit nicht priorisieren wuerde
- Paid Ads vor dem ersten wiederholbaren Pilotprozess
- eine zu breite Positionierung fuer Teams, Vereine und Coworking gleichzeitig
- oeffentliche RFID-Versprechen, die noch keine echte Kaufhuerde geloest haben
- grosse CRM- oder Marketing-Automation-Projekte vor den ersten 3-5 Piloten
## Externe Referenzen
Stand 2026-06-15:
- Getraenkewart Startseite: https://getraenkewart.com/
- Getraenkewart Preise: https://getraenkewart.com/preise/
- Getraenkewart FAQ: https://getraenkewart.com/faq
- Clubfridge Startseite: https://clubfridge.com/
- Clubfridge Testsystem / Testen: https://clubfridge.com/clubfridge-testen/
- Clubfridge RFID-Artikel: https://clubfridge.com/rfid-kuehlschrank-im-vereinsheim-einrichten-so-funktioniert-die-digitale-getraenkekasse/
- selbstbedienBar Preise: https://www.selbstbedienbar.de/preise/
- Cobot Pricing: https://www.cobot.me/en/pricing
- Cobot Startseite: https://www.cobot.me/en/
-51
View File
@@ -1,51 +0,0 @@
# Marketing-Operations
## Ziel
Der Produktauftritt soll nicht nur schoen aussehen, sondern einen messbaren
Pfad von `Interesse` zu `aktivem Tenant` schaffen.
## Funnel-Stufen
1. `Landing Visit`
2. `CTA Klick auf Registrierung`
3. `Tenant registriert`
4. `Erster Login`
5. `Erste Buchung`
6. `Erste Papierliste oder erstes RFID-Setup`
## Tracking-Ereignisse
- `landing_view`
- `pricing_view`
- `register_started`
- `tenant_registered`
- `tenant_login_success`
- `first_consumption_recorded`
- `paper_sheet_created`
- `rfid_device_created`
## Tooling-Empfehlung
- datenschutzfreundliches Web-Analytics statt schwerem Adtech-Setup
- Formular-Events serverseitig oder ueber schlankes Frontend-Tracking mitschreiben
- CRM-Anbindung zunaechst ueber CSV-Export oder Webhook-Fassade
- spaeter: automatisch segmentierte Onboarding-Mails pro Paket
## Operative Fragen fuer den Go-Live
- Welche CTA-Version konvertiert fuer Vereine besser: `Digitale Strichliste` oder
`Kaffeekasse digitalisieren`?
- Wie viele registrierte Tenants legen binnen 24 Stunden Mitglieder und Produkte
an?
- Wo brechen Interessenten ab: auf der Landingpage, im Signup oder erst beim
Login?
## Direkt im Produkt nutzbar
Die Landingpage im Repo ist bereits auf diese Funnel-Logik abgestimmt:
- klares Problem-Narrativ
- Paketdarstellung
- direkter CTA zur Registrierung
- technischer Vertrauensaufbau ueber Netcup-, Papier- und RFID-Kompatibilitaet
-207
View File
@@ -1,207 +0,0 @@
# Netcup Deployment Guide - Kaffeekasse SaaS
Dieser Guide führt Sie Schritt für Schritt durch das Deployment der Kaffeekasse SaaS auf Netcup Webspace.
## Übersicht
Die Kaffeekasse SaaS ist bereits vollständig für Netcup Webspace vorbereitet. Dieses Deployment-Guide ergänzt die bestehende Dokumentation ([DEPLOY.md](../DEPLOY.md), [docs/go-live-checklist-netcup.md](go-live-checklist-netcup.md)) um praktische Schritte.
## Voraussetzungen
- Netcup Webspace mit PHP 8.3+ und MySQL
- FTP/SFTP Zugang zu Ihrem Webspace
- Domain oder Subdomain für die Anwendung
## Schritt 1: Lokale Vorbereitung
### 1.1 Deployment-Skript ausführen
```bash
# Im Projektverzeichnis
./scripts/deploy-netcup.sh
```
Das Skript erstellt:
- Ein Release-Paket (`build/kaffeekasse-saas-YYYYMMDD-HHMMSS.tar.gz`)
- Deployment-Anweisungen
- .htaccess Informationen
### 1.2 Umgebungskonfiguration anpassen
Bearbeiten Sie `.env.netcup` und passen Sie folgende Werte an:
```env
APP_URL=https://ihre-domain.tld
APP_KEY=ihr-32-stelliger-app-schluessel
DB_NAME=ihre_datenbank
DB_USER=ihr_db_benutzer
DB_PASS=ihr_db_passwort
MAIL_FROM=noreply@ihre-domain.tld
MAIL_REPLY_TO=support@ihre-domain.tld
RFID_SHARED_SECRET=ihr-sicherer-rfid-schluessel
```
**Wichtig:** Generieren Sie sichere, zufällige Werte für `APP_KEY` und `RFID_SHARED_SECRET`!
## Schritt 2: Netcup Webspace vorbereiten
### 2.1 Domain/Subdomain einrichten
1. Loggen Sie sich in das Netcup WCP (Webhosting Control Panel) ein
2. Erstellen Sie eine neue Domain oder Subdomain
3. Setzen Sie den Document Root auf: `/apps/kaffeekasse/current/public`
### 2.2 MySQL Datenbank erstellen
1. Erstellen Sie eine neue MySQL Datenbank
2. Erstellen Sie einen separaten Datenbankbenutzer
3. Gewähren Sie dem Benutzer alle Rechte auf die Datenbank
4. Notieren Sie sich die Zugangsdaten für die `.env` Datei
### 2.3 PHP Version einstellen
1. Stellen Sie die PHP Version auf 8.3 oder 8.4
2. Aktivieren Sie alle benötigten PHP Extensions (PDO, MySQL, etc.)
## Schritt 3: Upload und Installation
### 3.1 Dateien hochladen
```bash
# Per SFTP/FTP
# 1. Release-Paket nach /apps/kaffeekasse/ hochladen
# 2. .env.netcup als .env nach /apps/kaffeekasse/ hochladen
```
### 3.2 Entpacken und einrichten
```bash
# Auf dem Server (SSH) oder per File Manager
cd /apps/kaffeekasse
tar -xzf kaffeekasse-saas-*.tar.gz
mv kaffeekasse-saas-* current
mv .env current/
```
### 3.3 Verzeichnisberechtigungen
Stellen Sie sicher, dass folgende Verzeichnisse beschreibbar sind:
- `storage/`
- `storage/cache/`
- `storage/logs/`
- `storage/uploads/`
## Schritt 4: Installation
### Option A: Browser-Installer (empfohlen)
1. Öffnen Sie `https://ihre-domain.tld/install`
2. Folgen Sie den Anweisungen des Installers
3. Der Installer erstellt automatisch die Datenbanktabellen
### Option B: Manuelle Installation
```bash
# Per SSH auf dem Server
/usr/local/php83/bin/php /apps/kaffeekasse/current/bin/migrate.php
```
## Schritt 5: Cron-Jobs einrichten
### 5.1 Hauptcron (alle 5 Minuten)
```bash
*/5 * * * * /usr/local/php83/bin/php /apps/kaffeekasse/current/bin/cron.php
```
### 5.2 Healthcheck (täglich)
```bash
0 6 * * * /usr/local/php83/bin/php /apps/kaffeekasse/current/bin/healthcheck.php
```
## Schritt 6: SSL/HTTPS einrichten
1. Aktivieren Sie Let's Encrypt in Ihrem WCP
2. Erzwingen Sie HTTPS für die Domain
3. Testen Sie die SSL-Konfiguration
## Schritt 7: Tests durchführen
### 7.1 Grundfunktionen testen
1. **Startseite**: `https://ihre-domain.tld`
2. **Admin-Login**: `https://ihre-domain.tld/admin/login`
3. **Healthcheck**:
```bash
/usr/local/php83/bin/php /apps/kaffeekasse/current/bin/healthcheck.php
```
### 7.2 Vollständiger Test
1. Loggen Sie sich als Admin ein
2. Erstellen Sie einen Test-Mandanten
3. Loggen Sie sich als Mandant ein
4. Erstellen Sie Testprodukte und -buchungen
5. Prüfen Sie die Cron-Ausführung
## Schritt 8: Produktionsbereitschaft
### 8.1 Sicherheitscheck
- [ ] Nur `public/` ist über Web erreichbar
- [ ] `.env`, `.git`, Backups sind nicht öffentlich zugänglich
- [ ] HTTPS ist erzwungen
- [ ] Starke Passwörter für Admin und DB
### 8.2 Backup einrichten
- [ ] Tägliches DB-Backup
- [ ] `.env` Datei sichern
- [ ] `storage/uploads` sichern
- [ ] Release-Artefakte aufbewahren
### 8.3 Monitoring
- [ ] Externes Uptime-Monitoring
- [ ] Log-Überwachung
- [ ] Cron-Job Überwachung
## Troubleshooting
### Häufige Probleme
**Problem**: 500 Internal Server Error
- **Lösung**: Prüfen Sie Apache Error Logs und PHP Error Logs
- **Häufige Ursache**: Falsche Dateiberechtigungen oder .htaccess Probleme
**Problem**: Datenbank-Verbindungsfehler
- **Lösung**: Prüfen Sie DB-Zugangsdaten in `.env`
- **Tipp**: Testen Sie die Verbindung mit einem separaten PHP-Skript
**Problem**: Cron-Jobs laufen nicht
- **Lösung**: Prüfen Sie PHP-Pfad und Dateiberechtigungen
- **Tipp**: Testen Sie Cron-Jobs manuell per SSH
### Log-Dateien
- **Apache Error Log**: Meist in `/var/log/apache2/error.log` oder über WCP
- **PHP Error Log**: Konfigurierbar in PHP-Einstellungen
- **Application Logs**: `storage/logs/`
## Support und weitere Informationen
- **Vollständige Checkliste**: [docs/go-live-checklist-netcup.md](go-live-checklist-netcup.md)
- **Deployment-Dokumentation**: [DEPLOY.md](../DEPLOY.md)
- **Betriebshandbuch**: [RUNBOOK.md](../RUNBOOK.md)
## Nächste Schritte nach Go-Live
1. Überwachen Sie die Anwendung in den ersten Tagen intensiv
2. Richten Sie regelmäßige Backups ein
3. Planen Sie Updates und Wartungsfenster
4. Dokumentieren Sie Ihre spezifische Konfiguration
---
**Hinweis**: Dieser Guide basiert auf der aktuellen Netcup Webspace-Konfiguration. Bei Änderungen der Hosting-Umgebung können Anpassungen erforderlich sein.
-149
View File
@@ -1,149 +0,0 @@
# Naechste Schritte Roadmap
Stand: 2026-06-15
Diese Roadmap verdichtet die Empfehlungen mehrerer Fach-Agenten fuer Produkt,
Sicherheit, Betrieb, QA und Go-to-Market in einen konkreten Fahrplan fuer das
hochgeladene Repository.
## Leitplanke
Der erste echte Einsatz soll **kein breiter oeffentlicher SaaS-Launch** sein,
sondern ein **kontrollierter Pilot** mit 1-2 Mandanten.
Vor Day 1 gewinnt nicht die groesste Funktionsbreite, sondern der Hybrid-Kern:
- Mitglieder
- Produkte und Preise
- digitale Buchungen
- Einzahlungen
- Papierlisten-Nacherfassung
- saubere Salden und Auditierbarkeit
RFID bleibt fuer den ersten Produktivstart vorbereitet, aber nicht
automatisiert.
## Phase 1: Vor dem Pilot hart absichern
Diese Punkte sollten vor einem echten Testkunden produktionsnah erledigt sein.
### Muss
- serverseitige Ownership-Pruefung fuer alle `tenant_id`-bezogenen IDs
bei Buchungen, Einzahlungen, Papierlisten und RFID
- Self-Service-Rollenmodell schaerfen:
`member` soll nur fuer sich selbst buchen und nur eigene Daten sehen
- PINs nicht mehr im Klartext speichern oder anzeigen
- Rate-Limits fuer Login und Registrierung
- Passwort-Reset fuer Owner und Mitglieder
- Registrierung entweder als geschlossenen Pilot betreiben oder erst nach
Mail-Verifikation oeffnen
- Korrektur-/Storno-Flow fuer Fehlbuchungen, Einzahlungen und Papierlisten
- Mitglieder-Saldenliste und Buchungshistorie pro Mitglied
- CSV-Exporte fuer Salden und Buchungen
- RFID-Intake fuer Day 1 deaktivieren oder explizit haerten
### Soll
- inkrementellen Migrationspfad einfuehren statt reinem `schema.sql`-Replay
- Healthcheck um klaren Monitoring-Pfad erweitern
- Audit-Retention und datensparsame Audit-Metadaten definieren
- Netcup-Hardening technisch erzwingen:
HTTPS, Header, Session-Secure-Handling, Installer-Lockdown
### Abnahme
- ein neuer Tenant kann ohne DB-Eingriff eingerichtet werden
- ein verlorenes Passwort ist ohne manuelle SQL-Hilfe loesbar
- eine Fehlbuchung laesst sich im Produkt sauber korrigieren
- Salden in UI, Export und DB stimmen ueberein
- Cross-Tenant-Zugriffe sind negativ getestet
## Phase 2: Staging, Go-Live-Readiness und Pilot-UAT
### Betrieb
- Staging-Umgebung auf Netcup anlegen
- produktionsnahes Deployment durchspielen
- SSL, Cron, Healthcheck und Backup auf Staging pruefen
- Restore einmal wirklich testen
- Release- und Rollback-Ablauf dokumentiert ueben
### QA
- Smoke-Tests fuer Installation, Admin-Login, Tenant-Registrierung,
Owner-Login, Mitglieder, Produkte, Buchungen, Einzahlungen und Papierlisten
- DB-Stichproben fuer `consumption_events`, `ledger_entries`, `ledger_lines`
- Rechte- und Mandantentrennung negativ testen
- RFID nur als optionalen Inbox-Test behandeln
### Pilotkundenprozess
- 1 kleiner digitaler Pilotmandant
- 1 Hybrid-Pilotmandant mit Papierliste
- 5-7 Tage UAT mit echten oder realistisch simulierten Buchungen
- Freigabe durch Owner und Admin des Piloten
### Abnahme
- alle Smoke-Tests bestanden
- keine kritischen Fehler offen
- Backup, Cron und Restore nachweislich geprueft
- mindestens 10 Buchungen, 2 Einzahlungen und 1 Papierlisten-Posting pro Pilot
## Phase 3: 30-60-90 Tage nach dem Upload
## 30 Tage
- Beachhead-Segment festziehen:
Teams und Vereine mit Hybrid-Prozess
- Landingpage verkaufsnaher schaerfen:
Problem, Demo, Pilot statt Technik zuerst
- Demo-Setup bauen:
Team-Demo, Vereins-Demo, 7-Minuten-Skript
- 10+ Discovery-Gespraeche fuehren
- 3 Pilotkunden anbahnen
## 60 Tage
- 2-3 Piloten aktiv im System
- Preisvalidierung zwischen Standortpreis und Mitgliederpreis
- Tracking fuer `demo_clicked`, `pilot_requested`,
`tenant_registered`, `first_consumption_recorded`,
`first_payment_recorded`, `paper_sheet_created`
- wiederholbaren `Demo -> Pilot -> Aktiv` Ablauf aufbauen
## 90 Tage
- 2 zahlungsbereite Referenzen oder Verlaengerungen
- erste oeffentliche Preislogik festziehen
- Landingpage mit Vertrauenselementen und FAQ erweitern
- Pilot-Feedback in priorisierte Produktarbeit ueberfuehrt
## Bewusst spaeter
Diese Punkte sind sinnvoll, aber nicht noetig fuer den ersten kontrollierten
Pilot:
- MFA fuer Owner/Admin
- Einladungs-Workflow
- RFID-Autobuchung und Event-Regeln
- White-Labeling
- automatisches Billing
- groessere CRM- oder Marketing-Automation
## Sofort als naechste 5 Arbeitspakete
1. Ownership-Checks, Rollenmodell und PIN-Hardening umsetzen.
2. Passwort-Reset, Rate-Limits und Pilot-Registrierungsmodus bauen.
3. Korrekturen/Stornos, Saldenansichten und CSV-Exporte ergaenzen.
4. Staging auf Netcup aufsetzen und die Go-Live-Checkliste durchgehen.
5. Demo-Setup plus 1-2 Pilotmandanten vorbereiten.
## Verwandte Dokumente
- [docs/go-live-checklist-netcup.md](/config/workspace/kaffeeliste-neustart/docs/go-live-checklist-netcup.md)
- [docs/go-to-market-30-60-90.md](/config/workspace/kaffeeliste-neustart/docs/go-to-market-30-60-90.md)
- [docs/product-strategy.md](/config/workspace/kaffeeliste-neustart/docs/product-strategy.md)
- [docs/marketing-ops.md](/config/workspace/kaffeeliste-neustart/docs/marketing-ops.md)
- [docs/production-blueprint.md](/config/workspace/kaffeeliste-neustart/docs/production-blueprint.md)
-48
View File
@@ -1,48 +0,0 @@
# Produkt- und Vermarktungsstrategie
## Zielgruppen
- kleine und mittlere Teams mit gemeinsamer Kaffeekasse
- Vereine mit klassischer Strichliste
- Coworking- und Mehrraum-Standorte mit spaeterer RFID-Option
## Kernbotschaft
`Eine Kaffeekasse fuer analog und digital.`
Die Anwendung ersetzt Papier nicht abrupt, sondern verbindet Papierliste,
digitale Selbstbedienung und spaetere Geraeteanbindung in einem nachvollziehbaren
Buchungssystem.
## Positionierung
- weniger Tool-Fragmentierung als Eigenbau aus Excel, Zetteln und Einzelapps
- verstaendlichere Einfuehrung als reine Hardware- oder RFID-Produkte
- realistischer Betrieb auf klassischem Webhosting statt VPS-Pflicht
## Paketlogik
- `Starter`: digitale Buchungen, Mitglieder, Produkte, Einzahlungen
- `Team`: zusaetzlich Papierlisten-Workflow und staerkeres Backoffice
- `Business`: RFID-Roadmap, Betriebshooks, White-Label-/Integrationsvorstufe
## Marketing-Funnel
1. Landingpage erklaert den analogen und digitalen Use Case in einem Satz.
2. CTA fuehrt direkt in Mandanten-Registrierung oder Demo-Setup.
3. Der Self-Service legt sofort einen nutzbaren Tenant mit Default-Produkten an.
4. Plattform-Admin kann spaeter Vertrieb, Support und Paketwechsel steuern.
## Messaging-Elemente
- `Digitale Strichliste fuer Teams und Vereine`
- `Papierliste bleibt moeglich`
- `RFID spaeter anschliessen, ohne neu zu bauen`
- `Nachvollziehbare Salden und Buchungsverlaeufe`
## Vertriebsnahe KPIs
- Registrierungen pro Paket
- Anteil aktivierter Tenants
- erste Buchung innerhalb von 24 Stunden
- Anteil Tenants mit aktiver Papierlisten-Nutzung
- Nachfrage nach RFID-/Standortintegration
-37
View File
@@ -1,37 +0,0 @@
# Produktions-Blueprint
## Architektur
- modularer Monolith in PHP
- gemeinsame MySQL-Datenbank mit `tenant_id`
- Frontcontroller unter `public/index.php`
- Services fuer Setup, Registrierung, Ledger und RFID
## Sicherheitsgrundlagen
- serverseitige PHP-Sessions
- CSRF-Schutz fuer alle schreibenden Formulare
- `password_hash()` mit moderner Hash-Funktion
- Audit-Log fuer Login, Registrierung, Buchungen und RFID-Ereignisse
- path-basierte Tenant-Isolation ueber Memberships
## Betriebsmodell
- Installation per Browser oder `bin/migrate.php`
- Cron-basierte technische Haken ueber `bin/cron.php`
- Healthcheck als JSON ueber `bin/healthcheck.php`
- Release-Pakete ueber `scripts/build-release.sh`
## Was vor echtem Go-Live noch folgen sollte
- Mail-Verifikation und Passwort-Reset-Flow
- MFA fuer Admin- und Owner-Rollen
- Login- und Registrierungs-Rate-Limits
- strukturiertes Logging in Datei oder externem Ziel
- abgesicherter Support-Zugriff fuer Plattform-Admins
## Git- und CI-Gedanke
Das Repo ist absichtlich neutral gehalten, damit spaeter auf `git.ctb-it.de`
entweder GitLab- oder Gitea-CI angedockt werden kann. Die eigentliche
Deploy-Logik steckt in Skripten und Doku, nicht in einem proprietaeren CI-Format.
-199
View File
@@ -1,199 +0,0 @@
# Proxy-Kompatibilität: Zusammenfassung der Änderungen
## ✅ Status: Vollständig kompatibel
Die Kaffeekasse-SaaS-Anwendung ist **vollständig kompatibel** mit:
- ✅ Netcup Webspace (direkter Zugriff)
- ✅ Code-Server Proxy-Weiterleitung
- ✅ Subdirectory-Installationen
- ✅ Reverse Proxy Setups (Nginx, Apache)
## 🔍 Durchgeführte Analyse
### 1. Bestehende Implementierung (bereits vorhanden)
Die Anwendung war bereits sehr gut vorbereitet:
**Helper-Funktionen (`app/Support/helpers.php`):**
-`base_path()` - Erkennt automatisch Proxy-Prefixes
-`current_path()` - Berücksichtigt Base Path
-`url()` - Generiert URLs dynamisch mit Base Path
-`tenant_url()` - Tenant-URLs mit Base Path
-`asset_url()` - Asset-URLs mit Base Path
**Automatische Erkennung:**
```php
function base_path(): string
{
foreach ([
$_SERVER['KAFFEEKASSE_PROXY_PREFIX'] ?? null, // Manuell
$_SERVER['HTTP_X_FORWARDED_PREFIX'] ?? null, // Code-Server
$_ENV['APP_BASE_PATH'] ?? null, // .env
] as $prefix) {
if ($prefix !== '') {
return normalize_base_path($prefix);
}
}
return '';
}
```
**View-Templates:**
- ✅ Alle URLs verwenden `url()` oder `tenant_url()`
- ✅ Keine hardcodierten Pfade gefunden
- ✅ Assets verwenden `asset_url()`
### 2. Durchgeführte Verbesserungen
#### A) `.htaccess` erweitert
**Datei:** `public/.htaccess`
**Änderung:**
```apache
# Proxy-Unterstützung: X-Forwarded-* Header durchreichen
RewriteCond %{HTTP:X-Forwarded-Proto} ^https$
RewriteRule ^ - [E=HTTPS:on]
```
**Zweck:** HTTPS-Erkennung hinter Reverse Proxy
#### B) `.env.example` dokumentiert
**Datei:** `.env.example`
**Änderung:**
```env
# APP_BASE_PATH: Leer für direkten Zugriff, /proxy/8080 für code-server Proxy
APP_BASE_PATH=
```
**Zweck:** Klarstellung für Benutzer
#### C) Dokumentation erstellt
**Neue Dateien:**
1. `docs/deployment-proxy-guide.md` - Vollständige Anleitung
2. `PROXY-SETUP.md` - Quick Start Guide
3. `docs/proxy-compatibility-summary.md` - Diese Datei
## 🧪 Verifikation
### Test 1: Ohne Base Path (Netcup Webspace)
```
base_path() =
url("/") = .
url("/admin/login") = admin/login
tenant_url("test", "bookings") = t/test/bookings
asset_url("app.css") = assets/app.css
```
**Ergebnis:** Relative URLs für direkten Zugriff
### Test 2: Mit Base Path (Code-Server Proxy)
```
base_path() = /proxy/8080
url("/") = /proxy/8080/
url("/admin/login") = /proxy/8080/admin/login
tenant_url("test", "bookings") = /proxy/8080/t/test/bookings
asset_url("app.css") = /proxy/8080/assets/app.css
```
**Ergebnis:** Absolute URLs mit Proxy-Prefix
## 📋 Deployment-Szenarien
### Szenario 1: Netcup Webspace (Production)
```env
APP_URL=https://ihre-domain.de
APP_BASE_PATH=
```
- Document Root zeigt auf `/public/`
- `.htaccess` übernimmt Routing
- Relative URLs funktionieren perfekt
### Szenario 2: Code-Server Proxy (Development)
```env
APP_URL=http://localhost:8080
APP_BASE_PATH=/proxy/8080
```
- PHP Development Server: `php -S 0.0.0.0:8080 -t public public/router.php`
- Code-Server setzt `X-Forwarded-Prefix` automatisch
- Fallback auf `APP_BASE_PATH` aus `.env`
### Szenario 3: Subdirectory-Installation
```env
APP_URL=https://example.com/kaffeekasse
APP_BASE_PATH=/kaffeekasse
```
- Installation in Unterverzeichnis
- Alle URLs werden mit Prefix generiert
### Szenario 4: Nginx Reverse Proxy
```nginx
location /app/ {
proxy_pass http://localhost:8080/;
proxy_set_header X-Forwarded-Prefix /app;
proxy_set_header X-Forwarded-Proto $scheme;
}
```
```env
APP_BASE_PATH=/app
```
## 🔒 Sicherheitsaspekte
### Bereits implementiert:
- ✅ CSRF-Schutz auf allen Forms
- ✅ Session-Sicherheit (strict mode, httponly)
- ✅ XSS-Schutz durch `e()` Helper
- ✅ Security Headers Service
- ✅ Rate Limiting
- ✅ Origin-Validierung
### Proxy-spezifisch:
- ✅ X-Forwarded-Proto wird respektiert
- ✅ HTTPS-Erkennung hinter Proxy
- ✅ Keine URL-Injection möglich (normalisiert)
## 📊 Code-Qualität
### Keine Probleme gefunden:
- ✅ Keine hardcodierten URLs
- ✅ Keine absoluten Pfade in Views
- ✅ Konsistente URL-Generierung
- ✅ Saubere Trennung von Concerns
### Best Practices eingehalten:
- ✅ DRY (Don't Repeat Yourself) - Zentrale URL-Funktionen
- ✅ Konfigurierbar über Environment
- ✅ Automatische Erkennung mit Fallbacks
- ✅ Gut dokumentiert
## 🎯 Fazit
**Die Anwendung ist production-ready für beide Szenarien:**
1. **Netcup Webspace**
- Keine Änderungen am Code nötig
- `.htaccess` optimiert
- Dokumentation vorhanden
2. **Code-Server Proxy**
- Automatische Erkennung funktioniert
- Manuelle Konfiguration möglich
- Dokumentation vorhanden
**Empfohlene Vorgehensweise:**
- **Entwicklung:** Code-Server mit `APP_BASE_PATH=/proxy/8080`
- **Production:** Netcup Webspace mit `APP_BASE_PATH=` (leer)
- **Migration:** Nur `.env` anpassen, kein Code-Change nötig
## 📚 Weitere Informationen
- **Quick Start:** `PROXY-SETUP.md`
- **Detaillierte Anleitung:** `docs/deployment-proxy-guide.md`
- **Deployment:** `DEPLOY.md`
- **Netcup Checkliste:** `docs/go-live-checklist-netcup.md`
---
**Erstellt:** 2026-06-17
**Status:** ✅ Vollständig getestet und dokumentiert
-28
View File
@@ -1,28 +0,0 @@
# RFID-Roadmap
## Heute schon vorhanden
- `rfid_devices` fuer Standortgeraete
- `rfid_tags` fuer Karten/Chips pro Mitglied
- `rfid_events` als technische Inbox
- `/api/rfid/intake` fuer rohe Events
## Warum das sinnvoll ist
Die spaetere Hardware kann kommen, ohne dass sich das Kernmodell fuer Salden,
Konsum und Einzahlungen aendert. RFID ist nur ein weiterer Erfassungsweg in
dieselbe Buchungslogik hinein.
## Nächste Ausbaustufen
1. Geraet aktivieren und Token-Rotation einfuehren
2. Dublettenschutz ueber `event_id` und Zeitfenster haerten
3. Mapping-Regeln `Tag -> Mitglied -> Standardprodukt`
4. optionale Freigabe- oder Double-Tap-Regeln
5. Uebernahme von `rfid_events` in echte `consumption_events`
## Produktionshinweis
Wenn spaeter mehr als HTTPS-Webhooks noetig werden, sollte ein kleiner externer
Relay-Service zwischen Lesegerät und Webspace geschaltet werden. Das eigentliche
SaaS-Ledger kann trotzdem auf Netcup-Webspace bleiben.