Rebuild as InnungsApp project: replace stadtwerke analysis with full documentation

- PRD: vollständige Produktspezifikation (5 Module, Scope, Akzeptanzkriterien)
- ARCHITECTURE: Tech Stack, Ordnerstruktur, Multi-Tenancy, Push, Kosten
- DATABASE_SCHEMA: Vollständiges SQL-Schema mit RLS Policies und Views
- USER_STORIES: 40+ Stories nach Rolle (Admin, Mitglied, Azubi, Obermeister)
- PERSONAS: 5 detaillierte Nutzerprofile mit Alltag, Zitaten und Erwartungen
- BUSINESS_MODEL: Preistabellen, Unit Economics, Revenue-Projektionen, Distribution
- ROADMAP: 6 Phasen, Sprint-Planung, Meilensteine und KPIs
- COMPETITIVE_ANALYSIS: Wettbewerbsmatrix, USPs, Preispositionierung
- API_DESIGN: Supabase Query Patterns, Edge Functions, Realtime Subscriptions
- ONBOARDING_FLOWS: 7 User Flows von Setup bis Fehlerfall
- GTM_STRATEGY: 3-Phasen-Vertrieb, Outreach-Sequenz, Einwandbehandlung
- AZUBI_MODULE: Video-Feed, 1-Click-Apply, Chat, Berichtsheft, Quiz
- DSGVO_KONZEPT: Rechtsgrundlagen, TOMs, AVV, Minderjährige, Incident Response
- FEATURES_BACKLOG: 72 Features nach MoSCoW + Technische Schulden

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Timo Knuth
2026-02-18 19:03:37 +01:00
parent fc68285cf1
commit fca42db4d2
116 changed files with 9329 additions and 6479 deletions

