290 lines
9.5 KiB
Markdown
290 lines
9.5 KiB
Markdown
# Stargirlnails Kiel - Nail Salon Booking System
|
||
|
||
Ein vollständiges Buchungssystem für Nagelstudios mit Admin-Panel, Kalender und E-Mail-Benachrichtigungen.
|
||
|
||
## Dependencies
|
||
|
||
- [TypeScript](https://www.typescriptlang.org/)
|
||
- [React](https://react.dev/)
|
||
- [Vite](https://vite.dev/)
|
||
- [Tailwind CSS V4](https://tailwindcss.com/)
|
||
- [oRPC](https://orpc.unnoq.com/)
|
||
- [Hono](https://hono.dev/)
|
||
- [Zod](https://zod.dev/)
|
||
|
||
> Hinweis zu DOMPurify: Wir nutzen `isomorphic-dompurify`, das DOMPurify bereits mitliefert und sowohl in Node.js als auch im Browser funktioniert. Eine zusätzliche Installation von `dompurify` ist daher nicht erforderlich und würde eine redundante Abhängigkeit erzeugen.
|
||
|
||
## Setup
|
||
|
||
### 1. Umgebungsvariablen konfigurieren
|
||
|
||
Kopiere die `.env.example` Datei zu `.env` und konfiguriere deine Umgebungsvariablen:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
### 2. Admin-Passwort Hash generieren (bcrypt)
|
||
|
||
Das Admin-Passwort wird als bcrypt-Hash in der `.env` Datei gespeichert. So erzeugst du einen Hash:
|
||
|
||
#### Node.js (empfohlen)
|
||
```bash
|
||
node -e "require('bcrypt').hash('dein_sicheres_passwort', 10).then(console.log)"
|
||
```
|
||
|
||
Alternativ kannst du ein kleines Script verwenden (falls du es öfter brauchst):
|
||
|
||
```javascript
|
||
// scripts/generate-hash.js
|
||
require('bcrypt').hash(process.argv[2] || 'dein_sicheres_passwort', 10).then(h => {
|
||
console.log(h);
|
||
});
|
||
```
|
||
|
||
Ausführen:
|
||
```bash
|
||
node scripts/generate-hash.js "dein_sicheres_passwort"
|
||
```
|
||
|
||
### 3. .env Datei konfigurieren
|
||
|
||
Bearbeite deine `.env` Datei und setze die generierten Werte:
|
||
|
||
```env
|
||
# Admin Account Configuration
|
||
ADMIN_USERNAME=owner
|
||
# bcrypt-Hash des Admin-Passworts (kein Base64). Beispielwert:
|
||
ADMIN_PASSWORD_HASH=$2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
|
||
|
||
# Domain Configuration
|
||
DOMAIN=localhost:5173 # Für Produktion: deine-domain.de
|
||
|
||
# Email Configuration
|
||
RESEND_API_KEY=your_resend_api_key_here
|
||
EMAIL_FROM=noreply@yourdomain.com
|
||
ADMIN_EMAIL=admin@yourdomain.com
|
||
|
||
# Stornierungsfrist (in Stunden)
|
||
MIN_STORNO_TIMESPAN=24
|
||
|
||
# Legal Information (Impressum/Datenschutz)
|
||
COMPANY_NAME=Stargirlnails Kiel
|
||
OWNER_NAME=Inhaber Name
|
||
ADDRESS_STREET=Liebigstr. 15
|
||
ADDRESS_CITY=Kiel
|
||
ADDRESS_POSTAL_CODE=24145
|
||
ADDRESS_COUNTRY=Deutschland
|
||
ADDRESS_LATITUDE=54.3233 # Optional: GPS-Koordinaten für Karte
|
||
ADDRESS_LONGITUDE=10.1228 # Optional: GPS-Koordinaten für Karte
|
||
CONTACT_PHONE=+49 431 123456
|
||
CONTACT_EMAIL=info@stargirlnails.de
|
||
TAX_ID=12/345/67890 # Optional
|
||
VAT_ID=DE123456789 # Optional
|
||
COMMERCIAL_REGISTER=HRB 12345 # Optional
|
||
RESPONSIBLE_FOR_CONTENT=Inhaber Name
|
||
DATA_PROTECTION_RESPONSIBLE=Inhaber Name
|
||
DATA_PROTECTION_EMAIL=datenschutz@stargirlnails.de
|
||
THIRD_PARTY_SERVICES=Resend (E-Mail-Versand),Google Analytics # Komma-getrennt
|
||
```
|
||
|
||
### 4. Anwendung starten
|
||
|
||
```bash
|
||
# Dependencies installieren
|
||
pnpm install
|
||
|
||
# Entwicklungsserver starten
|
||
pnpm dev
|
||
```
|
||
|
||
## Docker Deployment
|
||
|
||
### Lokale Entwicklung mit Docker
|
||
|
||
Für schnelles lokales Testing mit vorgebauten Artefakten:
|
||
|
||
```bash
|
||
# 1. Baue Client und Server lokal
|
||
pnpm install --frozen-lockfile
|
||
pnpm run build
|
||
|
||
# 2. Baue und starte Container (nutzt production-prebuilt Stage)
|
||
docker compose build
|
||
docker compose up -d
|
||
```
|
||
|
||
### Production-Deployment
|
||
|
||
Für Remote-Deployment (baut alles im Container):
|
||
|
||
```bash
|
||
# Nutzt production Stage für vollständigen Build
|
||
docker-compose -f docker-compose-prod.yml up --build -d
|
||
```
|
||
|
||
**Wichtig:** `docker-compose-prod.yml` baut Client und Server im Container und benötigt keine lokalen Builds.
|
||
|
||
### Docker Build-Stages
|
||
|
||
Das Dockerfile definiert zwei relevante Workflows:
|
||
- `production`: Vollständiger Build (Client + Server) innerhalb von Docker – langsamer, ideal für CI/CD
|
||
- `production-prebuilt`: Lokaler Build der Artefakte (`dist/`, `server-dist/`) und Kopie in das Image – schneller für lokale Entwicklung
|
||
|
||
Warum `dist/` und `server-dist/` nicht in `.dockerignore` gehören: Diese Verzeichnisse werden im `production-prebuilt`-Workflow benötigt, damit sie beim `docker compose build` in das Image kopiert werden können.
|
||
|
||
Details siehe [`docs/docker-build-stages.md`](docs/docker-build-stages.md)
|
||
|
||
### Native Module Hinweise (bcrypt)
|
||
|
||
Die App verwendet das native Node-Modul `bcrypt`, das für Alpine Linux kompiliert werden muss.
|
||
|
||
- Beim ersten Start oder nach Dependency-Updates kann ein Rebuild notwendig sein.
|
||
- In der `production` Stage wird `bcrypt` während des Docker-Builds kompiliert und verifiziert.
|
||
- In der `production-prebuilt` Stage erfolgt eine Verifikation/Rebuild beim Container-Start, und der Start bricht ab, wenn `bcrypt` fehlt.
|
||
|
||
Siehe ausführliche Hinweise und Troubleshooting in [`docs/docker-build-stages.md`](docs/docker-build-stages.md).
|
||
|
||
### Docker Compose (empfohlen)
|
||
|
||
Erstelle eine `docker-compose.yml` Datei:
|
||
|
||
```yaml
|
||
services:
|
||
stargirlnails:
|
||
build: .
|
||
ports:
|
||
- "3000:3000"
|
||
env_file:
|
||
- .env
|
||
restart: unless-stopped
|
||
volumes:
|
||
- ./.storage:/app/.storage
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 40s
|
||
```
|
||
|
||
Starten mit Docker Compose:
|
||
|
||
```bash
|
||
# Container starten
|
||
docker-compose up -d
|
||
|
||
# Logs anzeigen
|
||
docker-compose logs -f
|
||
|
||
# Container stoppen
|
||
docker-compose down
|
||
```
|
||
|
||
### Produktions-Deployment
|
||
|
||
Für den produktiven Einsatz mit automatischem SSL:
|
||
|
||
```bash
|
||
# Mit Docker Compose (empfohlen)
|
||
docker-compose -f docker-compose-prod.yml up -d
|
||
|
||
# Oder mit dem Caddy-Setup-Script
|
||
chmod +x scripts/setup-caddy.sh
|
||
./scripts/setup-caddy.sh
|
||
```
|
||
|
||
**Wichtige Produktions-Hinweise:**
|
||
- Verwende eine `.env.production` Datei mit Produktions-Konfiguration
|
||
- Setze `NODE_ENV=production` in der Umgebungsdatei
|
||
- **Automatisches SSL**: Caddy erstellt und verwaltet automatisch Let's Encrypt-Zertifikate
|
||
- Überwache Container mit Health Checks
|
||
- **Persistente Daten**: Der `.storage` Ordner wird als Volume gemountet, um Buchungen und Einstellungen zu erhalten
|
||
|
||
### Docker-Container startet nicht
|
||
|
||
**Symptom:** Container startet mit "Cannot find module" Fehlern
|
||
|
||
**Lösung:**
|
||
- Lokal: Stelle sicher, dass `pnpm build` vor `docker-compose up` ausgeführt wurde
|
||
- Production: Prüfe, dass `docker-compose-prod.yml` den `target: production` verwendet
|
||
- Siehe [`docs/docker-build-stages.md`](docs/docker-build-stages.md) für Details
|
||
- Nach Sicherheits- oder Dependency-Updates: `docker compose down && docker compose build --no-cache && docker compose up -d`
|
||
- Verifikation: `docker compose exec stargirlnails node -e "require('bcrypt')"`
|
||
|
||
### Development-Workflow mit nativen Modulen
|
||
|
||
Wenn du ein natives Modul wie `bcrypt` hinzufügst oder updatest, ist ein Container-Rebuild erforderlich. Nutze dafür die Scripts:
|
||
|
||
```bash
|
||
# Linux/macOS
|
||
./scripts/rebuild-dev.sh
|
||
|
||
# Windows
|
||
scripts\rebuild-dev.cmd
|
||
```
|
||
|
||
## Features
|
||
|
||
### Buchungssystem
|
||
- 📅 **Terminbuchung**: Kunden können online Termine buchen
|
||
- 💅 **Behandlungsverwaltung**: Admin kann Behandlungen hinzufügen/bearbeiten
|
||
- 📆 **Kalender-Ansicht**: Übersichtliche Darstellung aller Termine
|
||
- ⏰ **Verfügbarkeits-Slots**: Flexible Slot-Verwaltung mit behandlungsspezifischen Dauern
|
||
- ❌ **Termin-Stornierung**: Kunden können Termine über sichere Links stornieren
|
||
- ⏰ **Stornierungsfrist**: Konfigurierbare Mindestfrist vor dem Termin (MIN_STORNO_TIMESPAN)
|
||
|
||
### E-Mail & Benachrichtigungen
|
||
- 📧 **E-Mail-Benachrichtigungen**: Automatische Benachrichtigungen bei Buchungen
|
||
- 📅 **ICS-Kalendereinträge**: Termin-Bestätigungen mit ICS-Datei zum Importieren in Kalender-Apps
|
||
- ⏰ **Kalender-Erinnerungen**: 24h-Erinnerung im ICS-Kalendereintrag
|
||
- 📎 **AGB-Anhänge**: Automatischer PDF-Anhang der Allgemeinen Geschäftsbedingungen
|
||
|
||
### Sicherheit
|
||
- 🛡️ **Rate-Limiting**: IP- und E-Mail-basierter Schutz gegen Spam (3 Anfragen/E-Mail pro Stunde, 5 Anfragen/IP pro 10 Min)
|
||
- ✉️ **E-Mail-Validierung**: Mehrschichtige Validierung inkl. Disposable-Email-Detection und MX-Record-Prüfung
|
||
- 🚫 **Wegwerf-Email-Schutz**: Blockierung von temporären E-Mail-Adressen
|
||
- 🔐 **Admin-Panel**: Geschützter Bereich für Inhaber
|
||
- 🛡️ **Security.txt**: RFC 9116 konformer Endpoint für Sicherheitsmeldungen
|
||
|
||
### Rechtliches
|
||
- 📋 **Impressum/Datenschutz**: Rechtliche Seiten mit konfigurierbaren Daten
|
||
- ⚖️ **GDPR-konform**: Datenschutzfreundliche Implementierung
|
||
|
||
## Admin-Zugang
|
||
|
||
Nach dem Setup kannst du dich mit den in der `.env` konfigurierten Admin-Credentials anmelden:
|
||
- **Benutzername**: Wert aus `ADMIN_USERNAME`
|
||
- **Passwort**: Das ursprüngliche Passwort (nicht der Hash)
|
||
|
||
## Sicherheit
|
||
|
||
⚠️ **Wichtige Hinweise:**
|
||
- Ändere das Standard-Passwort vor dem Produktionseinsatz
|
||
- Das Passwort wird als bcrypt-Hash in der `.env` Datei gespeichert
|
||
- Verwende ein sicheres Passwort und generiere den entsprechenden Hash
|
||
- Die `.env` Datei sollte niemals in das Repository committet werden
|
||
|
||
Hinweis zur Migration: Vorhandene Base64-Hashes aus älteren Versionen werden beim Server-Start automatisch in bcrypt migriert. Zusätzlich erfolgt beim nächsten erfolgreichen Login ebenfalls eine Migration, falls noch erforderlich.
|
||
|
||
### Security.txt Endpoint
|
||
|
||
Die Anwendung bietet einen RFC 9116 konformen Security.txt Endpoint unter `/.well-known/security.txt`:
|
||
|
||
- **Kontakt**: Konfigurierbar über `SECURITY_CONTACT` Umgebungsvariable
|
||
- **Ablauf**: Automatisch gesetzt auf Ende des aktuellen Jahres
|
||
- **Sprachen**: Deutsch und Englisch bevorzugt
|
||
- **Caching**: 24 Stunden Cache-Header für bessere Performance
|
||
|
||
**Beispiel-Konfiguration:**
|
||
```env
|
||
SECURITY_CONTACT=security@stargirlnails.de
|
||
```
|
||
|
||
**Zugriff:**
|
||
```bash
|
||
curl https://your-domain.com/.well-known/security.txt
|
||
```
|
||
|
||
Dies ermöglicht Sicherheitsforschern, Sicherheitslücken verantwortungsvoll zu melden.
|