stadtwerke/innungsapp/README.md

294 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# InnungsApp
Die digitale Plattform für Innungen — News, Mitgliederverzeichnis, Termine und Lehrlingsbörse.
## Stack
| Schicht | Technologie |
|---|---|
| **Monorepo** | pnpm Workspaces + Turborepo |
| **Mobile App** | Expo (React Native) + Expo Router |
| **Admin Dashboard** | Next.js 15 (App Router) |
| **API** | tRPC v11 |
| **Auth** | better-auth (Magic Links) |
| **Datenbank** | PostgreSQL + Prisma ORM |
| **Styling Mobile** | NativeWind v4 (Tailwind CSS) |
| **Styling Admin** | Tailwind CSS |
| **State Management** | Zustand (Mobile) + React Query (beide Apps) |
## Projekt-Struktur
```
innungsapp/
├── apps/
│ ├── mobile/ # Expo React Native App (iOS + Android)
│ └── admin/ # Next.js Admin Dashboard
├── packages/
│ └── shared/ # TypeScript-Typen + Prisma Client
└── ...
```
## Setup
### Voraussetzungen
- Node.js >= 20
- pnpm >= 9
- PostgreSQL-Datenbank
- SMTP-Server (für Magic Links)
### 1. Abhängigkeiten installieren
```bash
pnpm install
```
### 2. Umgebungsvariablen
```bash
cp .env.example apps/admin/.env.local
# .env.local befüllen (DATABASE_URL, BETTER_AUTH_SECRET, SMTP_*)
```
### 3. Datenbank einrichten
```bash
# Prisma Client generieren
pnpm db:generate
# Migrationen anwenden
pnpm db:migrate
# Demo-Daten einspielen (optional)
pnpm db:seed
```
### 4. Entwicklung starten
```bash
# Admin Dashboard (http://localhost:3000)
pnpm --filter @innungsapp/admin dev
# Mobile App (Expo DevTools)
pnpm --filter @innungsapp/mobile dev
```
Oder alles parallel:
```bash
pnpm dev
```
## Datenbank-Schema
Das Schema befindet sich in `packages/shared/prisma/schema.prisma`.
Wichtige Tabellen:
- `organizations` — Innungen (Multi-Tenancy)
- `members` — Mitglieder (verknüpft mit Auth-User nach Einladung)
- `user_roles` — Berechtigungen (admin | member)
- `news`, `news_reads`, `news_attachments` — News-System
- `termine`, `termin_anmeldungen` — Terminverwaltung
- `stellen` — Lehrlingsbörse (öffentlich lesbar)
## Auth-Flow
1. **Admin einrichten:** Seed-Daten oder manuell in der DB
2. **Mitglied einladen:** Admin erstellt Mitglied → "Einladung senden" → Magic Link per E-Mail
3. **Mitglied loggt ein:** Magic Link → Session → App-Zugang
## API (tRPC)
Alle API-Endpunkte sind typsicher über tRPC definiert:
- `organizations.*` — Org-Einstellungen, Stats, AVV
- `members.*` — CRUD, Einladungen
- `news.*` — CRUD, Lesestatus, Push-Benachrichtigungen
- `termine.*` — CRUD, Anmeldungen
- `stellen.*` — Public + Auth-geschützte Endpunkte
## Deployment
### Admin — Docker (empfohlen für Self-Hosting)
**Voraussetzungen:** Docker + Docker Compose auf dem Server installiert.
#### Schritt 1: Repository klonen
```bash
git clone <repo-url>
cd innungsapp
```
#### Schritt 2: Umgebungsvariablen anlegen
```bash
cp .env.production.example .env
```
Dann `.env` öffnen und **alle Werte** befüllen:
| Variable | Beschreibung |
|---|---|
| `BETTER_AUTH_SECRET` | Zufälliger String (min. 32 Zeichen) — z.B. `openssl rand -hex 32` |
| `BETTER_AUTH_URL` | Öffentliche URL der App, z.B. `https://app.deine-innung.de` |
| `NEXT_PUBLIC_APP_URL` | Gleicher Wert wie `BETTER_AUTH_URL` |
| `EMAIL_FROM` | Absender-Adresse für Magic Links |
| `SMTP_HOST` | SMTP-Server-Adresse |
| `SMTP_PORT` | Meistens `587` (STARTTLS) oder `465` (SSL) |
| `SMTP_USER` | SMTP-Benutzername |
| `SMTP_PASS` | SMTP-Passwort |
#### Schritt 3: Container bauen und starten
```bash
docker compose up -d --build
```
Der Build dauert beim ersten Mal ~23 Minuten. Danach läuft die App auf **Port 3000**.
Logs prüfen:
```bash
docker compose logs -f admin
```
#### Schritt 4: Superadmin anlegen (nur beim ersten Start)
```bash
docker compose exec admin node -e "
const { PrismaClient } = require('@prisma/client');
const { scryptSync, randomBytes } = require('crypto');
const prisma = new PrismaClient();
// Superadmin wird via seed-superadmin.ts angelegt
"
```
Einfacher: Den Seed direkt ausführen:
```bash
docker compose exec -w /app admin \
node packages/shared/prisma/seed-superadmin.js
```
> Standard-Login nach Seed: `superadmin@innungsapp.de` / `demo1234`
> **Passwort sofort in den Einstellungen ändern!**
#### Schritt 5: Reverse Proxy (HTTPS)
Nginx-Beispielkonfiguration für `app.deine-innung.de`:
```nginx
server {
listen 80;
server_name app.deine-innung.de;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name app.deine-innung.de;
ssl_certificate /etc/letsencrypt/live/app.deine-innung.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.deine-innung.de/privkey.pem;
client_max_body_size 20M;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
```
SSL-Zertifikat mit Certbot:
```bash
certbot --nginx -d app.deine-innung.de
```
#### Updates einspielen
```bash
git pull
docker compose up -d --build
```
Datenbank und Uploads bleiben dabei erhalten (Docker Volumes).
#### Häufige Befehle
```bash
# Status prüfen
docker compose ps
# Logs ansehen
docker compose logs -f admin
# Container neustarten
docker compose restart admin
# In Container einloggen
docker compose exec admin sh
# App stoppen
docker compose down
# App stoppen + Daten löschen (Vorsicht!)
docker compose down -v
```
---
### Admin — Vercel (Alternative)
```bash
# Umgebungsvariablen in Vercel setzen:
# DATABASE_URL, BETTER_AUTH_SECRET, BETTER_AUTH_URL, SMTP_*
vercel --cwd apps/admin
```
### Mobile (EAS Build)
```bash
cd apps/mobile
eas build --platform all --profile production
eas submit --platform all
```
## DSGVO / AVV
- AVV-Akzeptanz in Admin → Einstellungen (Pflichtfeld vor Go-Live)
- Alle personenbezogenen Daten in EU-Region (Datenbankserver in Deutschland empfohlen)
- Keine Daten an Dritte außer Expo Push API (anonymisierte Token)
## Roadmap
Siehe `innung-app-mvp.md` für die vollständige Roadmap.
## Apps starten (Schnellstart)
Um die Anwendungen lokal zu starten, öffne ein Terminal im Hauptverzeichnis (`innungsapp/`) und nutze folgende Befehle:
**Admin Dashboard starten:**
```bash
pnpm --filter @innungsapp/admin dev
```
Das Dashboard ist im Browser unter [http://localhost:3000](http://localhost:3000) erreichbar.
**Mobile App starten:**
```bash
pnpm --filter @innungsapp/mobile dev
```
Dies startet den Expo-Server. Scanne den QR-Code mit der **Expo Go App** auf deinem Smartphone oder drücke `a` (für den Android Emulator) bzw. `i` (für den iOS Simulator) im Terminal.
**Beides gleichzeitig starten:**
```bash
pnpm dev
```