341
ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,341 @@
# InnungsApp — Technische Architektur
> **Version:** 1.0 | **Stand:** Februar 2026
---
## 1. Überblick
InnungsApp besteht aus drei Hauptkomponenten:
```
┌─────────────────────────────────────────────────────────────┐
│ CLIENTS │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Mobile App │ │ Admin Web App │ │
│ │ (React Native) │ │ (Next.js) │ │
│ │ iOS + Android │ │ Browser │ │
│ └────────┬────────┘ └────────┬────────┘ │
└───────────┼────────────────────┼──────────────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ SUPABASE │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
│ │ Auth │ │ Postgres │ │ Storage │ │ Realtime │ │
│ │ Magic │ │ + RLS │ │ PDFs │ │ Push + │ │
│ │ Link │ │ Database │ │ Images │ │ Events │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ EXTERNE DIENSTE │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
│ │ Expo │ │ Resend │ │ PostHog │ │ Mux │ │
│ │ Push │ │ E-Mail │ │ Analytics│ │ Video │ │
│ │ (FCM/APNs│ │ Transact.│ │ │ │ (Q2) │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────────┘ │
└─────────────────────────────────────────────────────────────┘
```
---
## 2. Mobile App (React Native + Expo)
### Tech Stack
| Schicht | Technologie | Begründung |
|---|---|---|
| Framework | React Native 0.74 + Expo SDK 51 | Eine Codebasis iOS + Android |
| Navigation | Expo Router v3 (file-based) | Typ-sicher, einfach wartbar |
| State Management | Zustand | Leichtgewichtig, kein Redux-Overhead |
| Data Fetching | TanStack Query v5 | Caching, Background Refetch, Optimistic Updates |
| UI-Komponenten | Custom + NativeWind (Tailwind on Native) | Konsistentes Design, schnelle Entwicklung |
| Push Notifications | Expo Notifications + FCM/APNs | Out-of-the-box mit Expo |
| Auth | Supabase Auth Client | Magic Link Flow |
| Type Safety | TypeScript (strict mode) | Pflicht für Produktionscode |
### Ordnerstruktur
```
apps/mobile/
├── app/ # Expo Router — File-based Navigation
│ ├── (auth)/
│ │ ├── login.tsx # Magic Link Login Screen
│ │ └── verify.tsx # Token Verification
│ ├── (tabs)/
│ │ ├── _layout.tsx # Tab Bar Layout
│ │ ├── index.tsx # Dashboard / Home Feed
│ │ ├── members.tsx # Mitgliederverzeichnis
│ │ ├── news.tsx # Mitteilungen Feed
│ │ ├── termine.tsx # Terminkalender
│ │ └── stellen.tsx # Lehrlingsbörse
│ ├── member/[id].tsx # Mitglied Detailansicht
│ ├── news/[id].tsx # Beitrag Detailansicht
│ ├── termin/[id].tsx # Termin Detailansicht
│ └── _layout.tsx # Root Layout (Auth Guard)
├── components/
│ ├── ui/ # Atomare UI-Komponenten
│ │ ├── Button.tsx
│ │ ├── Card.tsx
│ │ ├── Badge.tsx
│ │ ├── Avatar.tsx
│ │ └── Input.tsx
│ ├── members/ # Feature-spezifische Komponenten
│ ├── news/
│ ├── termine/
│ └── stellen/
├── hooks/
│ ├── useAuth.ts
│ ├── useMembers.ts
│ ├── useNews.ts
│ └── usePushNotifications.ts
├── lib/
│ ├── supabase.ts # Supabase Client Singleton
│ ├── queryClient.ts # TanStack Query Client
│ └── notifications.ts # Push Token Registration
├── store/
│ └── auth.ts # Zustand Auth Store
├── types/
│ └── database.ts # Generierte Supabase Types
└── constants/
├── colors.ts # Design Tokens
└── config.ts # Env-Variablen
```
---
## 3. Admin Web App (Next.js)
### Tech Stack
| Schicht | Technologie |
|---|---|
| Framework | Next.js 14 (App Router) |
| Styling | Tailwind CSS + shadcn/ui |
| Auth | Supabase Auth (SSR) |
| Data Fetching | Server Components + TanStack Query (Client) |
| Tables | TanStack Table v8 |
| Forms | React Hook Form + Zod |
| Charts | Recharts |
| Deployment | Vercel |
### Ordnerstruktur
```
apps/admin/
├── app/
│ ├── (auth)/
│ │ └── login/page.tsx
│ ├── (dashboard)/
│ │ ├── layout.tsx # Sidebar Layout
│ │ ├── page.tsx # Overview Dashboard
│ │ ├── members/
│ │ │ ├── page.tsx # Mitgliederliste
│ │ │ ├── new/page.tsx # Mitglied anlegen
│ │ │ └── [id]/page.tsx # Mitglied bearbeiten
│ │ ├── news/
│ │ │ ├── page.tsx
│ │ │ └── new/page.tsx
│ │ ├── termine/
│ │ ├── stellen/
│ │ └── settings/
│ └── layout.tsx
├── components/
│ ├── ui/ # shadcn/ui Komponenten
│ ├── data-table/
│ └── forms/
└── lib/
├── supabase-server.ts # Supabase SSR Client
└── actions.ts # Server Actions
```
---
## 4. Backend: Supabase
### Warum Supabase?
- **Kein eigener API-Server** nötig für MVP → spart 46 Wochen Entwicklung
- **PostgreSQL** mit vollem SQL-Zugriff → keine NoSQL-Kompromisse
- **Row Level Security** → Multi-Tenancy ohne eigene Middleware
- **Realtime** → Live-Updates ohne WebSocket-Implementierung
- **Storage** → S3-kompatibel, CDN included
- **Auth** → Magic Link, Sessions, JWT out-of-the-box
- **EU-Region Frankfurt** → DSGVO-konform
### Supabase Services genutzt
| Service | Verwendung |
|---|---|
| Auth | Magic Link Login, Session-Management, JWT |
| Database | PostgreSQL, alle Tabellen |
| Row Level Security | Multi-Tenancy, Datenisolation |
| Storage | PDF-Anhänge, Profilbilder, Logos |
| Realtime | Live-Updates (News Feed, Teilnehmerlisten) |
| Edge Functions | Komplexe Businesslogik (Einladungs-E-Mails) |
---
## 5. Multi-Tenancy Konzept
### Datenisolation via Row Level Security (RLS)
Jede Innung ist eine `organization`. Alle Tabellen haben eine `org_id` Spalte.
```sql
-- Beispiel RLS Policy für die members-Tabelle
CREATE POLICY "members_isolation" ON members
FOR ALL
USING (org_id = (
SELECT org_id FROM user_roles
WHERE user_id = auth.uid()
));
```
**Prinzip:**
- Kein Nutzer sieht Daten außerhalb seiner `org_id`
- Policy wird für jede Operation (SELECT, INSERT, UPDATE, DELETE) durchgesetzt
- Supabase prüft dies auf Datenbankebene — kein Bypass möglich
### Tenancy Identifikation
- **MVP:** `org_id` wird beim Login aus `user_roles` geladen und in allen Queries mitgegeben
- **Post-MVP:** Subdomain-Routing (`innung-elektro-stuttgart.innungsapp.de`) mit Middleware-Lookup
---
## 6. Authentifizierung
### Login Flow
```
Nutzer gibt E-Mail ein
Supabase sendet Magic Link
Nutzer klickt Link im E-Mail
App/Browser öffnet sich, Token wird verarbeitet
Supabase Auth gibt Session zurück (JWT)
App lädt user_roles → bestimmt org_id und Rolle
Redirect zu korrekter Startseite
```
### Rollen-System
```sql
CREATE TYPE user_role AS ENUM ('admin', 'member', 'public');
CREATE TABLE user_roles (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid REFERENCES auth.users NOT NULL,
org_id uuid REFERENCES organizations NOT NULL,
role user_role NOT NULL DEFAULT 'member',
created_at timestamptz DEFAULT now(),
UNIQUE(user_id, org_id)
);
```
---
## 7. Push Notifications
### Architektur
```
Admin erstellt Beitrag
Supabase Edge Function wird getriggert (via Database Webhook)
Edge Function fetcht alle Push Tokens der org_id
Expo Push Notification Service (EPNS)
┌──┴──┐
▼ ▼
APNs FCM
(iOS) (Android)
```
### Push Token Registrierung (Mobile)
```typescript
// hooks/usePushNotifications.ts
async function registerPushToken() {
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') return;
const token = await Notifications.getExpoPushTokenAsync({
projectId: Constants.expoConfig.extra.eas.projectId,
});
await supabase
.from('push_tokens')
.upsert({ user_id: user.id, token: token.data });
}
```
---
## 8. Infrastruktur & Kosten
### Monatliche Kosten (MVP, bis 100 Innungen)
| Service | Plan | Kosten/Monat |
|---|---|---|
| Supabase | Pro | 25 € |
| Vercel | Pro | 20 € |
| Resend (E-Mail) | Starter | 0 € (bis 3.000 Mails) |
| Expo EAS Build | Production | 29 € |
| PostHog | Cloud | 0 € (bis 1 Mio. Events) |
| Apple Developer | (jährlich) | 8 € |
| **Gesamt** | | **~82 €/Monat** |
### Skalierung (ab 500 Innungen)
| Service | Plan | Kosten/Monat |
|---|---|---|
| Supabase | Team | 599 € |
| Vercel | Enterprise | ~400 € |
| Resend | Business | 89 € |
| **Gesamt** | | **~1.100 €/Monat** |
Break-even bei 6 zahlenden Innungen à 200 €.
---
## 9. Deployment & CI/CD
### Pipeline
```
git push → GitHub/Gitea
├── Mobile: Expo EAS Build (iOS + Android)
│ └── App Store / Play Store (manual submit)
└── Web Admin: Vercel Deploy (automatisch)
└── Preview URL für jeden Branch
```
### Environments
| Environment | Supabase | Vercel | Verwendung |
|---|---|---|---|
| `development` | Lokal (Docker) | localhost:3000 | Entwicklung |
| `staging` | Staging-Projekt | staging.innungsapp.de | Pilot-Tests |
| `production` | Pro-Projekt | app.innungsapp.de | Live |