renew
This commit is contained in:
@@ -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`
|
||||
@@ -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/
|
||||
@@ -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/
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user