diff --git a/API_DESIGN.md b/API_DESIGN.md new file mode 100644 index 0000000..726a3e7 --- /dev/null +++ b/API_DESIGN.md @@ -0,0 +1,492 @@ +# InnungsApp — API Design + +> Supabase stellt die API automatisch via PostgREST bereit. Dieses Dokument beschreibt die wichtigsten Query-Patterns und Edge Functions. + +--- + +## 1. Basis-URL & Auth + +``` +Base URL: https://.supabase.co +REST API: /rest/v1/ +Auth API: /auth/v1/ +Storage API: /storage/v1/ +Edge Functions: /functions/v1/ + +Headers: + apikey: # Öffentliche Requests + Authorization: Bearer # Authentifizierte Requests +``` + +--- + +## 2. Auth Endpoints + +### Magic Link anfordern + +```http +POST /auth/v1/otp +Content-Type: application/json + +{ + "email": "max.muster@muellerszdk.de", + "options": { + "emailRedirectTo": "innungsapp://auth/verify" + } +} +``` + +### Session mit Token verifizieren (nach Link-Klick) + +```typescript +const { data, error } = await supabase.auth.verifyOtp({ + token_hash: params.token_hash, + type: 'magiclink' +}); +``` + +### Aktuelle Session + +```typescript +const { data: { session } } = await supabase.auth.getSession(); +``` + +### Logout + +```typescript +await supabase.auth.signOut(); +``` + +--- + +## 3. Members API + +### Alle Mitglieder einer Innung abrufen + +```typescript +// RLS filtert automatisch nach org_id des eingeloggten Users +const { data, error } = await supabase + .from('members') + .select('id, vorname, nachname, betrieb, sparte, ort, telefon, email, status, ausbildungsbetrieb') + .eq('status', 'aktiv') + .order('nachname'); +``` + +### Mitglieder suchen (Volltext) + +```typescript +const { data } = await supabase + .from('members') + .select('*') + .or(`nachname.ilike.%${query}%,betrieb.ilike.%${query}%,ort.ilike.%${query}%`) + .eq('status', 'aktiv'); +``` + +### Mitglied nach Sparte filtern + +```typescript +const { data } = await supabase + .from('members') + .select('*') + .eq('sparte', 'Elektrotechnik') + .eq('status', 'aktiv'); +``` + +### Mitglied anlegen (Admin only) + +```typescript +const { data, error } = await supabase + .from('members') + .insert({ + org_id: currentOrgId, + vorname: 'Max', + nachname: 'Müller', + betrieb: 'Müller Sanitär GmbH', + sparte: 'SHK', + email: 'max@mueller-sanitaer.de', + telefon: '0711-123456', + ort: 'Stuttgart', + status: 'aktiv', + ausbildungsbetrieb: true, + mitglied_seit: 2015 + }); +``` + +### Mitglied aktualisieren + +```typescript +const { error } = await supabase + .from('members') + .update({ status: 'ausgetreten' }) + .eq('id', memberId); +``` + +--- + +## 4. News API + +### News Feed (veröffentlichte Beiträge) + +```typescript +const { data } = await supabase + .from('news') + .select(` + id, title, body, kategorie, published_at, pinned, + author:members(vorname, nachname, betrieb), + attachments:news_attachments(id, filename, storage_url), + read:news_reads(read_at) + `) + .not('published_at', 'is', null) + .lte('published_at', new Date().toISOString()) + .order('pinned', { ascending: false }) + .order('published_at', { ascending: false }) + .limit(20); +``` + +### Beitrag als gelesen markieren + +```typescript +const { error } = await supabase + .from('news_reads') + .upsert({ + news_id: newsId, + user_id: userId + }, { onConflict: 'news_id,user_id' }); +``` + +### Beitrag mit Leserate (Admin) + +```typescript +const { data } = await supabase + .from('news_with_stats') // VIEW + .select('*') + .order('published_at', { ascending: false }); +``` + +### Beitrag erstellen (Admin) + +```typescript +const { data: news } = await supabase + .from('news') + .insert({ + org_id: currentOrgId, + title: 'Wichtige Mitteilung: Jahreshauptversammlung', + body: '## Einladung\n\nWir laden alle Mitglieder...', + kategorie: 'Veranstaltung', + published_at: new Date().toISOString() // oder null für Entwurf + }) + .select() + .single(); +``` + +--- + +## 5. Termine API + +### Kommende Termine + +```typescript +const { data } = await supabase + .from('termine_with_counts') // VIEW + .select('*') + .gte('datum', new Date().toISOString().split('T')[0]) + .order('datum'); +``` + +### Anmeldung für Termin + +```typescript +const { error } = await supabase + .from('termine_anmeldungen') + .insert({ + termin_id: terminId, + member_id: memberId + }); +``` + +### Abmeldung von Termin + +```typescript +const { error } = await supabase + .from('termine_anmeldungen') + .delete() + .match({ termin_id: terminId, member_id: memberId }); +``` + +### Anmeldestatus prüfen + +```typescript +const { data } = await supabase + .from('termine_anmeldungen') + .select('id, angemeldet_at') + .match({ termin_id: terminId, member_id: memberId }) + .maybeSingle(); + +const isAngemeldet = !!data; +``` + +### iCal-Export generieren (Client-seitig) + +```typescript +function generateICalEvent(termin: Termin): string { + return `BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//InnungsApp//DE +BEGIN:VEVENT +UID:${termin.id}@innungsapp.de +DTSTART:${termin.datum.replace(/-/g, '')}T${termin.uhrzeit_von?.replace(/:/g, '') || '080000'} +DTEND:${termin.datum.replace(/-/g, '')}T${termin.uhrzeit_bis?.replace(/:/g, '') || '100000'} +SUMMARY:${termin.titel} +LOCATION:${termin.ort || ''} +DESCRIPTION:${termin.beschreibung || ''} +END:VEVENT +END:VCALENDAR`; +} +``` + +--- + +## 6. Stellen (Lehrlingsbörse) API + +### Alle aktiven Stellen (öffentlich, kein Login) + +```typescript +// Mit anon key — RLS erlaubt das für aktive Stellen +const { data } = await supabase + .from('stellen') + .select(` + id, sparte, berufsbezeichnung, stellen_anzahl, + verguetung_1, verguetung_2, verguetung_3, verguetung_4, + ausbildungsstart, lehrjahr, schulabschluss, + kontakt_email, kontakt_tel, + member:members(betrieb, ort, plz) + `) + .eq('aktiv', true) + .order('created_at', { ascending: false }); +``` + +### Stellen filtern + +```typescript +const { data } = await supabase + .from('stellen') + .select('*') + .eq('aktiv', true) + .eq('sparte', 'SHK') + .ilike('member.ort', '%Stuttgart%'); +``` + +### Stelle anlegen (Mitglied) + +```typescript +const { data, error } = await supabase + .from('stellen') + .insert({ + org_id: currentOrgId, + member_id: currentMemberId, + sparte: 'Elektrotechnik', + berufsbezeichnung: 'Elektroniker für Energie- und Gebäudetechnik', + stellen_anzahl: 2, + verguetung_1: 800, + verguetung_2: 920, + verguetung_3: 1020, + ausbildungsstart: 'August 2026', + lehrjahr: '1. Lehrjahr', + schulabschluss: 'Hauptschule', + kontakt_email: 'ausbildung@mueller-elektro.de', + kontakt_tel: '0711-98765' + }); +``` + +--- + +## 7. Storage API + +### PDF hochladen (Admin) + +```typescript +const { data, error } = await supabase.storage + .from('news-attachments') + .upload(`${orgId}/${newsId}/${file.name}`, file, { + contentType: 'application/pdf', + upsert: false + }); + +const { data: urlData } = supabase.storage + .from('news-attachments') + .getPublicUrl(`${orgId}/${newsId}/${file.name}`); +``` + +### Logo hochladen (Admin) + +```typescript +const { error } = await supabase.storage + .from('org-assets') + .upload(`${orgId}/logo.png`, file, { + contentType: 'image/png', + upsert: true + }); +``` + +--- + +## 8. Edge Functions + +### `send-invitation` — Einladungsmail senden + +```typescript +// apps/supabase/functions/send-invitation/index.ts +import { Resend } from 'npm:resend'; + +Deno.serve(async (req) => { + const { member_id, org_id } = await req.json(); + + // Member und Org-Daten laden + const { data: member } = await supabase + .from('members') + .select('*, org:organizations(name)') + .eq('id', member_id) + .single(); + + // Magic Link generieren + const { data: { properties } } = await supabase.auth.admin + .generateLink({ type: 'magiclink', email: member.email }); + + // E-Mail senden + const resend = new Resend(Deno.env.get('RESEND_API_KEY')); + await resend.emails.send({ + from: 'noreply@innungsapp.de', + to: member.email, + subject: `Einladung zur ${member.org.name}`, + html: invitationEmailTemplate(member, properties.hashed_token) + }); + + return new Response(JSON.stringify({ success: true })); +}); +``` + +### `send-push-notification` — Push senden bei neuem Beitrag + +```typescript +// Wird via Database Webhook nach INSERT auf news getriggert +Deno.serve(async (req) => { + const { record: news } = await req.json(); + if (!news.published_at) return new Response('Draft, skip'); + + // Alle Push Tokens der Innung laden + const { data: tokens } = await supabase + .from('push_tokens') + .select('token') + .eq('org_id', news.org_id); // via user_roles Join + + // Expo Push API + const messages = tokens.map(({ token }) => ({ + to: token, + title: news.title, + body: news.body.substring(0, 100) + '...', + data: { type: 'news', id: news.id } + })); + + await fetch('https://exp.host/--/api/v2/push/send', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(messages) + }); + + return new Response(JSON.stringify({ sent: messages.length })); +}); +``` + +### `import-members` — CSV-Import + +```typescript +Deno.serve(async (req) => { + const formData = await req.formData(); + const file = formData.get('file') as File; + const orgId = formData.get('org_id') as string; + + const csv = await file.text(); + const rows = parseCSV(csv); // eigene Parse-Funktion + + const members = rows.map(row => ({ + org_id: orgId, + nachname: row['Nachname'], + vorname: row['Vorname'], + betrieb: row['Betrieb'], + sparte: row['Sparte'], + email: row['E-Mail'], + telefon: row['Telefon'], + ort: row['Ort'], + status: 'aktiv' + })); + + const { data, error } = await supabase + .from('members') + .insert(members); + + return new Response(JSON.stringify({ imported: members.length, error })); +}); +``` + +--- + +## 9. Realtime Subscriptions + +### Live-Updates für News Feed + +```typescript +// Neuer Beitrag erscheint sofort in der App +const subscription = supabase + .channel('news-updates') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'news', + filter: `org_id=eq.${currentOrgId}` + }, (payload) => { + queryClient.invalidateQueries({ queryKey: ['news'] }); + }) + .subscribe(); + +// Cleanup +return () => subscription.unsubscribe(); +``` + +### Live-Updates für Teilnehmerzahl + +```typescript +const subscription = supabase + .channel(`termin-${terminId}`) + .on('postgres_changes', { + event: '*', + schema: 'public', + table: 'termine_anmeldungen', + filter: `termin_id=eq.${terminId}` + }, () => { + queryClient.invalidateQueries({ queryKey: ['termin', terminId] }); + }) + .subscribe(); +``` + +--- + +## 10. Error Handling Patterns + +```typescript +// Zentrale Error-Handling Utility +export function handleSupabaseError(error: PostgrestError | null): never | void { + if (!error) return; + + switch (error.code) { + case '23505': // unique_violation + throw new Error('Dieser Eintrag existiert bereits.'); + case '42501': // insufficient_privilege (RLS) + throw new Error('Keine Berechtigung für diese Aktion.'); + case 'PGRST116': // no rows returned + throw new Error('Kein Eintrag gefunden.'); + default: + console.error('Supabase error:', error); + throw new Error('Ein unbekannter Fehler ist aufgetreten.'); + } +} +``` diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..f77ce8c --- /dev/null +++ b/ARCHITECTURE.md @@ -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 4–6 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 | diff --git a/AZUBI_MODULE.md b/AZUBI_MODULE.md new file mode 100644 index 0000000..3597c18 --- /dev/null +++ b/AZUBI_MODULE.md @@ -0,0 +1,289 @@ +# InnungsApp — Azubi-Modul (Advanced) + +> **Status:** Post-MVP | **Geplant:** Q2–Q3 2026 +> **Ziel:** Fachkräftemangel bekämpfen durch Gen-Z-gerechtes Recruiting + +--- + +## 1. Problem: Warum reicht die Basic-Lehrlingsbörse nicht? + +Die Basic-Lehrlingsbörse (MVP) ist eine Listenansicht mit Stellenangeboten — funktional, aber kein Differenzierungs-Feature. + +**Das echte Problem:** +- Gen Z verbringt 4–6h täglich auf TikTok und Instagram +- Textbasierte Stellenanzeigen werden nicht gelesen +- "Bewerbung per E-Mail mit CV" schreckt ab +- Kein emotionaler Bezug zum Beruf +- ~250.000 unbesetzte Ausbildungsplätze trotz Nachfrage + +**Die Lösung:** Azubis ihren Berufsalltag zeigen — kurze Videos, transparent, ehrlich. Bewerbung mit einem Klick. + +--- + +## 2. Feature: TikTok-Style Video-Feed + +### Konzept + +Jeder Handwerksbetrieb kann kurze Videos (15–60 Sekunden) hochladen, die echten Berufsalltag zeigen: +- "POV: Du bist Dachdecker in München — Tagesstart" +- "Was verdiene ich wirklich als Elektroniker-Azubi?" +- "5 Dinge, die ich als Sanitär-Azubi gelernt habe" + +### UX/UI + +``` +Vertikaler Scroll-Feed (Fullscreen): +┌──────────────────────────────────────────┐ +│ │ +│ [VIDEO 15s Dachdecker] │ +│ "POV: Mein erster Tag" │ +│ │ +│ ♥ 234 💬 12 📤 │ +│ │ +│ Dachdecker Müller GmbH │ +│ München · 2 offene Stellen │ +│ │ +│ [Mehr erfahren] [Jetzt bewerben →] │ +└──────────────────────────────────────────┘ +(Swipe up für nächstes Video) +``` + +### Technische Umsetzung + +| Komponente | Technologie | Begründung | +|---|---|---| +| Video-Upload | Mux via API | Automatische Transcoding, CDN | +| Video-Player | Mux Player React Native | Adaptive Streaming, HLS | +| Feed-Logik | Cursor-based Pagination | Infinite Scroll ohne Offset-Problem | +| Caching | Expo Video Pre-loading | Nächstes Video vorab laden | +| Thumbnail | Mux Thumbnail API | Automatisch | + +### Video-Spezifikationen + +``` +Format: MP4 (H.264) +Auflösung: 1080x1920 (9:16) — vertikal +Länge: 5–60 Sekunden +Dateigröße: Max 500 MB (Mux transcoded auf ~20MB) +Ton: Pflicht (Untertitel empfohlen) +Upload-Kanal: Admin Web App oder Mobile (Betrieb) +``` + +--- + +## 3. Feature: Bewerber-Profil & 1-Click-Apply + +### Konzept + +Kein Lebenslauf. Kein Anschreiben. Ein kurzes Profil reicht. + +### Profil-Felder (Bewerber) + +``` +Name: [Max Müller ] +Alter: [16 ] +Wohnort: [Stuttgart ] +Schulabschluss: [Realschule ▼ ] +Schulnoten (opt.): [Mathe: 2 Deutsch: 3 ] +Interessen-Tags: [Technik] [Draußen] [Elektro] +Über mich (opt.): [Kurzer Text, max 200 Zeichen] +Telefon (opt.): [________________ ] +``` + +### Apply-Flow + +``` +1. Bewerber sieht Video oder Stellenanzeige +2. Klickt [Jetzt bewerben] +3. Profil (falls noch nicht erstellt): + → Quick-Setup in 2 Minuten + → Nur Pflichtfelder (Name, Alter, Wohnort, Schulabschluss) +4. Bewerbung absenden: + → "Möchten Sie sich bei [Betrieb] bewerben?" + → [Ja, Bewerbung senden] / [Abbrechen] +5. Betrieb erhält Push + E-Mail: + "Neue Bewerbung von Max Müller (16, Stuttgart, Realschule)" +6. Betrieb öffnet Profil, entscheidet: + → [Zum Gespräch einladen] → Chat öffnet sich + → [Ablehnen] → Bewerber erhält Benachrichtigung +``` + +--- + +## 4. Feature: In-App Chat (Betrieb ↔ Bewerber) + +### Scope + +Minimaler 1:1-Chat für Bewerbungs-Kommunikation. +Kein allgemeines Messaging-System (zu komplex für MVP). + +### Technische Umsetzung + +```typescript +// Supabase Realtime-basierter Chat +CREATE TABLE azubi_messages ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + conversation_id uuid NOT NULL, + sender_id uuid REFERENCES auth.users, + body text NOT NULL, + read_at timestamptz, + created_at timestamptz DEFAULT now() +); + +CREATE TABLE azubi_conversations ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + stelle_id uuid REFERENCES stellen, + bewerber_id uuid REFERENCES auth.users, + betrieb_member_id uuid REFERENCES members, + status text DEFAULT 'offen', -- offen | eingeladen | abgelehnt + created_at timestamptz DEFAULT now() +); +``` + +### Moderation + +- Betrieb kann Konversation archivieren +- Bewerber kann blockieren +- InnungsApp hat keine Einsicht in Chat-Inhalte (DSGVO) +- Automatische Löschung nach 90 Tagen Inaktivität + +--- + +## 5. Feature: Vergütungs-Rechner + +### Konzept + +"Was verdiene ich wirklich?" — transparente, vergleichbare Darstellung der Vergütung. + +``` +Beruf wählen: [Elektroniker ▼] +Bundesland: [Baden-Württemberg ▼] + +Ergebnis: +┌────────────────────────────────────────────┐ +│ Bruttogehalt nach Tarif (2026): │ +│ 1. Lehrjahr: 820 € / Monat │ +│ 2. Lehrjahr: 950 € / Monat │ +│ 3. Lehrjahr: 1.080 € / Monat │ +│ │ +│ Abzüge (ca.): │ +│ Steuer + Sozialversicherung: ~15–20% │ +│ │ +│ Nettogehalt (ca.): │ +│ 1. Jahr: ~680 € | 2. Jahr: ~790 € │ +│ │ +│ Vergleich: Mindestlohn 2026 = 12,41 €/h │ +│ Vollzeit: ~2.152 €/Monat brutto │ +│ │ +│ Nach Gesellenprüfung: ∅ 2.800–3.500 € │ +└────────────────────────────────────────────┘ +``` + +--- + +## 6. Feature: Digitales Berichtsheft + +### Konzept + +Azubis führen ihr Berichtsheft digital in der App — Fotos, Sprachnotizen, automatische Wochenstruktur. + +### Eintrag erfassen + +``` +Woche: 15 | 07.04.2026 – 11.04.2026 + +Montag: +┌──────────────────────────────────────────┐ +│ 🎤 Sprachnotiz anhören │ +│ "Heute haben wir die neue Verteilung │ +│ in der Hauptstraße 5 installiert..." │ +│ │ +│ 📷 3 Fotos hinzugefügt │ +│ [Foto 1] [Foto 2] [Foto 3] │ +└──────────────────────────────────────────┘ + +[+ Tag hinzufügen] + +Status: Eingereicht ✓ | [Als PDF exportieren] +``` + +### Betrieb-Ansicht (Bestätigung) + +``` +Berichtsheft-Übersicht: Max Müller (Azubi) +───────────────────────────────────────────── +Woche 14: ✓ Bestätigt am 08.04.2026 +Woche 15: ⏳ Ausstehend [Bestätigen] +Woche 16: ⏳ Ausstehend + +[Alle als PDF exportieren] +``` + +--- + +## 7. Feature: Prüfungsvorbereitung + +### Konzept + +Tägliche 5-Minuten-Quiz-Session für den jeweiligen Ausbildungsberuf. + +### User Flow + +``` +Push Notification täglich um 18:00 Uhr: +"📝 Dein heutiges Quiz: 5 Fragen Elektrotechnik" + +App öffnet sich → Quiz startet: + +Frage 1 von 5: +┌──────────────────────────────────────────┐ +│ Wie viele Drähte hat ein dreiphasiger │ +│ Wechselstromkreis (mit Nullleiter)? │ +│ │ +│ ○ 2 │ +│ ○ 3 │ +│ ● 4 │ +│ ○ 5 │ +│ │ +│ ✓ Richtig! │ +│ Erklärung: L1, L2, L3 + N (Nullleiter). │ +└──────────────────────────────────────────┘ +[Nächste Frage →] + +Ergebnis: +"4 von 5 richtig! 🎉" +"Schwächstes Thema: Schaltkreise — morgen üben!" +``` + +### Datenbasis + +- Fragenkatalog manuell gepflegt pro Gewerk +- Startend mit: Elektrotechnik, SHK, Bau (3 häufigste) +- Erweiterbar via Admin-Interface (Q4) +- Quelle: Gesellenprüfungs-Kataloge der HWK (öffentlich) + +--- + +## 8. Azubi-Modul Pricing + +| Modul | Preis (Add-on zu Basis-Plan) | Inklusiv | +|---|---|---| +| Azubi-Recruiting (Video-Feed + Apply) | + 99 €/Monat | Bis 10 Videos | +| Digitales Berichtsheft | + 49 €/Monat | Bis 50 Azubis | +| Prüfungsvorbereitung | + 49 €/Monat | 3 Berufe | +| **Azubi Komplett-Paket** | **+ 179 €/Monat** | Alles kombiniert | + +--- + +## 9. Azubi-Modul Roadmap + +| Feature | Quartal | Status | +|---|---|---| +| Basic Lehrlingsbörse (Liste) | Q1 2026 (MVP) | In Planung | +| Video-Feed (Upload + Player) | Q2 2026 | Post-MVP | +| Bewerber-Profil + 1-Click-Apply | Q2 2026 | Post-MVP | +| In-App Chat (Betrieb ↔ Bewerber) | Q3 2026 | Post-MVP | +| Digitales Berichtsheft | Q3 2026 | Post-MVP | +| Vergütungs-Rechner | Q2 2026 | Post-MVP | +| Prüfungsvorbereitung | Q4 2026 | Post-MVP | +| KI-Matching (Azubi ↔ Betrieb) | 2027 | Vision | diff --git a/BUSINESS_MODEL.md b/BUSINESS_MODEL.md new file mode 100644 index 0000000..1a4e980 --- /dev/null +++ b/BUSINESS_MODEL.md @@ -0,0 +1,225 @@ +# InnungsApp — Business Model & Unit Economics + +--- + +## 1. Geschäftsmodell-Überblick + +**Typ:** B2B SaaS (Business-to-Business, Software as a Service) +**Käufer:** Innungen und Kreishandwerkerschaften +**Endnutzer:** Mitglieder der Innungen (Handwerksbetriebe, Azubis) +**Vertrieb:** Direct Sales (Phase 1) → Verbands-Partnerschaft (Phase 2-3) + +--- + +## 2. Preismodell + +### Basis-Pläne (monatlich, pro Innung) + +| Plan | Preis | Mitglieder | Laufzeit | +|---|---|---|---| +| **Pilot** | 0 € (3 Monate) | bis 50 | Testphase | +| **Starter** | 99 € / Monat | bis 100 | Monatlich kündbar | +| **Standard** | 199 € / Monat | bis 300 | Monatlich kündbar | +| **Pro** | 349 € / Monat | unbegrenzt | Monatlich kündbar | + +### Jahresvertrag (15 % Rabatt) + +| Plan | Monatspreis (jährlich) | Jahresbetrag | +|---|---|---| +| Starter | 84 € | 1.008 € | +| Standard | 169 € | 2.028 € | +| Pro | 297 € | 3.564 € | + +### Feature-Matrix + +| Feature | Pilot | Starter | Standard | Pro | +|---|---|---|---|---| +| Mitgliederverzeichnis | ✓ | ✓ | ✓ | ✓ | +| News / Mitteilungen | ✓ | ✓ | ✓ | ✓ | +| Push Notifications | ✓ | ✓ | ✓ | ✓ | +| Lehrlingsbörse | ✓ | ✓ | ✓ | ✓ | +| Terminkalender | ✓ | ✓ | ✓ | ✓ | +| Admin Web Dashboard | ✓ | ✓ | ✓ | ✓ | +| PDF-Anhänge | 5 GB | 10 GB | 25 GB | Unbegrenzt | +| Analytics & Berichte | Basic | Basic | Erweitert | Vollständig | +| CSV Export | - | ✓ | ✓ | ✓ | +| Support | E-Mail | E-Mail | Priority E-Mail | Dedicated Manager | +| White-Label (Logo, Farbe) | - | - | ✓ | ✓ | +| API-Zugang | - | - | - | ✓ | +| HWK-Anbindung | - | - | - | ✓ | + +--- + +## 3. Upsell & Add-ons (Post-MVP) + +| Add-on | Preis | Beschreibung | +|---|---|---| +| **Azubi-Modul** | + 99 € / Monat | TikTok-Style Lehrlingsbörse, Video-Feed, 1-Click-Apply | +| **Digitales Berichtsheft** | + 49 € / Monat | App für Azubis, Prüfungsvorbereitung | +| **Dokumentenarchiv** | + 49 € / Monat | Unbegrenzte Dokumentenspeicherung + Versionierung | +| **Premium Job Ad** | 50 € / Monat / Stelle | Hervorgehobene Lehrstellenanzeige | +| **Content Service** | 2.000 € (einmalig) | Wir filmen 10 Videos für die Lehrlingsbörse | +| **Onboarding-Service** | 500 € (einmalig) | Datenimport, Setup, Schulung | + +--- + +## 4. Unit Economics + +### Zielwerte + +| KPI | Ziel (MVP) | Ziel (12 Monate) | +|---|---|---| +| **ARPU** (Ø Erlös pro Innung/Monat) | 150 € | 220 € | +| **CAC** (Customer Acquisition Cost) | < 400 € | < 300 € | +| **LTV** (Lifetime Value, 24 Monate) | > 3.600 € | > 5.280 € | +| **LTV:CAC Ratio** | > 9:1 | > 17:1 | +| **Churn Rate** (monatlich) | < 2 % | < 1,5 % | +| **Payback Period** | < 3 Monate | < 2 Monate | + +### Warum niedriger Churn? + +Innungen wechseln selten Software: +- Daten sind einmal importiert und strukturiert +- Mitglieder haben sich an die App gewöhnt +- Kündigung = Chaos + Rückfall auf Excel/WhatsApp +- Entscheidung liegt beim Vorstand (trifft sich quartalsweise) + +Erwarteter Churn: **< 1 % pro Monat** (= 11,4 % annual) für das erste Jahr, sinkt auf < 0,5 % bei eingeführten Verbandskunden. + +--- + +## 5. Revenue-Projektionen + +### Szenario: Konservativ + +| Quartal | Neue Innungen | Gesamt Innungen | MRR | +|---|---|---|---| +| Q1 2026 | 5 (Piloten, kostenlos) | 5 | 0 € | +| Q2 2026 | 5 zahlend | 10 | 750 € | +| Q3 2026 | 10 zahlend | 20 | 2.200 € | +| Q4 2026 | 15 zahlend | 35 | 5.500 € | +| Q1 2027 | 20 zahlend | 55 | 9.500 € | +| Q2 2027 | 30 zahlend | 85 | 16.000 € | + +**ARR Ende 2026:** ~66.000 € +**ARR Ende 2027:** ~192.000 € + +### Szenario: Optimistisch (mit HWK-Partner) + +| Zeitpunkt | Innungen | MRR | ARR | +|---|---|---|---| +| Q4 2026 (HWK-Deal) | 80 | 14.000 € | 168.000 € | +| Q2 2027 | 250 | 47.000 € | 564.000 € | +| Q4 2027 | 500 | 100.000 € | 1.200.000 € | + +**Break-even bei:** ~8 zahlende Innungen à 199 € (Infrastrukturkosten ~80 €/Monat) + +--- + +## 6. Kostenstruktur + +### Fixkosten (monatlich, MVP) + +| Posten | Kosten | +|---|---| +| Supabase Pro | 25 € | +| Vercel Pro | 20 € | +| Resend (E-Mail) | 0–30 € | +| Expo EAS Build | 29 € | +| Domänen + SSL | 5 € | +| **Gesamt** | **~79 €/Monat** | + +### Variable Kosten + +| Posten | Kosten | +|---|---| +| Supabase (ab 100 Innungen) | ~1 €/Innung/Monat | +| Push Notifications (Expo) | ~0,50 €/1.000 Nachrichten | +| Storage (PDFs) | ~0,02 €/GB/Monat | +| Transaktions-E-Mails | ~0,001 €/Mail | + +**Operative Marge bei 100 Innungen:** ~95 % (SaaS-typisch) + +--- + +## 7. Distributionsstrategie + +### Phase 1: Direct Sales (Monat 1–6) + +**Ziel:** 5–10 Piloten in Baden-Württemberg + +**Taktik:** +1. Kaltakquise-Mail an 50 Innungen in BW (SHK, Elektro, Bau, Dachdecker) +2. Kostenloser 3-Monats-Pilot als Türöffner +3. Demo-Call → Figma-Prototype zeigen +4. Pilot live, Feedback sammeln, Testimonials sammeln + +**Aufwand:** ~10h/Woche Sales, 1 Person + +**Erwartete Conversion:** +- 50 angeschriebene Innungen +- 15 Antworten (30 %) +- 8 Demo-Calls +- 5 Piloten (10 %) +- 3 zahlende Kunden nach Pilot (60 % Pilot-Conversion) + +### Phase 2: Regionale HWK-Partnerschaft (Monat 6–12) + +**Ziel:** 1–2 Handwerkskammern als Empfehlungspartner + +**Taktik:** +1. Referenzfall aus Phase 1 als Case Study aufbereiten +2. HWK-Geschäftsführer ansprechen (LinkedIn + direkter Kontakt) +3. Rabattmodell für HWK-Mitglieder (10–20 % Rabatt) +4. HWK empfiehlt App an ihre Mitgliedsinnungen + +**Multiplikator:** 1 HWK-Bezirk = 100–400 Innungen + +### Phase 3: ZDH-Bundesrahmenvertrag (ab Monat 18) + +**Ziel:** Zugang zu allen 7.500 Innungen in Deutschland + +**Voraussetzung:** >50 zahlende Innungen, NPS > 50, funktionierender Sales-Prozess + +**Modell:** Rahmenvertrag mit ZDH (Zentralverband des Deutschen Handwerks) +- ZDH bekommt 10–15 % Revenue Share +- Innungen bekommen Sonderkonditionen +- InnungsApp wird offizielle ZDH-empfohlene Lösung + +--- + +## 8. Wettbewerbspositionierung + +### Preisvergleich + +| Anbieter | Modell | Preis | +|---|---|---| +| InnungsApp | SaaS, mobile-first | 99–349 €/Monat | +| Lokale Webagenturen | Einmalentwicklung | 15.000–30.000 € | +| Vereinssoftware (ClubDesk) | SaaS, web-only | 50–200 €/Monat | +| WhatsApp + Excel | Kostenlos | 0 € (aber DSGVO-Problem) | +| Handwerk-Apps (generisch) | SaaS | 100–500 €/Monat | + +**Positionierung:** Günstigste branchenspezifische Lösung mit mobil-first UX. + +--- + +## 9. Finanzierungsstrategie + +### Phase 1: Bootstrapped + +- Keine externe Finanzierung notwendig +- Entwicklungskosten ~80 €/Monat (Infrastruktur) +- Eigenentwicklung (Zeitinvestition) + +### Phase 2: Revenue-based Growth + +- Reinvestition der ersten Umsätze in Marketing und Sales +- Erste Einstellung: Sales-Person bei MRR > 5.000 € + +### Phase 3: Seed-Runde (optional, bei Traktion) + +- **Trigger:** 50+ zahlende Innungen oder HWK-Partnerschaft +- **Volumen:** 500k–1Mio. € +- **Use of Funds:** Team (Entwickler, Sales), Marketing, HWK-Akquise +- **Investoren:** Tech-fokussierte Angels, Handwerk-nahe Fonds diff --git a/COMPETITIVE_ANALYSIS.md b/COMPETITIVE_ANALYSIS.md new file mode 100644 index 0000000..8fe9e46 --- /dev/null +++ b/COMPETITIVE_ANALYSIS.md @@ -0,0 +1,188 @@ +# InnungsApp — Wettbewerbsanalyse + +--- + +## 1. Marktübersicht + +Der Markt für Innungs-/Handwerkssoftware lässt sich in drei Kategorien einteilen: + +1. **Allgemeine Vereins-/Verbandssoftware** — nicht für Handwerk gebaut +2. **Handwerkssoftware** — für Betriebe, nicht für Innungen +3. **Status-Quo-Tools** — Excel, WhatsApp, E-Mail (der echte Wettbewerb) + +--- + +## 2. Direkte Wettbewerber + +### ClubDesk + +| Kategorie | Details | +|---|---| +| **Typ** | Vereinsverwaltungssoftware (Schweizer Startup) | +| **Zielgruppe** | Sportvereine, Kulturvereine, NGOs | +| **Preis** | 19–99 CHF/Monat | +| **Stärken** | Mitgliederverwaltung, Kassenbuch, Eventverwaltung | +| **Schwächen** | Web-only, keine mobile App, kein Handwerk-Fokus, kein Azubi-Recruiting | +| **Marktposition** | 10.000+ Kunden in DACH | + +**InnungsApp-Vorteil:** Mobile-first, Handwerk-spezifische Features (Sparten, Lehrlingsbörse, Prüfungen) + +--- + +### MeinVerein + +| Kategorie | Details | +|---|---| +| **Typ** | Deutsche Vereinssoftware (Vogel Communications) | +| **Zielgruppe** | Sportvereine, Ortsvereine, Feuerwehren | +| **Preis** | 19–149 €/Monat | +| **Stärken** | SEPA-Lastschrift, Kassenbuch, Mitgliederverwaltung | +| **Schwächen** | Web-only (Mobile App sehr rudimentär), kein Handwerk-Fokus | +| **Marktposition** | 60.000+ Kunden in Deutschland | + +**InnungsApp-Vorteil:** Native Mobile App, Lehrlingsbörse, kein Vereins-Overhead (Kassenbuch etc. nicht für Innungen relevant) + +--- + +### Handi (früher: Mein Handwerk App) + +| Kategorie | Details | +|---|---| +| **Typ** | Handwerks-Community App | +| **Zielgruppe** | Einzelne Handwerker (Consumer-Fokus) | +| **Preis** | Freemium, bis 30 €/Monat | +| **Stärken** | Bekannte Marke, Handwerk-Fokus | +| **Schwächen** | Consumer-App, kein B2B-Innungs-Fokus, keine Multi-Tenancy, schwache Admin-Tools | +| **Marktposition** | Unbekannte Nutzerzahlen, wenig Traktion | + +**InnungsApp-Vorteil:** Echte B2B-Plattform für Innungen als Mandanten, kein Consumer-Fokus + +--- + +### Campai (früher: easyVerein) + +| Kategorie | Details | +|---|---| +| **Typ** | Vereinsverwaltung SaaS | +| **Zielgruppe** | Vereine aller Art | +| **Preis** | 20–180 €/Monat | +| **Stärken** | Modernes UI, Mitgliederverwaltung, Online-Formulare | +| **Schwächen** | Kein Handwerk-Fokus, Mobile App schwach, keine Lehrlingsbörse | + +--- + +### GuildWork (fiktiv, potenzielle Bedrohung) + +Ein von HWK/ZDH selbst entwickeltes Tool wäre die größte Bedrohung. Aktuell gibt es kein solches bundesweites System. Die HWK betreiben meist veraltete, in-house-entwickelte Portale. + +--- + +## 3. Indirekter Wettbewerb (Status Quo) + +### WhatsApp-Gruppen + +**Warum es trotzdem genutzt wird:** +- Alle kennen es +- Kostenlos +- Funktioniert sofort + +**Warum es scheitert:** +- DSGVO: Telefonnummern werden auf US-Servern gespeichert +- Kein Archiv, kein Tracking, keine Ordnung +- Mitglieder können austreten, Gruppen wachsen unkontrolliert +- Kein Admin-Dashboard + +--- + +### Excel + E-Mail-Verteiler + +**Warum es trotzdem genutzt wird:** +- Jeder kennt es +- Volle Kontrolle über Daten +- Keine Abhängigkeit von einem Anbieter + +**Warum es scheitert:** +- Nicht synchronisiert (nur auf einem Laptop) +- E-Mails landen im Spam +- Keine Lesebestätigung +- Kein Self-Service für Mitglieder +- Manueller Aufwand für jede Änderung + +--- + +## 4. Wettbewerbsmatrix + +| Kriterium | InnungsApp | ClubDesk | MeinVerein | WhatsApp+Excel | +|---|---|---|---|---| +| Mobile App (iOS + Android) | ✓ Nativ | Rudimentär | Sehr schwach | ✓ (WhatsApp) | +| Handwerk-spezifisch | ✓ | - | - | - | +| Lehrlingsbörse | ✓ | - | - | - | +| Multi-Tenancy (viele Innungen) | ✓ | ✓ | ✓ | - | +| DSGVO-konform | ✓ (EU) | ✓ (CH) | ✓ | - (WhatsApp) | +| Push Notifications | ✓ | - | - | ✓ (WhatsApp) | +| Leserate-Tracking | ✓ | - | - | - | +| PDF-Anhänge | ✓ | ✓ | ✓ | ✓ (limitiert) | +| Admin Web Dashboard | ✓ | ✓ | ✓ | - | +| Preis (€/Monat) | 99–349 | 19–99 | 19–149 | 0 | +| Onboarding-Zeit | < 15 Min | ~60 Min | ~90 Min | 0 Min | + +--- + +## 5. Differenzierung InnungsApp + +### USP #1: Handwerk-DNA von Anfang an + +Kein generisches Vereinstool. Jede Feature-Entscheidung orientiert sich an der Realität einer Innung: +- Sparten (Elektro, SHK, Dach, etc.) als First-Class-Citizen +- Lehrlingsbörse als Kernfeature, nicht Afterthought +- Rollen die zu Innung passen (Obermeister, Geschäftsführer, Mitglied) +- Beitrags-Kategorien die Innungs-Alltag widerspiegeln (Prüfung, Förderung, Lossprechung) + +### USP #2: Mobile-First für Handwerker + +Handwerker sitzen nicht am Schreibtisch. ClubDesk und MeinVerein sind Web-Tools mit schwachen Mobile-Afterthoughts. InnungsApp ist primär für das Smartphone gebaut — weil Handwerker ihr Smartphone auf der Baustelle haben, nicht ihren Laptop. + +### USP #3: Einfachstes Onboarding am Markt + +Ziel: Eine Innung ist in 15 Minuten live. Mitglieder können sich via Magic Link einloggen — kein Passwort, keine App-Store-Navigation nötig. + +### USP #4: Azubi-Recruiting als Differenzierung (Post-MVP) + +Kein anderer Anbieter hat einen TikTok-style Video-Feed für Ausbildungsplätze. Das ist kein Feature, das aus einer Vereinsverwaltungslösung entsteht. Es ist ein fundamentaler Neuansatz. + +### USP #5: Verbands-Vertriebskanal + +Wenn ein HWK-Rahmenvertrag gelingt, kann kein Direktwettbewerber mithalten — der Distributor ist der Moat. + +--- + +## 6. Preispositionierung + +``` +Preis + ▲ + │ Bespoke Agency + │ (15k–50k€) + │ + │ [InnungsApp Standard 199€] ← Zielzone + │ [InnungsApp Starter 99€] + │ + │ ClubDesk / MeinVerein (50–150€) + │ + │ WhatsApp + Excel (0€) + └─────────────────────────────────────────► Feature-Tiefe + Wenig Viel +``` + +InnungsApp positioniert sich bewusst über generischen Vereinstools, weit unter Bespoke-Lösungen — mit einem Feature-Set, das auf Innungen zugeschnitten ist. + +--- + +## 7. Bedrohungsszenarien + +| Szenario | Wahrscheinlichkeit | Impact | Gegenmaßnahme | +|---|---|---|---| +| ZDH entwickelt eigenes Tool | Niedrig (bürokratisch, langsam) | Sehr hoch | Rahmenvertrag mit ZDH anstreben | +| Vereinssoftware kopiert Handwerk-Features | Mittel | Mittel | Schneller Marktausbau, Verbands-Deals | +| Großer HR-Anbieter (Personio) adressiert Innungen | Niedrig | Hoch | Nischenvorsprung, Community-Lock-in | +| Konkurrent kopiert InnungsApp | Mittel | Mittel | Netzwerkeffekte, Verbandsdeal als Moat | diff --git a/DATABASE_SCHEMA.md b/DATABASE_SCHEMA.md new file mode 100644 index 0000000..efabdeb --- /dev/null +++ b/DATABASE_SCHEMA.md @@ -0,0 +1,416 @@ +# InnungsApp — Datenbankschema + +> **Datenbank:** PostgreSQL via Supabase | **Stand:** Februar 2026 + +--- + +## 1. Entity Relationship Diagram (vereinfacht) + +``` +organizations + │ + ├── user_roles (N:M mit auth.users) + ├── members (1:N) + │ └── stellen (1:N) + ├── news (1:N) + │ └── news_reads (1:N) + │ └── news_attachments (1:N) + ├── termine (1:N) + │ └── termine_anmeldungen (1:N) + └── push_tokens (via user_id) +``` + +--- + +## 2. Vollständiges Schema + +### organizations — Mandanten + +```sql +CREATE TABLE organizations ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + name text NOT NULL, -- "Innung Elektrotechnik Stuttgart" + slug text UNIQUE NOT NULL, -- "innung-elektro-stuttgart" + plan text NOT NULL DEFAULT 'pilot' CHECK (plan IN ('pilot', 'standard', 'pro', 'verband')), + logo_url text, -- Supabase Storage URL + primary_color text DEFAULT '#1a56db', -- Hex-Farbe für White-Label + sparten text[] DEFAULT '{}', -- ['Elektro', 'Sanitär', 'Heizung'] + kontakt_email text, + kontakt_tel text, + website text, + adresse text, + plz text, + ort text, + bundesland text, + created_at timestamptz DEFAULT now(), + updated_at timestamptz DEFAULT now() +); + +-- Trigger: updated_at automatisch setzen +CREATE TRIGGER organizations_updated_at + BEFORE UPDATE ON organizations + FOR EACH ROW EXECUTE FUNCTION update_updated_at(); +``` + +--- + +### user_roles — Rollen & Mandantenzuordnung + +```sql +CREATE TYPE user_role AS ENUM ('admin', 'member'); + +CREATE TABLE user_roles ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + user_id uuid NOT NULL REFERENCES auth.users ON DELETE CASCADE, + org_id uuid NOT NULL REFERENCES organizations ON DELETE CASCADE, + role user_role NOT NULL DEFAULT 'member', + created_at timestamptz DEFAULT now(), + UNIQUE(user_id, org_id) +); + +-- Index für schnelle Rollenlookups +CREATE INDEX idx_user_roles_user_id ON user_roles(user_id); +CREATE INDEX idx_user_roles_org_id ON user_roles(org_id); +``` + +--- + +### members — Mitgliedsbetriebe + +```sql +CREATE TYPE member_status AS ENUM ('aktiv', 'ruhend', 'ausgetreten'); + +CREATE TABLE members ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + org_id uuid NOT NULL REFERENCES organizations ON DELETE CASCADE, + user_id uuid REFERENCES auth.users ON DELETE SET NULL, -- null wenn noch kein Login + -- Basis-Infos + vorname text, + nachname text NOT NULL, + betrieb text NOT NULL, + sparte text, -- muss in organizations.sparten enthalten sein + -- Kontakt + email text, + telefon text, + mobil text, + website text, + -- Adresse + strasse text, + plz text, + ort text, + -- Innung + status member_status NOT NULL DEFAULT 'aktiv', + mitglied_seit int, -- Eintrittsjahr, z.B. 2015 + ausbildungsbetrieb boolean DEFAULT false, + mitgliedsnummer text, + -- Metadaten + notizen text, -- interne Admin-Notizen + eingeladen_am timestamptz, -- Datum der Einladungsmail + created_at timestamptz DEFAULT now(), + updated_at timestamptz DEFAULT now() +); + +CREATE INDEX idx_members_org_id ON members(org_id); +CREATE INDEX idx_members_user_id ON members(user_id); +CREATE INDEX idx_members_status ON members(org_id, status); +CREATE INDEX idx_members_sparte ON members(org_id, sparte); +``` + +--- + +### news — Mitteilungen & Beiträge + +```sql +CREATE TYPE news_kategorie AS ENUM ('Wichtig', 'Prüfung', 'Förderung', 'Veranstaltung', 'Allgemein'); + +CREATE TABLE news ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + org_id uuid NOT NULL REFERENCES organizations ON DELETE CASCADE, + author_id uuid REFERENCES members(id) ON DELETE SET NULL, + -- Inhalt + title text NOT NULL, + body text NOT NULL, -- Markdown-formatiert + kategorie news_kategorie NOT NULL DEFAULT 'Allgemein', + -- Sichtbarkeit + published_at timestamptz, -- null = Entwurf + pinned boolean DEFAULT false, + -- Metadaten + push_sent boolean DEFAULT false, + created_at timestamptz DEFAULT now(), + updated_at timestamptz DEFAULT now() +); + +CREATE INDEX idx_news_org_id ON news(org_id, published_at DESC); +CREATE INDEX idx_news_pinned ON news(org_id, pinned) WHERE pinned = true; +``` + +--- + +### news_reads — Lesestatus + +```sql +CREATE TABLE news_reads ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + news_id uuid NOT NULL REFERENCES news ON DELETE CASCADE, + user_id uuid NOT NULL REFERENCES auth.users ON DELETE CASCADE, + read_at timestamptz DEFAULT now(), + UNIQUE(news_id, user_id) +); + +CREATE INDEX idx_news_reads_news_id ON news_reads(news_id); +CREATE INDEX idx_news_reads_user_id ON news_reads(user_id); +``` + +--- + +### news_attachments — PDF-Anhänge + +```sql +CREATE TABLE news_attachments ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + news_id uuid NOT NULL REFERENCES news ON DELETE CASCADE, + filename text NOT NULL, + storage_url text NOT NULL, -- Supabase Storage URL + file_size int, -- Bytes + created_at timestamptz DEFAULT now() +); +``` + +--- + +### stellen — Ausbildungsstellen + +```sql +CREATE TABLE stellen ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + org_id uuid NOT NULL REFERENCES organizations ON DELETE CASCADE, + member_id uuid NOT NULL REFERENCES members(id) ON DELETE CASCADE, + -- Stelle + sparte text NOT NULL, + berufsbezeichnung text NOT NULL, -- "Elektroniker für Energie- und Gebäudetechnik" + stellen_anzahl int NOT NULL DEFAULT 1, + -- Vergütung (nach Lehrjahr) + verguetung_1 int, -- Brutto in € / Monat + verguetung_2 int, + verguetung_3 int, + verguetung_4 int, + -- Ausbildungsdetails + ausbildungsstart text, -- "August 2026" oder "sofort" + lehrjahr text, -- "1. Lehrjahr" oder "Quereinsteiger" + schulabschluss text, -- "Kein" | "Hauptschule" | "Realschule" | "Abitur" + -- Kontakt + kontakt_name text, + kontakt_email text, + kontakt_tel text, + -- Sichtbarkeit + aktiv boolean DEFAULT true, + created_at timestamptz DEFAULT now(), + updated_at timestamptz DEFAULT now() +); + +CREATE INDEX idx_stellen_org_id ON stellen(org_id, aktiv); +CREATE INDEX idx_stellen_sparte ON stellen(org_id, sparte) WHERE aktiv = true; +``` + +--- + +### termine — Veranstaltungskalender + +```sql +CREATE TYPE termin_typ AS ENUM ('Prüfung', 'Versammlung', 'Kurs', 'Event', 'Lossprechung', 'Sonstiges'); + +CREATE TABLE termine ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + org_id uuid NOT NULL REFERENCES organizations ON DELETE CASCADE, + -- Details + titel text NOT NULL, + beschreibung text, + typ termin_typ NOT NULL DEFAULT 'Sonstiges', + -- Zeit & Ort + datum date NOT NULL, + uhrzeit_von time, + uhrzeit_bis time, + ort text, + online_link text, -- Zoom/Teams-Link (Post-MVP) + -- Anmeldung + anmeldung_erforderlich boolean DEFAULT false, + max_teilnehmer int, -- null = unbegrenzt + anmeldeschluss date, + -- Metadaten + created_at timestamptz DEFAULT now(), + updated_at timestamptz DEFAULT now() +); + +CREATE INDEX idx_termine_org_id ON termine(org_id, datum); +CREATE INDEX idx_termine_upcoming ON termine(org_id, datum) WHERE datum >= CURRENT_DATE; +``` + +--- + +### termine_anmeldungen — Teilnehmerliste + +```sql +CREATE TABLE termine_anmeldungen ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + termin_id uuid NOT NULL REFERENCES termine ON DELETE CASCADE, + member_id uuid NOT NULL REFERENCES members(id) ON DELETE CASCADE, + angemeldet_at timestamptz DEFAULT now(), + notiz text, -- optionale Teilnehmernotiz + UNIQUE(termin_id, member_id) +); + +CREATE INDEX idx_termine_anmeldungen_termin ON termine_anmeldungen(termin_id); +CREATE INDEX idx_termine_anmeldungen_member ON termine_anmeldungen(member_id); +``` + +--- + +### push_tokens — Push Notification Tokens + +```sql +CREATE TABLE push_tokens ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + user_id uuid NOT NULL REFERENCES auth.users ON DELETE CASCADE, + token text NOT NULL UNIQUE, + platform text NOT NULL CHECK (platform IN ('ios', 'android')), + updated_at timestamptz DEFAULT now(), + UNIQUE(user_id, token) +); + +CREATE INDEX idx_push_tokens_user_id ON push_tokens(user_id); +``` + +--- + +## 3. Row Level Security (RLS) Policies + +```sql +-- Alle Tabellen: RLS aktivieren +ALTER TABLE organizations ENABLE ROW LEVEL SECURITY; +ALTER TABLE members ENABLE ROW LEVEL SECURITY; +ALTER TABLE news ENABLE ROW LEVEL SECURITY; +ALTER TABLE news_reads ENABLE ROW LEVEL SECURITY; +ALTER TABLE stellen ENABLE ROW LEVEL SECURITY; +ALTER TABLE termine ENABLE ROW LEVEL SECURITY; +ALTER TABLE termine_anmeldungen ENABLE ROW LEVEL SECURITY; + +-- Helper Funktion: Gibt org_id des aktuellen Users zurück +CREATE OR REPLACE FUNCTION current_user_org_id() +RETURNS uuid AS $$ + SELECT org_id FROM user_roles + WHERE user_id = auth.uid() + LIMIT 1; +$$ LANGUAGE sql STABLE SECURITY DEFINER; + +-- Helper Funktion: Ist aktueller User Admin? +CREATE OR REPLACE FUNCTION current_user_is_admin() +RETURNS boolean AS $$ + SELECT EXISTS ( + SELECT 1 FROM user_roles + WHERE user_id = auth.uid() + AND role = 'admin' + ); +$$ LANGUAGE sql STABLE SECURITY DEFINER; + +-- members: Jeder sieht nur seine Innung +CREATE POLICY "members_select" ON members + FOR SELECT USING (org_id = current_user_org_id()); + +-- members: Nur Admin darf anlegen/bearbeiten +CREATE POLICY "members_insert" ON members + FOR INSERT WITH CHECK ( + org_id = current_user_org_id() AND current_user_is_admin() + ); + +CREATE POLICY "members_update" ON members + FOR UPDATE USING ( + org_id = current_user_org_id() AND current_user_is_admin() + ); + +-- news: Alle Mitglieder können lesen (nur veröffentlichte) +CREATE POLICY "news_select" ON news + FOR SELECT USING ( + org_id = current_user_org_id() + AND published_at IS NOT NULL + AND published_at <= now() + ); + +-- news: Nur Admin kann erstellen/bearbeiten +CREATE POLICY "news_admin" ON news + FOR ALL USING ( + org_id = current_user_org_id() AND current_user_is_admin() + ); + +-- stellen: Öffentlich lesbar (ohne Login) — via Supabase anon key +CREATE POLICY "stellen_public_select" ON stellen + FOR SELECT USING (aktiv = true); + +-- stellen: Nur zugehöriges Mitglied und Admins können schreiben +CREATE POLICY "stellen_insert" ON stellen + FOR INSERT WITH CHECK ( + org_id = current_user_org_id() + AND ( + member_id IN (SELECT id FROM members WHERE user_id = auth.uid()) + OR current_user_is_admin() + ) + ); +``` + +--- + +## 4. Utility Functions + +```sql +-- Funktion: updated_at Trigger +CREATE OR REPLACE FUNCTION update_updated_at() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_at = now(); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +-- Trigger für alle relevanten Tabellen +CREATE TRIGGER members_updated_at BEFORE UPDATE ON members + FOR EACH ROW EXECUTE FUNCTION update_updated_at(); + +CREATE TRIGGER news_updated_at BEFORE UPDATE ON news + FOR EACH ROW EXECUTE FUNCTION update_updated_at(); + +CREATE TRIGGER stellen_updated_at BEFORE UPDATE ON stellen + FOR EACH ROW EXECUTE FUNCTION update_updated_at(); + +CREATE TRIGGER termine_updated_at BEFORE UPDATE ON termine + FOR EACH ROW EXECUTE FUNCTION update_updated_at(); + +-- View: Beitrag mit Leserate +CREATE VIEW news_with_stats AS +SELECT + n.*, + COUNT(DISTINCT nr.user_id) AS read_count, + COUNT(DISTINCT m.user_id) FILTER (WHERE m.user_id IS NOT NULL) AS total_users +FROM news n +LEFT JOIN news_reads nr ON nr.news_id = n.id +LEFT JOIN members m ON m.org_id = n.org_id AND m.status = 'aktiv' +GROUP BY n.id; + +-- View: Kommende Termine mit Anmeldezahl +CREATE VIEW termine_with_counts AS +SELECT + t.*, + COUNT(ta.id) AS anmeldungen_count +FROM termine t +LEFT JOIN termine_anmeldungen ta ON ta.termin_id = t.id +WHERE t.datum >= CURRENT_DATE +GROUP BY t.id; +``` + +--- + +## 5. Migrations-Strategie + +- Migrations mit `supabase db migrations` verwaltet +- Jede Migration ist eine `.sql`-Datei in `supabase/migrations/` +- Migrations werden in CI/CD vor dem Deploy ausgeführt +- Staging-Datenbank bekommt Migrations zuerst (Blue-Green-Prinzip) +- Rollbacks: nur additiv — keine destruktiven Changes ohne Backup diff --git a/DSGVO_KONZEPT.md b/DSGVO_KONZEPT.md new file mode 100644 index 0000000..711ebac --- /dev/null +++ b/DSGVO_KONZEPT.md @@ -0,0 +1,231 @@ +# InnungsApp — DSGVO & Datenschutzkonzept + +--- + +## 1. Überblick + +InnungsApp verarbeitet personenbezogene Daten von: +- Innungsgeschäftsführern und Admins +- Mitgliedsbetrieben (Betriebsinhaber) +- Azubi-Bewerbern (Minderjährige möglich!) +- Auszubildenden (Minderjährige möglich!) + +Dies begründet hohe DSGVO-Anforderungen — insbesondere bei Minderjährigen. + +--- + +## 2. Rechtsgrundlagen + +| Verarbeitung | Rechtsgrundlage | Artikel DSGVO | +|---|---|---| +| Mitgliederverwaltung | Berechtigtes Interesse der Innung | Art. 6 Abs. 1 lit. f | +| Kommunikation (News) | Berechtigtes Interesse | Art. 6 Abs. 1 lit. f | +| Lehrlingsbörse (Betrieb) | Vertragserfüllung | Art. 6 Abs. 1 lit. b | +| Lehrlingsbörse (Bewerber) | Einwilligung | Art. 6 Abs. 1 lit. a | +| Azubi-Profil (Minderjährige) | Elterliche Einwilligung (< 16 J.) | Art. 8 DSGVO | +| Analytics (PostHog) | Berechtigtes Interesse | Art. 6 Abs. 1 lit. f | +| Push Notifications | Einwilligung | Art. 6 Abs. 1 lit. a | + +--- + +## 3. Datenkategorien & Speicherdauer + +### Mitgliedsdaten + +| Datenkategorie | Speicherdauer | Begründung | +|---|---|---| +| Name, Betrieb, Kontaktdaten | Mitgliedschaft + 3 Jahre | Handelsrechtliche Aufbewahrungspflicht | +| E-Mail (Auth) | Bis Kontolöschung | Technisch notwendig | +| Push Tokens | Bis Abmeldung / App-Deinstallation | Technisch notwendig | +| Lesestatus (news_reads) | 12 Monate | Analytics, danach Anonymisierung | +| Login-Logs | 30 Tage | Sicherheit | + +### Azubi-Bewerber-Daten + +| Datenkategorie | Speicherdauer | Begründung | +|---|---|---| +| Bewerberprofil | 6 Monate nach letzter Aktivität | Automatische Löschung | +| Chat-Nachrichten | 90 Tage nach Gesprächsende | Automatische Löschung | +| Video-Views (anonym) | 90 Tage | Analytics | + +### Logs & Analytics + +| Datenkategorie | Speicherdauer | +|---|---| +| Supabase Auth Logs | 30 Tage | +| PostHog Events | 12 Monate (anonymisiert nach 3 Monaten) | +| Edge Function Logs | 7 Tage | + +--- + +## 4. Auftragsverarbeitung (AVV) + +InnungsApp ist **Auftragsverarbeiter** für die Innungen. +Innungen sind **Verantwortliche** für die Daten ihrer Mitglieder. + +### AVV-Pflicht + +Mit jeder Innung wird ein AVV (Auftragsverarbeitungsvertrag) abgeschlossen: +- Elektronisch im Onboarding-Prozess +- Signatur via Klick-Einwilligung (dokumentiert) +- Bestandteil der AGBs + +### AVV-Inhalte (Kernanforderungen) + +- Gegenstand und Dauer der Verarbeitung +- Art und Zweck der Verarbeitung +- Art der personenbezogenen Daten +- Kategorien betroffener Personen +- Pflichten und Rechte des Verantwortlichen (Innung) +- Technische und organisatorische Maßnahmen (TOMs) +- Sub-Auftragsverarbeiter (Supabase, Resend, etc.) + +--- + +## 5. Sub-Auftragsverarbeiter + +| Anbieter | Zweck | Standort | Datenschutz-Basis | +|---|---|---|---| +| **Supabase** | Datenbank, Auth, Storage | EU (Frankfurt, AWS eu-central-1) | EU-Standardvertragsklauseln | +| **Vercel** | Web-Hosting Admin | USA + EU-Edge | EU-SCC, EU-Daten bleiben in EU | +| **Resend** | Transaktions-E-Mails | USA | EU-SCC | +| **Expo / EAS** | App-Build, Push-Routing | USA | EU-SCC | +| **PostHog** | Analytics | EU (optional) | EU-Hosting wählbar | +| **Mux** | Video-Hosting (Post-MVP) | USA | EU-SCC | + +**Wichtig:** Alle kritischen Daten (Mitgliederdaten, Auth) liegen in Supabase Frankfurt (EU). US-Anbieter erhalten nur technisch notwendige Minimal-Daten. + +--- + +## 6. Technische & Organisatorische Maßnahmen (TOMs) + +### Vertraulichkeit + +- **Datenverschlüsselung in Transit:** TLS 1.3 für alle Verbindungen +- **Datenverschlüsselung at Rest:** AES-256 via Supabase (AWS KMS) +- **Row Level Security:** Strikte Datenisolation auf Datenbankebene +- **JWT-basierte Auth:** Kurzlebige Access Tokens (1 Stunde), Refresh Tokens (7 Tage) +- **Magic Link:** Einmalig verwendbar, 7 Tage gültig + +### Integrität + +- **Audit Logs:** Alle Admin-Aktionen werden geloggt (wer hat was wann geändert) +- **Backup:** Supabase automatisch täglich (30 Tage Retention im Pro-Plan) +- **Input Validation:** Server-seitige Validierung aller Formulare (Zod Schemas) + +### Verfügbarkeit + +- **Supabase SLA:** 99,5 % Uptime +- **Multi-AZ:** Supabase verwendet PostgreSQL mit Standby in separater AZ +- **CDN:** Vercel und Supabase Storage mit globalem CDN + +### Zugriffskontrolle + +- **Role-based Access Control:** `admin` | `member` | `public` +- **Principle of Least Privilege:** Jede Rolle nur Minimalrechte +- **Admin-Zugang:** Nur via Supabase Dashboard mit 2FA +- **Mitarbeiter-Schulung:** Jährliche DSGVO-Unterweisung + +--- + +## 7. Betroffenenrechte + +### Auskunftsrecht (Art. 15 DSGVO) + +**Prozess:** +1. Betroffene Person sendet E-Mail an datenschutz@innungsapp.de +2. Identität wird verifiziert (Magic Link oder Ausweiskopie) +3. Auskunft innerhalb von 30 Tagen +4. Format: PDF mit allen gespeicherten Daten + +### Recht auf Löschung (Art. 17 DSGVO) + +**Self-Service in der App:** +- Einstellungen → "Konto löschen" +- Sofortige Anonymisierung der personenbezogenen Daten +- Technische Daten werden nach 30 Tagen endgültig gelöscht +- Auth-Account wird sofort gelöscht + +**Admin-seitige Löschung:** +- Admin kann Mitglied deaktivieren (kein Datenzugriff) +- Vollständige Löschung auf Anfrage an InnungsApp innerhalb 30 Tage + +### Recht auf Datenübertragbarkeit (Art. 20 DSGVO) + +- Export als JSON oder CSV auf Anfrage +- Enthält: Profildaten, News-Leseverlauf, Terminanmeldungen, eigene Stellen + +### Widerspruchsrecht (Art. 21 DSGVO) + +- Push Notifications: jederzeit in App-Einstellungen deaktivierbar +- Analytics: Opt-Out via Einstellungsmenü (PostHog Cookie-freies Tracking) + +--- + +## 8. Besondere Anforderungen: Minderjährige + +### Problem + +Azubi-Bewerber können 15–16 Jahre alt sein → Minderjährige nach DSGVO Art. 8. + +### Lösung + +**Altersabfrage bei Registrierung:** +- "Sind Sie unter 16 Jahre alt?" (Ja / Nein) +- Bei "Ja": Elterliche Einwilligung erforderlich + +**Einwilligungs-Flow (unter 16):** +1. App zeigt: "Für Personen unter 16 Jahren benötigen wir die Zustimmung eines Erziehungsberechtigten." +2. E-Mail-Adresse des Erziehungsberechtigten eingeben +3. Erziehungsberechtigter erhält E-Mail mit Einwilligung-Link +4. Nach Bestätigung: Bewerber-Profil freigegeben + +**Minimale Datenerhebung bei Minderjährigen:** +- Kein Geburtsdatum gespeichert (nur "unter/über 16") +- Keine Adresse +- Keine Fotos ohne explizite Einwilligung +- Chat: automatische Löschung nach 30 Tagen + +--- + +## 9. Datenschutzerklärung & Impressum + +### Pflichtangaben + +**Datenschutzerklärung** (auf innungsapp.de + in App abrufbar): +- Verantwortlicher: Timo Knuth, [Adresse] +- Datenschutzbeauftragter: (ab 20 Mitarbeiter oder sensible Daten: Pflicht — für MVP: optional) +- Kategorien verarbeiteter Daten +- Zwecke und Rechtsgrundlagen +- Speicherdauer +- Sub-Auftragsverarbeiter +- Betroffenenrechte + Beschwerderecht bei Aufsichtsbehörde + +**Aufsichtsbehörde BW:** +Der Landesbeauftragte für den Datenschutz und die Informationsfreiheit Baden-Württemberg +Lautenschlagerstraße 20, 70173 Stuttgart + +### Cookie-Policy + +- InnungsApp Mobile: keine Cookies (Native App) +- Admin Web: Session Cookie (Supabase Auth) — notwendig, kein Banner erforderlich +- Analytics (PostHog): Cookie-freies Tracking (pixel-los) — kein Banner erforderlich + +--- + +## 10. Incident Response Plan + +### Bei Datenpanne + +1. **Erkennung** → intern oder via Supabase-Alert +2. **Bewertung** (< 24h): Umfang, betroffene Personen, Risiko +3. **Meldung an Aufsichtsbehörde** (< 72h, Art. 33 DSGVO) wenn Risiko für Betroffene +4. **Benachrichtigung der Betroffenen** wenn hohes Risiko (Art. 34 DSGVO) +5. **Dokumentation** im Verarbeitungsverzeichnis + +### Technische Reaktionsmaßnahmen + +- Supabase Auth: Alle Sessions ungültig machen (1 Klick) +- Betroffene Innungen isolieren (org_id deaktivieren) +- Logs sichern (vor Löschung durch Rotation) +- Passwörter: nicht relevant (Magic Link, kein Passwort) diff --git a/EXECUTIVE_SUMMARY.md b/EXECUTIVE_SUMMARY.md deleted file mode 100644 index 416e065..0000000 --- a/EXECUTIVE_SUMMARY.md +++ /dev/null @@ -1,385 +0,0 @@ -# EXECUTIVE SUMMARY -## Analyse: Pain Points deutscher Stadtwerke & Softwarelösungen - -**Dokument:** Hochrangige Zusammenfassung -**Datum:** Februar 2026 -**Zielgruppe:** Geschäftsführer, Investoren, Entscheidungsträger - ---- - -## KERNFINDING - -Deutsche Stadtwerke haben **5 kritische Probleme**, aber **nicht alle parallel lösbar**: -- **60-70% aller Kundenservice-Anfragen** führen zurück zu Pain Point #1-3 -- **25-35% Kundenabwanderung** korreliert mit Zählerablesung & Abschlag-Unklarheit -- **5-10 Millionen EUR Jahreskosten** (bei größeren Stadtwerken für alle 5) - -**MVP-Strategie:** Nur Pain Point #1 (Zählerablesung) mit professioneller Qualität in **4-6 Monaten**. Die anderen 4 folgen später. - -⚠️ **Realistic Check:** Nur #1 entwickeln ist schneller, günstiger, und fokussierter. - ---- - -## TOP 5 PAIN POINTS (Prioritätsreihenfolge) - -### 1️⃣ **Zählerablesung** (Höchste Priorität) -- **Problem:** Manuelle Ablesungen → 30-40% Fehler → Nachberechnungen -- **Kundenimpact:** Verwirung, Rechnungskorrektionen, Ärger -- **Lösung:** SmartMeter-Lite App (Foto-Upload + OCR) -- **ROI:** 8-Monatliche Amortisierung - -### 2️⃣ **Abschlagsrechnungen** (Hoch) -- **Problem:** Unklar, intransparent → 45% Kunden unzufrieden -- **Kundenimpact:** Verwirrung, Serviceanfragen -- **Lösung:** AbschlagAssistant Web-Tool (interaktive Erklärung) -- **ROI:** Sofort ROI durch weniger Support-Calls - -### 3️⃣ **Entstörungsprozesse** (Hoch) -- **Problem:** Keine Echtzeit-Info → lange Unsicherheit -- **Kundenimpact:** Angst, Ärger, Misstrauen -- **Lösung:** OutageAlert Pro (Live-Status + SMS/App) -- **ROI:** 50%+ Reduktion Service-Anrufe - -### 4️⃣ **Kundenservice Fragmentierung** (Mittel-Hoch) -- **Problem:** 5 verschiedene Kanäle → lange Wartezeiten -- **Kundenimpact:** Frustration, Wiederholte Erklärungen -- **Lösung:** Kundenservice 360 (KI-Chatbot + Omnichannel) -- **ROI:** 40-60% Kostenersparnis - -### 5️⃣ **Abrechnungsunklarheiten** (Mittel) -- **Problem:** Rechnungen komplex → Misstrauen -- **Kundenimpact:** Verstehen nicht warum sie zahlen -- **Lösung:** RechnungsAnalyzer+ (Visuelle Erklärung + Archive) -- **ROI:** 60% weniger Abrechnungsbeschwerde - ---- - -## MARKTTECHNIKEN - -### Zielmarkt -- **8-10 Millionen Haushalte** in Deutschland mit Stadwerk-Versorgung -- **900+ Stadtwerke** (kleine bis sehr große) -- **Fokus auf Top 100 Stadtwerke** (60% des Marktes) - -### Geschätztes Gesamtmarktvolumen (KORRIGIERT) - -| Jahr | Szenario Conservative | Szenario Realistic | Szenario Optimistic | -|------|----------------------|-------------------|-------------------| -| Y1 | 400-600K EUR | **500K-1.2M EUR** | 2.0M EUR | -| Y2 | 1.2-2M EUR | **2-4M EUR** | 8-10M EUR | -| Y3 | 2.5-5M EUR | **5-10M EUR** | 15-20M EUR | - -**Realistisches Szenario (mit nur MVP #1):** -- Y1: €500-1.2M (5-10 Kunden) -- Y2: €2-4M (20-35 Kunden) -- Y3: €5-10M (40-60 Kunden) - -**Wichtig:** Das ist mit nur **SmartMeter-App MVP**, nicht alle 5 Solutions. - ---- - -## INVESTMENTTHESE - -### Why Now? (3 Gründe) - -1. **Digitalisierungsdruck:** Pandemie & EU-Vorgaben zwingen Stadtwerke zur Digitalisierung -2. **Fachkräftemangel:** Kundenservice-Mitarbeiter kosten 400-600K EUR/Jahr -3. **Customer Expectations:** Kunden erwarten Modern UX (wie Amazon, Netflix) - -### Key Success Factors - -✅ **Schnelle MVP-Entwicklung** (12-16 Wochen) -✅ **Direct Sales Focus** (B2B an Stadtwerke) -✅ **White-Label Potential** (mehrere Stadtwerke, ein Code) -✅ **Sticky Product** (high switching costs) -✅ **Recurring Revenue** (SaaS-Modell) - ---- - -## FINANZIELLE PROJEKTION (KORRIGIERT - LEAN MVP) - -### Investitionen für MVP Phase 1 (SmartMeter-App only) -- **MVP Development:** 250-350K EUR (4-6 Monate, 3-4 Devs) -- **Product/Design:** 50K EUR -- **Sales/Marketing (Validation):** 30-50K EUR -- **Ops/Legal/Setup:** 20K EUR -- **Total für MVP-Launch:** **€350-450K EUR** (nicht 2M!) - -### Revenue Projektion (3 Jahre) - REALISTISCH - -| Metrik | Year 1 | Year 2 | Year 3 | -|--------|--------|--------|--------| -| Stadtwerk-Kunden | 5-10 | 20-35 | 40-60 | -| ARR (Recurring) | €500K-1.2M | €2-4M | €5-10M | -| Gross Margin | 70% | 75% | 78% | -| EBITDA Margin | -100% | 0% to 15% | 30-40% | -| Break-Even | Month 18-22 | - | - | - -### Unit Economics -- **ACV (Annual Contract Value):** €80K-120K EUR (nicht höher) -- **CAC (Customer Acq. Cost):** €20-30K EUR -- **LTV:CAC Ratio:** 3.5-4:1 (healthy) -- **Churn Rate:** 5-7% (annually) - -### Key Outputs (REALISTISCH) -- **3-Year Total Revenue:** 7.5-15M EUR (Y1 + Y2 + Y3) -- **Break-Even:** Month 18-22 (statt vorher Month 18-20) -- **IRR (bei 350K Inv. nur MVP):** 150%+ (deutlich besser!) -- **Payback Period:** 1.5-2 Jahre -- **WICHTIG:** Mit €350K statt €2M Investment ist das Risiko 6x niedriger! - ---- - -## KOMPETITIVE POSITION - -### Vs. Inhouse-Entwicklung (durch Stadtwerke) -- **Unsere Vorteile:** - - ✅ Best Practices von 100+ Stadtwerken - - ✅ Spesialisierte Expertise (nicht IT-getrieben) - - ✅ Schneller Time-to-Market - - ✅ Skalierbare Lösung -- **Ihre Barriere:** - - ❌ 2-3 Jahre Development - - ❌ Hohe Kosten (2-3M EUR) - - ❌ Weniger Expertise - -### Vs. Große Softwareanbieter (SAP, Oracle) -- **Unsere Vorteile:** - - ✅ Lokalisiert für deutsche Stadtwerke - - ✅ Best-of-Breed Fokus (nicht schwerfällig) - - ✅ Schnelle Innovation - - ✅ Attraktive Pricing -- **Ihre Barriere:** - - ❌ Zu komplex für SMB Stadtwerke - - ❌ Zu teuer (100K+/Monat) - - ❌ Nicht spezialisiert - ---- - -## IMPLEMENTIERUNGS-STRATEGIE (LEAN MVP) - -### ⚠️ WICHTIG: Nur #1 (SmartMeter-App) im MVP - -### Phase 1: VALIDATION (Wochen 1-4, €20-30K) -- 5-10 Interviews mit echten Stadtwerken -- Konkurrenz-Analyse (SAP, Oracle, lokale Lösungen) -- Feature-Priorisierung -- GO/NO-GO Decision -- **Team:** 1 Founder + 1 PM - -### Phase 2: MVP-DEVELOPMENT (Wochen 5-14, €200-300K) -- **NUR SmartMeter-Lite App** (nicht alle 5!) -- Tech Stack: React Native (iOS+Android), Python Backend, Tesseract OCR -- Core Features: Foto-Upload, OCR, Validierung, Admin Portal, API -- Sicherheit: DSGVO, Encryption, Audit Logs -- **Team:** 3-4 Developer, 1 PM, 1 Designer -- **Launch:** Woche 14 - -### Phase 3: BETA & PILOTS (Wochen 15-26, €50-80K) -- 5 Pilot-Stadtwerke (kostenlos, signiert NDA) -- Feedback Loops & Iteration -- Dokumentation & Onboarding -- Sales Materials -- **Team:** 1-2 Developer, 1 PM, 1 Sales -- **GO-to-Market Launch:** Woche 26 - -### Phase 4: EXPANSION (Monat 7+, progressiv) -- Nach erfolgreichem MVP: Pain Point #2, #3, etc. -- Nur wenn #1 momentum hat! -- **Team:** +2-3 Developer pro Solution - -**Total für MVP nur SmartMeter: €350-450K (nicht 1.6M!)** - ---- - -## GO-TO-MARKET (LEAN & REALISTIC) - -### Sales Strategy - 3 Optionen - -**OPTION A: Direct Sales (klassisch)** -- Kleine Sales-Agentur (2-3 Personen) -- Target: Top 20 Stadtwerke -- Sales Cycle: 60-90 Tage -- Risiko: Kostspielig bei wenig early wins -- ✅ Best für: Wenn ihr gute Kontakte habt - -**OPTION B: Partnership-First (empfohlen)** -- VKU-Partnership (Verband Kommunaler Unternehmen) -- Oder: SAP/Oracle Implementation Partner -- Sie bringen Kunden, wir liefern Software -- Dein Anteil: 40-50% der Lizenz -- ✅ Schneller Umsatz, weniger Sales-Kosten -- ✅ Best für: MVP-Phase - -**OPTION C: Reseller Model (niedrig-Risiko)** -- Baue SmartMeter App -- Verkaufe White-Label an 2-3 Consultants -- Sie verkaufen an ihre Stadtwerk-Kunden -- Du kriegst €2-5K pro Installation -- ✅ Wenig Sales-Overhead -- ✅ Best für: Bootstrapping - -### Pricing (Realistisch) -- **Small Stadtwerke (<50K Haushalte):** €1-2K/Monat -- **Medium Stadtwerke (50K-200K):** €3-5K/Monat -- **Large Stadtwerke (>200K):** €5-15K/Monat -- **Average ACV:** €80-120K/year (nicht höher) - ---- - -## RISIKEN & MITIGATION - -| Risiko | Wahrscheinlichkeit | Impact | Mitigation | -|--------|-------------------|--------|-----------| -| Lange Sales Cycles | Hoch | Mittel | Freemium-Modell, POCs | -| Integration Komplexität | Mittel | Hoch | Dediziertes Team, Fallbacks | -| Compliance/Datenschutz | Mittel | Hoch | Early Audits, Legal Review | -| Technische Schulden | Mittel | Mittel | Agile Dev, Code Quality | -| Konkurrenz (SAP, etc.) | Mittel | Mittel | Spezialisation, Speed | - ---- - -## SUCCESS METRICS (18 Monate) - -### Business Metrics -- [ ] 20-30 Stadtwerk-Kunden akquiriert -- [ ] 2.0M EUR ARR -- [ ] 60% Gross Margin -- [ ] Break-Even auf Sicht - -### Product Metrics -- [ ] 40%+ Endkunden-Adoption -- [ ] 50+ NPS Score -- [ ] 99.9% Uptime -- [ ] <2h Support Response Time - -### Market Metrics -- [ ] Top 3 in Google Suche "Stadtwerk Software" -- [ ] 50+ Case Studies/Referenzen -- [ ] Partnership mit VKU etabliert -- [ ] Thought Leadership (Artikel, Events) - ---- - -## FINANZIELLE ANFORDERUNGEN (KORRIGIERT) - -### Capital Requirement - MVP nur SmartMeter-App -- **Lean MVP:** 350-450K EUR (nicht 2-3M!) -- **Extended (mit 6 Monate Runway):** 600-800K EUR -- **Use of Funds (MVP):** - - Product Development: 250-350K EUR (65%) - - Validation & Sales: 50-80K EUR (15%) - - Operations & Legal: 50-70K EUR (15%) - - Reserve: 20-50K EUR (5%) - -### Alternative Szenarien -- **Bootstrapping (aus Eigenkapital):** 150-200K EUR möglich (sehr lean) -- **Friends & Family:** 250-350K EUR -- **Seed Round:** 600-800K EUR (Safety Net) - -### Financial Milestones (REALISTISCH) -- **Months 1-4: Validation Phase** - - 10 Stadtwerk-Interviews - - Konkurrenz-Analyse - - GO/NO-GO Entscheidung - -- **Months 5-14: MVP Development** - - SmartMeter-App Release (Woche 14) - - 5 Beta-Kunden akquiriert (kostenlos) - - NPS Feedback > 40 - -- **Year 1 (Months 15-12):** - - 5-8 First Paying Customers: Month 16-18 - - €400-600K ARR: Month 12 - - Burn Rate stabilisiert - -- **Year 2 (Months 13-24):** - - 20-35 Customers: Month 24 - - €2-4M ARR: Month 24 - - Path to Profitability sichtbar - ---- - -## INVESTOREN-PERSPEKTIVE - -### Why this is attractive for VCs - -✅ **Real TAM:** 5-12M EUR market opportunity (Germany, realistic) -✅ **Recurring Revenue:** Sticky SaaS model (high switching costs) -✅ **Defensible:** Specialized vertical, not generic software -✅ **Experienced Team:** (Required: proven B2B/SaaS founders) -✅ **Global Expansion:** Deutschland → Austria/CH/NL (fast copy-paste) -✅ **M&A Potential:** Attractive for SAP, Oracle, Salesforce, regional players -✅ **Fast Growth:** 2-3x YoY revenue possible (realistic for B2B SaaS) -✅ **Low CAC:** €20-30K acquisition cost vs. €80-120K lifetime value -✅ **Capital Efficient:** Nur €350-450K für MVP (nicht 2M!) - -### Comparable Exits & Valuations -- **B2B SaaS 3-Year ARR:** €5-10M × 5-8x Multiple = €25-80M Exit -- **Similar Verticals (Utilities):** 6-10x Revenue multiples -- **Realistic Scenario Year 3:** €5-10M ARR × 6x = **€30-60M Exit** - -**Investment Returns:** -- **Initial: 350K EUR Seed** -- **Year 3 Exit: €30-60M** = **85x - 170x Return** ✅ -- **IRR:** 80-120% (very attractive for VCs) -- **Risk Level:** Medium (vs. High für Venture Fantasien) - ---- - -## NÄCHSTE SCHRITTE (Next 30 Days) - -### Week 1 -- [ ] Founding Team Onboarding -- [ ] Technical Architecture Review -- [ ] Legal/Compliance Setup - -### Week 2 -- [ ] Initial Stadtwerk Interviews (5-10) -- [ ] Competitive Landscape Deep-Dive -- [ ] Development Environment Setup - -### Week 3 -- [ ] Product Requirements Document (PRD) -- [ ] Visual Design System -- [ ] Development Roadmap - -### Week 4 -- [ ] Board/Investor Update -- [ ] Hiring Plans (Developer, Designer, PM) -- [ ] Marketing Strategy Finalization - ---- - -## KONTAKT & WEITERE INFORMATIONEN - -**Für detaillierte Informationen siehe:** -1. `stadtwerke_analysis.md` - Umfassende Pain Point Analyse -2. `implementation_roadmap.md` - Detaillierte Implementierungsplanung -3. `detailed_use_cases.md` - Kundenszenarien und konkrete Beispiele - -**Ansprechpartner:** -- Technical Lead: [TBD] -- Product Manager: [TBD] -- Business Development: [TBD] - ---- - -## APPENDIX: KEY DEFINITIONS - -**Pain Point:** Wiederkurrentes Problem, das Kundenzufriedenheit reduziert -**ARR:** Annual Recurring Revenue (jährliche wiederkurrende Einnahmen) -**ACV:** Average Contract Value (durchschnittlicher Vertragswert) -**CAC:** Customer Acquisition Cost (Kosten zur Kundenakquisition) -**NPS:** Net Promoter Score (Maß für Kundenloyal und Empfehlungsbereitschaft) -**TTM:** Time-to-Market (Zeit bis zur Markteinführung) -**MVP:** Minimum Viable Product (kleinste funktionsfähige Version) -**SaaS:** Software as a Service (Cloud-basiertes Softwaremodell) -**Churn:** Kündigungsquote (% der Kunden, die gehen) -**EBITDA:** Earnings Before Interest, Taxes, Depreciation, Amortization - ---- - -**Datum dieser Analyse:** Februar 2026 -**Gültigkeitsdauer:** 12 Monate (Marktdaten aktuell) -**Nächste Review:** November 2026 diff --git a/FEATURES_BACKLOG.md b/FEATURES_BACKLOG.md new file mode 100644 index 0000000..40105b2 --- /dev/null +++ b/FEATURES_BACKLOG.md @@ -0,0 +1,129 @@ +# InnungsApp — Feature Backlog + +> Priorisiert nach MoSCoW: **M**ust | **S**hould | **C**ould | **W**on't (MVP) +> Sortiert nach Impact / Effort Score (H = Hoch, M = Mittel, N = Niedrig) + +--- + +## MVP Must-Have (Phase 1) + +| ID | Feature | Modul | Impact | Effort | Sprint | +|---|---|---|---|---|---| +| F-001 | Magic Link Login (E-Mail) | Auth | H | N | 1 | +| F-002 | Auth Guard (geschützte Routes) | Auth | H | N | 1 | +| F-003 | Mitgliederverzeichnis (Liste + Suche) | Mitglieder | H | N | 1 | +| F-004 | Mitglied-Detailansicht + Tap-to-Call | Mitglieder | H | N | 1 | +| F-005 | Filter: Sparte, Ort, Ausbildungsbetrieb | Mitglieder | M | N | 1 | +| F-006 | Admin: Mitglied anlegen / bearbeiten | Mitglieder | H | M | 1 | +| F-007 | Admin: Mitglied deaktivieren | Mitglieder | H | N | 1 | +| F-008 | CSV-Import Mitglieder | Mitglieder | H | M | 1 | +| F-009 | Einladungsmail per Resend | Mitglieder | H | N | 1 | +| F-010 | News Feed (veröffentlichte Beiträge) | News | H | N | 2 | +| F-011 | News-Detailansicht mit Markdown | News | H | N | 2 | +| F-012 | Kategoriefilter (Wichtig/Prüfung/etc.) | News | M | N | 2 | +| F-013 | Ungelesen/Gelesen-Status | News | M | N | 2 | +| F-014 | PDF-Anhang öffnen | News | H | M | 2 | +| F-015 | Push Notification bei Veröffentlichung | News | H | M | 2 | +| F-016 | Admin: Beitrag erstellen (Markdown) | News | H | M | 2 | +| F-017 | Admin: Beitrag anpinnen | News | M | N | 2 | +| F-018 | Admin: Leserate pro Beitrag | News | H | N | 2 | +| F-019 | Admin: Zeitgesteuerte Veröffentlichung | News | M | M | 2 | +| F-020 | Terminliste (chronologisch) | Termine | H | N | 3 | +| F-021 | Termin-Detailansicht | Termine | H | N | 3 | +| F-022 | Typ-Tags (Prüfung/Versammlung/etc.) | Termine | M | N | 3 | +| F-023 | An-/Abmeldung für Termin | Termine | H | N | 3 | +| F-024 | iCal-Export (Google/Outlook) | Termine | H | N | 3 | +| F-025 | Admin: Termin anlegen / bearbeiten | Termine | H | N | 3 | +| F-026 | Admin: Teilnehmerliste einsehen + CSV-Export | Termine | H | N | 3 | +| F-027 | E-Mail-Bestätigung nach Anmeldung | Termine | M | N | 3 | +| F-028 | Stellenliste öffentlich (ohne Login) | Lehrlingsbörse | H | N | 4 | +| F-029 | Stellen-Filter (Sparte, Ort, Lehrjahr) | Lehrlingsbörse | H | N | 4 | +| F-030 | Vergütungsanzeige nach Lehrjahr | Lehrlingsbörse | H | N | 4 | +| F-031 | Betrieb: Stelle anlegen | Lehrlingsbörse | H | M | 4 | +| F-032 | Betrieb: Stelle aktivieren/pausieren | Lehrlingsbörse | H | N | 4 | +| F-033 | Admin Dashboard Übersicht | Admin | H | M | 4 | +| F-034 | Admin: Innung-Setup (Logo, Sparten) | Admin | H | M | 0 | +| F-035 | Multi-Tenancy RLS | Backend | H | H | 0 | +| F-036 | Row Level Security alle Tabellen | Backend | H | M | 0 | +| F-037 | Push Token Registrierung | Backend | H | M | 2 | +| F-038 | Onboarding-Wizard (neue Innung) | Onboarding | H | M | 5 | +| F-039 | First-Use Tutorial (Mobile) | Onboarding | M | M | 5 | +| F-040 | App Store Submission (iOS + Android) | Launch | H | M | 6 | + +--- + +## Should Have (Phase 2, Q2 2026) + +| ID | Feature | Modul | Impact | Effort | +|---|---|---|---|---| +| F-041 | Push Reminder 24h vor Termin | Termine | H | M | +| F-042 | Admin: Monatsbericht als PDF | Analytics | M | H | +| F-043 | Erweiterte Analytics (DAU/WAU/MAU Charts) | Analytics | M | M | +| F-044 | Leeransicht für leere Listen | UX | M | N | +| F-045 | Offline-Modus (Cached Data) | UX | M | H | +| F-046 | Dokumentenarchiv (Upload/Download) | Dokumente | H | H | +| F-047 | Videokonferenz-Link in Terminen | Termine | M | N | +| F-048 | Mitglied: eigenes Profil bearbeiten | Mitglieder | M | M | +| F-049 | Admin: Mitteilung an Sparte gezielt | News | M | M | +| F-050 | Admin: Vorlage für häufige Beiträge | News | M | M | +| F-051 | Benachrichtigungs-Einstellungen (Nutzer) | Notifications | M | M | +| F-052 | Karten-Ansicht Mitglieder (Google Maps) | Mitglieder | N | H | +| F-053 | Bewerbungs-Kontaktformular (in App) | Lehrlingsbörse | M | M | +| F-054 | Admin: Stellen moderieren / ausblenden | Lehrlingsbörse | M | N | + +--- + +## Could Have (Phase 3, Q3–Q4 2026) + +| ID | Feature | Modul | Impact | Effort | +|---|---|---|---|---| +| F-055 | TikTok-Style Video-Feed | Azubi-Modul | H | H | +| F-056 | Video-Upload für Betriebe | Azubi-Modul | H | H | +| F-057 | Bewerber-Profil (ohne CV) | Azubi-Modul | H | M | +| F-058 | 1-Click-Apply | Azubi-Modul | H | M | +| F-059 | In-App Chat (Betrieb ↔ Bewerber) | Azubi-Modul | H | H | +| F-060 | Vergütungs-Rechner | Azubi-Modul | M | M | +| F-061 | Digitales Berichtsheft | Azubi-Modul | M | H | +| F-062 | Prüfungsvorbereitung Quiz | Azubi-Modul | M | H | +| F-063 | White-Label (Subdomain, Logo) | Platform | H | H | +| F-064 | HWK-Dashboard (alle Innungen im Bezirk) | Platform | H | H | +| F-065 | API für externe Systeme (OpenAPI) | Platform | M | H | +| F-066 | Webhook-Integration | Platform | M | H | +| F-067 | Chat / Direktnachrichten (allgemein) | Kommunikation | M | H | +| F-068 | Prüfungsverwaltung (Gesellenprüfungen) | Prüfungen | H | H | +| F-069 | Obermeister-Genehmigung für Beiträge | Governance | N | M | +| F-070 | Mitgliederbeiträge / Buchhaltung | Finanzen | M | H | +| F-071 | Öffentliches Unternehmensverzeichnis | Marketing | N | H | +| F-072 | Bewertungssystem für Betriebe | Community | N | H | + +--- + +## Won't Have (MVP — bewusste Nein-Entscheidungen) + +| Feature | Begründung | +|---|---| +| Mehrsprachigkeit | Zielgruppe 100% deutsch, 2027 frühestens | +| SEPA-Lastschrift | Buchhaltungsintegration zu komplex | +| Lernmanagementsystem (LMS) | Zu komplex, eigenes Produkt | +| Öffentliche API ab Tag 1 | Erst wenn Produkt stabil | +| App für HWK (übergeordnet) | Erst nach HWK-Partnerschaft | +| Gamification (Punkte, Badges) | Nicht Kernbedürfnis der Zielgruppe | +| Social Feed (Mitglieder posten) | Moderation zu aufwendig | +| Marktplatz / E-Commerce | Separate Business Unit 2027 | + +--- + +## Technische Schulden & Non-Feature Backlog + +| ID | Aufgabe | Priorität | +|---|---|---| +| T-001 | End-to-End Tests (Playwright) für Admin-App | Hoch | +| T-002 | Unit Tests für Supabase Edge Functions | Hoch | +| T-003 | React Native E2E Tests (Maestro) | Mittel | +| T-004 | Error Monitoring (Sentry) integrieren | Hoch | +| T-005 | Performance Monitoring (Supabase Insights) | Mittel | +| T-006 | Dependency Updates automatisieren (Renovate) | Mittel | +| T-007 | API Rate Limiting (Edge Function) | Hoch | +| T-008 | Spam-Schutz Lehrstellenanzeigen | Mittel | +| T-009 | Datenbankindizes optimieren (EXPLAIN ANALYZE) | Mittel | +| T-010 | Storybook für UI-Komponenten | Niedrig | diff --git a/GTM_STRATEGY.md b/GTM_STRATEGY.md new file mode 100644 index 0000000..9c6227a --- /dev/null +++ b/GTM_STRATEGY.md @@ -0,0 +1,292 @@ +# InnungsApp — Go-to-Market Strategie + +--- + +## 1. Markt-Entry Strategie + +### Fokus: Baden-Württemberg First + +**Warum BW als erstes Bundesland?** +- 1.000+ Innungen in BW (10–15 % des Gesamtmarkts) +- HWK Baden-Württemberg hat 3 Kammern (Stuttgart, Karlsruhe, Freiburg) mit regionaler Entscheidungshoheit +- Geografisch erreichbar für persönliche Demos +- ZDH-Präsident kommt aus BW (Netzwerkeffekt) + +**Zielsegment Phase 1:** +- Handwerk-Innungen mit 50–300 Mitgliedern +- Branchen: SHK, Elektrotechnik, Bau, Dachdecker (hoher Fachkräftemangel) +- Geschäftsführer ist digital affin (< 55 Jahre, LinkedIn-Präsenz) + +--- + +## 2. Phase 1: Direct Sales (Monat 1–6) + +### Ziel +5 zahlende Innungen in BW + +### Prospecting + +**Lead-Generierung:** +1. Scraping: innungsverzeichnis.de / HWK-Websites → alle BW-Innungen mit Kontaktdaten +2. LinkedIn: Geschäftsführer und Obermeister identifizieren +3. Branchen-Priorisierung: SHK > Elektro > Bau > Dachdecker + +**Ziel-Lead-Liste: 100 Innungen in BW** + +### Outreach-Sequenz + +**E-Mail 1 (Tag 1): Kaltakquise** +``` +Betreff: Digitale Mitgliederverwaltung für [Innungsname] + +Hallo Frau/Herr [Name], + +ich bin Timo Knuth und entwickle InnungsApp — eine App, die Innungen von +Excel und WhatsApp befreit. + +Drei Dinge in 30 Sekunden: +- Mitgliederverzeichnis mit Suche auf dem Smartphone +- Rundschreiben mit Push-Benachrichtigung (Sie sehen, wer es gelesen hat) +- Lehrlingsbörse — Azubis finden, direkt über Ihre Innung + +Für [Innungsname] würde ich das 3 Monate kostenlos zur Verfügung stellen. + +Haben Sie 20 Minuten für eine kurze Demo nächste Woche? + +Mit freundlichen Grüßen +Timo Knuth +``` + +**E-Mail 2 (Tag 5): Follow-Up** +``` +Betreff: Re: InnungsApp für [Innungsname] + +Hallo [Name], + +kurzes Follow-Up — haben Sie meine E-Mail gesehen? + +Ich verstehe, dass Sie viel zu tun haben. Deshalb direkt zum Punkt: + +Können wir 20 Minuten finden? Ich zeige Ihnen, wie +[vergleichbare Innung, z.B. "die Elektro-Innung Mannheim"] +ihre Mitgliederverwaltung digitalisiert hat. + +Alternativ: Soll ich Ihnen einen kurzen Demo-Link schicken, +den Sie selbst ausprobieren können? +``` + +**LinkedIn (parallel):** +- Personalisierte Kontaktanfrage ohne Pitch +- Nach Annahme: kurze Nachricht mit Link zur Demo + +**Telefon (Woche 2):** +- Direktanruf wenn keine E-Mail-Antwort +- Ziel: Demo-Termin vereinbaren + +### Demo-Call Struktur (20 Minuten) + +``` +0–2 min: Gesprächspartner kennenlernen, aktuelle Situation verstehen + "Wie verwalten Sie heute Ihre Mitglieder?" + "Wie verschicken Sie Rundschreiben?" + "Wie finden Ihre Mitglieder Ausbildungsplätze?" + +2–12 min: Demo (Figma Prototype / Live-App) + - Login via Magic Link zeigen (30 Sek.) + - Mitgliederverzeichnis: Suche, Kontakt + - News: Beitrag erstellen, Leserate sehen + - Lehrlingsbörse: Stelle aufgeben + - Admin-Dashboard: Übersicht + +12–17 min: Fragen & Einwände klären + Häufigste Einwände: siehe unten + +17–20 min: Nächste Schritte + "Ich würde Ihnen gerne 3 Monate kostenlos geben. + Was brauchen wir, um nächste Woche zu starten?" +``` + +### Häufige Einwände & Antworten + +| Einwand | Antwort | +|---|---| +| "Unsere Mitglieder nutzen so etwas nicht" | "Wir testen das kostenlos. Wenn nach 3 Monaten weniger als 40 % eingeloggt sind, haben Sie nichts verloren." | +| "Wir haben gerade kein Budget" | "3 Monate kostenlos. Danach 149 €/Monat — weniger als ein Mittag essen pro Tag." | +| "Das entscheidet der Vorstand" | "Super. Darf ich für die nächste Vorstandssitzung eine kurze Demo aufzeichnen?" | +| "Wir haben das schon mit WhatsApp" | "WhatsApp ist DSGVO-kritisch für Mitgliederdaten. Wir sind EU-gehosted und haben AVV." | +| "Wir warten auf die HWK-Lösung" | "Die HWK hat seit Jahren keine eigene App. Können Sie 2 Jahre warten bei dem Azubi-Mangel?" | + +### Conversion-Ziele + +| Schritt | Zielrate | +|---|---| +| Lead → E-Mail geöffnet | 40 % | +| E-Mail → Antwort / Demo-Anfrage | 15 % | +| Demo → Pilot-Zusage | 50 % | +| Pilot → Bezahlt | 60 % | + +**Bei 100 Leads:** 6 zahlende Kunden → **Ziel erreicht** + +--- + +## 3. Phase 2: HWK-Partnerschaft (Monat 7–12) + +### Ziel +1 regionale HWK als Empfehlungspartner → Zugang zu 200+ Innungen + +### Vorbereitung + +**Voraussetzungen:** +- Mindestens 10 zahlende Innungen (Referenzen) +- NPS > 50 (messbar via PostHog / manuell) +- Case Study (1 Innung mit konkreten Zahlen: "Aktivierungsrate 78%, Leserate 65%") +- DSGVO-Dokumentation vollständig (AVV, TOMs, Datenschutzerklärung) + +### HWK-Ansprache + +**Einstieg:** Nicht als Verkäufer, sondern als Lösung für ihr Problem: +> "Ihre Mitgliedsinnungen haben einen Azubi-Mangel. +> Wir haben ein Tool, das ihnen hilft, Azubis zu finden. +> Wir hätten gerne Ihre Empfehlung — nicht Ihr Geld." + +**Deal-Struktur:** +- HWK empfiehlt InnungsApp offiziell an Mitgliedsinnungen +- Innungen erhalten 15 % Rabatt (Sonderkonditionen) +- HWK erhält 10 % Revenue Share auf alle Verträge im Bezirk +- HWK Dashboard: Überblick aller aktiven Innungen im Bezirk + +**Verhandlungsweg:** +1. Direktkontakt mit HWK-Hauptgeschäftsführer (LinkedIn / Messe) +2. Präsentation im HWK-Vorstand +3. Pilotphase: 1 Kammerbezirk exklusiv für 3 Monate +4. Rahmenvertrag + +### Messen & Events + +| Event | Datum | Ziel | +|---|---|---| +| Handwerk trifft Digitalwirtschaft (Stuttgart) | März 2026 | 5 Kontakte | +| HWK-Jahresempfang BW | Mai 2026 | Obermeister-Networking | +| IHK Digitalisierungstag | Juni 2026 | HWK-Entscheider | +| ZDH-Bundesversammlung Berlin | November 2026 | ZDH-Kontakt | + +--- + +## 4. Phase 3: ZDH-Bundesrahmenvertrag (ab Monat 18) + +### Was der ZDH bedeutet + +Der Zentralverband des Deutschen Handwerks (ZDH) ist der Dachverband über: +- 53 Spitzenorganisationen +- 130 Bundesinnungsverbände +- 7.500 Innungen + +Ein ZDH-Rahmenvertrag bedeutet: **direkter Zugang zu 7.500 potentiellen Kunden**. + +### Voraussetzungen + +- >50 zahlende Innungen bundesweit +- Mindestens 1 HWK-Rahmenvertrag als Referenz +- Technische Due Diligence bestanden (DSGVO, Verfügbarkeit, Skalierbarkeit) +- Team von mindestens 3 Personen (Stabilität demonstrieren) + +### Verhandlungsposition + +**Was der ZDH bekommt:** +- Branded Version ("ZDH InnungsApp") +- Dashboard für ZDH-Mitarbeiter +- 15 % Revenue Share +- Kostenlose Accounts für ZDH-Mitarbeiter + +**Was wir bekommen:** +- Offizielle ZDH-Empfehlung +- Eintrag im ZDH-Serviceportal +- Zugang zu allen Innungsvertretern auf Bundesversammlungen + +--- + +## 5. Content Marketing (begleitend) + +### Blog / Content-Strategie + +**Zielgruppe:** Innungsgeschäftsführer, Obermeister, HWK-Mitarbeiter + +**Themen:** +- "5 Gründe, warum WhatsApp in Innungen ein DSGVO-Risiko ist" +- "Wie Innung [Name] 3h/Woche durch Digitalisierung spart" (Case Study) +- "Warum Gen Z keine Ausbildungsanzeigen auf Websites liest" +- "DSGVO-konform kommunizieren als Innung: Was erlaubt ist" +- "Digitalisierungsförderung 2026: Was Innungen beantragen können" + +**Verteilung:** +- Blog auf innungsapp.de +- LinkedIn-Posts (Timo persönlich) +- Newsletter an Lead-Liste (Resend) + +### "Trojan Horse" Lead Magnet + +**PDF-Guide:** "Wie Sie als Innung 2026 Azubis finden — Der komplette Leitfaden" + +Inhalt: +- Fachkräftemangel: aktuelle Zahlen +- Wo Gen Z Ausbildungsplätze sucht (TikTok, Instagram, nicht Websites) +- Checkliste: "Ist Ihre Lehrstellenanzeige Gen-Z-fähig?" +- Vorlage: E-Mail-Vorlage für Schulen +- Bonus: "Kostenloser Pilot der InnungsApp" + +**Verteilung:** LinkedIn-Post + Kaltakquise als Einstieg + +--- + +## 6. Partnerkanäle + +| Partner | Typ | Potenzial | +|---|---|---| +| HWK Baden-Württemberg | Empfehlungspartner | 400 Innungen | +| Berufsschulen | Azubi-Traffic | Direkt an Bewerber | +| Handwerkskammertage | Events | Sichtbarkeit | +| Steuerberater (Handwerk-nah) | Empfehlung | Warm Leads | +| Verbände (SHK, ZVEH) | Branchenverband | Bundesinnungen | + +--- + +## 7. Pricing im Vertrieb + +### Pilot-Angebot (für erste 20 Innungen) + +``` +3 Monate kostenlos (Pilot) +→ Alle Features des Standard-Plans +→ Persönliches Onboarding durch Gründer +→ Wöchentlicher Check-In-Call +→ Direct Feedback-Kanal (WhatsApp mit Timo) + +Nach Pilot: +→ 149 €/Monat (Standard) — kein Automatikvertrag +→ Entscheidung liegt beim Admin +``` + +### Einwandbehandlung Preis + +**"Zu teuer":** +> "149 € pro Monat — das sind 1,80 € pro Mitglied bei 80 Mitgliedern. +> Dafür sparen Sie 3 Stunden Verwaltung pro Woche. +> Was kostet eine Verwaltungsstunde bei Ihnen?" + +**"Wir haben kein Budget":** +> "Haben Sie sich schon mit dem Digitalisierungsbonus Bayern/BW beschäftigt? +> Viele Innungen bekommen 80 % der Softwarekosten gefördert." + +--- + +## 8. KPIs Go-to-Market + +| Metrik | Monat 3 | Monat 6 | Monat 12 | +|---|---|---|---| +| Leads in Pipeline | 20 | 50 | 150 | +| Demo Calls pro Woche | 2 | 5 | 10 | +| Pilot-Innungen | 5 | 8 | 15 | +| Zahlende Innungen | 0 | 3 | 12 | +| MRR | 0 € | 450 € | 2.000 € | +| CAC | - | 400 € | 280 € | +| Erstes HWK-Gespräch | - | ✓ | ✓ | diff --git a/INDEX.md b/INDEX.md deleted file mode 100644 index 017e6a0..0000000 --- a/INDEX.md +++ /dev/null @@ -1,507 +0,0 @@ -# DOKUMENTATIONS-INDEX - -**Project:** SmartMeter-Lite App für deutsche Stadtwerke -**Status:** Ready to Validate & Build MVP -**Last Updated:** Februar 2026 - ---- - -## 📋 Quick Navigation - -### 🚀 **START HERE** - -| Rolle | Dokument | Zeit | Ziel | -|------|----------|------|------| -| **Founder** | [NEXT_STEPS.md](#next_steps) | 5 min | Wissen, was diese Woche zu tun ist | -| **Investor** | [EXECUTIVE_SUMMARY.md](#executive_summary) | 10 min | Investment Case verstehen | -| **Developer** | [LEAN_ROADMAP_MVP.md](#lean_roadmap) | 15 min | Development Plan verstehen | -| **Sales** | [VALIDATION_PLAYBOOK.md](#validation) | 10 min | Interview Guide nutzen | -| **Everyone** | [REALISTIC_VS_OPTIMISTIC.md](#realistic) | 5 min | Aligned sein on realistic expectations | - ---- - -## 📚 Document Library - -### 🔴 CRITICAL (Must Read First) - -#### **NEXT_STEPS.md** {#next_steps} -**Länge:** 10 min read + action items -**Für:** Everybody -**Inhalt:** -- Wochenweise Action Plan (Wochen 1-4) -- Team assembly checklist -- Fundraising timeline -- Risk mitigation strategies -- Success metrics - -**Wann:** Lies das JETZT und starte die Actions -**Action:** Print + put on wall - ---- - -#### **EXECUTIVE_SUMMARY.md** {#executive_summary} -**Länge:** 15 min read -**Für:** Investors, Geschäftsführer, Board -**Inhalt:** -- Market opportunity (€5-12M realistic) -- Revenue projections (Y1: €500K-1.2M, Y2: €2-4M) -- Capital requirements (€350-450K MVP) -- Unit economics (ACV, CAC, LTV) -- Risk assessment - -**Wann:** Share mit Investors/Board -**Format:** Ready to present, professional tone - ---- - -#### **REALISTIC_VS_OPTIMISTIC.md** {#realistic} -**Länge:** 10 min read -**Für:** Everybody (especially founders) -**Inhalt:** -- Side-by-side comparison of 2 scenarios -- Why realistic is better (safer, more capital efficient) -- GO/NO-GO framework -- Investment attractiveness analysis - -**Wann:** When tempted to overcommit/overspend -**Key Takeaway:** Build ONE thing great, not 5 things mediocre - ---- - -### 🟠 IMPORTANT (Read This Week) - -#### **VALIDATION_PLAYBOOK.md** {#validation} -**Länge:** 20 min read + 2-3 weeks execution -**Für:** Sales, Founder doing outreach -**Inhalt:** -- Interview guide (11 questions) -- Interview scoring framework -- GO/NO-GO criteria -- Sample report template -- Timeline & execution plan - -**Wann:** Use starting Week 1 (interviews) -**Execute:** Complete by Week 4 - ---- - -#### **LEAN_ROADMAP_MVP.md** {#lean_roadmap} -**Länge:** 20 min read -**Für:** CTO, Product Manager, Developers -**Inhalt:** -- Phase 0: Validation (Weeks 1-4) -- Phase 1: MVP Development (Weeks 5-14) - - Sprint-by-sprint breakdown - - Tech stack decisions - - Team structure -- Phase 2: GTM (Weeks 15-26) -- Budget: €350-450K total - -**Wann:** Share with technical team Week 5 -**Use for:** Sprint planning, task breakdown - ---- - -### 🟡 SUPPORTING (Read as Needed) - -#### **SmartMeter_PRD.md** -**Länge:** 30 min read -**Für:** Product Manager, Designers, Developers -**Inhalt:** -- Product Requirements Document -- User stories -- Feature specifications -- UI/UX requirements -- Success criteria - -**When:** Week 5+ (during development) -**Use for:** Detailed specs, engineering - ---- - -#### **detailed_use_cases.md** -**Länge:** 15 min read -**Für:** Sales, Product, Design -**Inhalt:** -- 5 detailed customer scenarios -- Before/After comparisons -- ROI calculations per customer -- Objection handling - -**Wann:** Share with prospects -**Format:** Customer-friendly stories - ---- - -#### **stadtwerke_analysis.md** -**Länge:** 20 min read -**Für:** Deep dive into market -**Inhalt:** -- All 5 pain points explained -- Market size validation -- Competitive landscape -- Detailed opportunity analysis - -**Wann:** Reference document -**Use for:** Understanding full context - ---- - -#### **quick_reference.txt** -**Länge:** 2 min glance -**Für:** Quick recap -**Inhalt:** -- One-page checklists -- Key metrics -- Timeline overview -- Pricing reference - -**Wann:** Team sync, quick lookups -**Format:** Bullet points, print-friendly - ---- - -### 🟢 SUPPORTING (Context Only) - -#### **README.md** -**Länge:** 5 min -**Content:** Navigation guide, glossary -**Wann:** First time reading the project - ---- - -#### **qrmaster_scraped.md** -**Content:** QRMaster market research (background) -**Relevance:** Low (for reference only) - ---- - -## 📖 Reading Paths by Role - -### 👨‍💼 **Founder / CEO** -``` -Week 1: NEXT_STEPS.md → EXECUTIVE_SUMMARY.md → REALISTIC_VS_OPTIMISTIC.md -Week 2: VALIDATION_PLAYBOOK.md (learn interview process) -Week 3: Conduct interviews (using VALIDATION_PLAYBOOK.md) -Week 5: LEAN_ROADMAP_MVP.md (for development planning) -Week 15: SmartMeter_PRD.md (for GTM) -``` - -**Time commitment:** 5-7 hours reading + 20 hours interviewing + daily 2h management - ---- - -### 💰 **Investor / Board Member** -``` -Quick Path (30 min): -1. EXECUTIVE_SUMMARY.md (15 min) -2. REALISTIC_VS_OPTIMISTIC.md (10 min) -3. NEXT_STEPS.md (5 min) → "OK, when can I invest?" - -Deep Dive (90 min): -+ VALIDATION_PLAYBOOK.md (understand market validation) -+ LEAN_ROADMAP_MVP.md (understand execution capability) -+ detailed_use_cases.md (customer stories) -``` - -**Key questions answered:** -- Market size? → EXECUTIVE_SUMMARY.md -- Why not build all 5 solutions? → REALISTIC_VS_OPTIMISTIC.md -- How will you acquire customers? → VALIDATION_PLAYBOOK.md -- Can you execute? → LEAN_ROADMAP_MVP.md -- What's the financial return? → EXECUTIVE_SUMMARY.md - ---- - -### 👨‍💻 **CTO / Lead Developer** -``` -Week 1: LEAN_ROADMAP_MVP.md (architecture, team, timeline) -Week 2: SmartMeter_PRD.md (detailed specs) -Week 3: Tech stack decision (using roadmap as guide) -Week 5: Sprint planning begins -``` - -**Key outputs:** -- Tech stack chosen -- Development environment set up -- CI/CD pipeline ready -- Sprint 0 complete - ---- - -### 🎯 **Product Manager** -``` -Week 1: NEXT_STEPS.md + LEAN_ROADMAP_MVP.md -Week 2: SmartMeter_PRD.md (deep dive) -Week 3-4: VALIDATION_PLAYBOOK.md (customer feedback) -Week 5+: Execute roadmap, track KPIs -``` - ---- - -### 📞 **Sales / Business Development** -``` -Week 1: VALIDATION_PLAYBOOK.md (learn interview framework) -Week 1-3: Conduct 10-15 interviews (Week 1-3) -Week 4: Scoring & go/no-go analysis -Week 15: detailed_use_cases.md (customer stories) -Week 15+: Sales & pipeline management -``` - ---- - -### 🎨 **Designer** -``` -Week 5: SmartMeter_PRD.md (user stories + requirements) -Week 5-7: Create design system, wireframes, prototypes -Week 7+: Design sprint implementation -``` - ---- - -## 🗂️ File Organization - -``` -C:\Users\a931627\Documents\stadtwerke-saas-analysis\ - -CRITICAL (Read First): -├── NEXT_STEPS.md [Action plan - Week by week] -├── EXECUTIVE_SUMMARY.md [Investor pitch] -└── REALISTIC_VS_OPTIMISTIC.md [Keep team grounded] - -EXECUTION (Operational): -├── VALIDATION_PLAYBOOK.md [Interview guide + scoring] -├── LEAN_ROADMAP_MVP.md [Development roadmap] -└── SmartMeter_PRD.md [Product specs] - -SUPPORTING (Reference): -├── detailed_use_cases.md [Customer stories] -├── stadtwerke_analysis.md [Market analysis] -├── quick_reference.txt [One-pagers] -├── README.md [Original overview] -└── implementation_roadmap.md [Original detailed roadmap] - -BACKGROUND (Info Only): -└── qrmaster_scraped.md [Earlier research] -``` - ---- - -## ⏰ How to Use This Project - -### **Phase 0: VALIDATION (Weeks 1-4)** -``` -Primary docs: -✓ NEXT_STEPS.md (Week 1 tasks) -✓ VALIDATION_PLAYBOOK.md (Conduct interviews) -✓ REALISTIC_VS_OPTIMISTIC.md (Stay grounded) - -Secondary: -✓ EXECUTIVE_SUMMARY.md (For investors if fundraising) - -Output: GO/NO-GO decision + 3-5 signed LOIs -``` - -### **Phase 1: MVP DEVELOPMENT (Weeks 5-14)** -``` -Primary docs: -✓ LEAN_ROADMAP_MVP.md (Development plan) -✓ SmartMeter_PRD.md (Product specs) - -Secondary: -✓ NEXT_STEPS.md (Execution tracking) -✓ REALISTIC_VS_OPTIMISTIC.md (When scope creep tempts) - -Output: Production-ready MVP + 5 beta customers -``` - -### **Phase 2: GO-TO-MARKET (Weeks 15-26)** -``` -Primary docs: -✓ detailed_use_cases.md (Sales collateral) -✓ NEXT_STEPS.md (Sales execution) -✓ EXECUTIVE_SUMMARY.md (For new investors) - -Secondary: -✓ VALIDATION_PLAYBOOK.md (Reference for sales process) - -Output: 5-8 paying customers, €50-100K MRR -``` - ---- - -## 🎯 Key Metrics by Phase - -### Phase 0 Success (Week 4) -- [ ] 10+ interviews completed -- [ ] 5+ Hot Leads identified -- [ ] 3+ LOIs signed -- [ ] GO/NO-GO decision made - -### Phase 1 Success (Week 14) -- [ ] MVP released (iOS + Android) -- [ ] 5 beta customers onboarded -- [ ] NPS feedback > 40 -- [ ] Production metrics solid - -### Phase 2 Success (Week 26) -- [ ] 5-8 paying customers -- [ ] €50-100K MRR achieved -- [ ] NPS > 50 -- [ ] Word-of-mouth building - ---- - -## 📊 Document Statistics - -| Document | Pages | Time to Read | Audience | Priority | -|----------|-------|--------------|----------|----------| -| NEXT_STEPS.md | 12 | 10 min | Everyone | 🔴 CRITICAL | -| EXECUTIVE_SUMMARY.md | 14 | 15 min | Investors/Board | 🔴 CRITICAL | -| REALISTIC_VS_OPTIMISTIC.md | 10 | 10 min | Everyone | 🔴 CRITICAL | -| LEAN_ROADMAP_MVP.md | 12 | 20 min | Dev/PM | 🟠 Important | -| VALIDATION_PLAYBOOK.md | 14 | 20 min | Sales/BD | 🟠 Important | -| SmartMeter_PRD.md | 18 | 25 min | Dev/Design | 🟠 Important | -| detailed_use_cases.md | 10 | 15 min | Sales | 🟡 Supporting | -| stadtwerke_analysis.md | 17 | 20 min | Reference | 🟡 Supporting | -| quick_reference.txt | 24 | 5 min | Quick lookup | 🟡 Supporting | - -**Total Learning Time:** ~2 hours (complete review) -**Total Time to Execute:** ~20-30 weeks - ---- - -## ✅ Before You Start - -Make sure you have: - -- [ ] Access to all documents (you're reading this, so ✅) -- [ ] Core founding team identified (Founder + CTO) -- [ ] €20-30K available for validation phase -- [ ] 5-10 personal contacts at Stadtwerke (or can get intros) -- [ ] Willingness to validate before building (don't skip Phase 0!) - ---- - -## 🚀 First Actions (TODAY) - -1. **Read:** NEXT_STEPS.md (10 min) -2. **Read:** REALISTIC_VS_OPTIMISTIC.md (10 min) -3. **Decide:** Are you committed to this? - - IF YES → Do Week 1 tasks (NEXT_STEPS.md) - - IF NO → Discuss what's holding you back - -4. **Share:** Send EXECUTIVE_SUMMARY.md to 5 potential investors -5. **Meet:** Have kickoff call with CTO candidate using LEAN_ROADMAP_MVP.md - ---- - -## 📞 Quick Reference - -| Need | Document | Section | -|------|----------|---------| -| "What should I do this week?" | NEXT_STEPS.md | "THIS WEEK" | -| "Is this financially viable?" | EXECUTIVE_SUMMARY.md | "Financial Projections" | -| "How do I interview customers?" | VALIDATION_PLAYBOOK.md | "Interview Guide" | -| "How long will development take?" | LEAN_ROADMAP_MVP.md | "Sprint Breakdown" | -| "What are we building?" | SmartMeter_PRD.md | "Overview" | -| "Why not build all 5 solutions?" | REALISTIC_VS_OPTIMISTIC.md | "Why Realistic is Better" | -| "What are the risks?" | NEXT_STEPS.md | "Risk Mitigation" | -| "What features does the app have?" | SmartMeter_PRD.md | "Feature List" | - ---- - -## 🎓 Learning Resources - -**Useful to read alongside this project:** - -Books: -- "Lean Startup" by Eric Ries -- "The Innovator's Dilemma" by Clayton Christensen -- "Traction" by Gabriel Weinberg - -Frameworks: -- Jobs to be Done (JTBD) -- Product-Market Fit -- Unit Economics -- TAM/SAM/SOM - -Online: -- Y Combinator Startup School (free) -- Paul Graham essays -- First Round Review - ---- - -## 📝 Document Version Control - -| Version | Date | Changes | -|---------|------|---------| -| v1.0 | Feb 17, 2026 | Initial creation - Realistic MVP focus | -| - | - | - | - -**Last Updated:** February 17, 2026 -**Next Review:** After Phase 0 GO/NO-GO decision - ---- - -## ❓ FAQ - -**Q: Do I need to read all documents?** -A: No. Start with the CRITICAL section. Read others as needed for your role. - -**Q: Can I skip Phase 0 (Validation)?** -A: No. DO NOT SKIP. This saves you from building something nobody wants. - -**Q: Should I raise money before or after Phase 0?** -A: Start fundraising in Week 3-4 (while doing final interviews). Close by Week 7. - -**Q: How much money do I really need?** -A: €350-450K for MVP. €600-800K with runway is safer. - -**Q: What if validation shows NO-GO?** -A: Pivot to Pain Point #2 or #3. Same interview process, different solution. - -**Q: Can I build all 5 solutions?** -A: No. That's why we wrote REALISTIC_VS_OPTIMISTIC.md. Read it. - ---- - -## 🎁 Bonus: How to Share This Project - -**With Investors:** -→ Send EXECUTIVE_SUMMARY.md + link to this INDEX - -**With Team:** -→ Share NEXT_STEPS.md + relevant role-specific docs - -**With Advisors:** -→ Send full folder + ask for feedback on LEAN_ROADMAP_MVP.md - -**With Customers (During Validation):** -→ Share detailed_use_cases.md + ask for feedback - ---- - -## 🏁 Final Checklist - -Before you consider Phase 0 complete: - -- [ ] Read all CRITICAL documents -- [ ] Form core team (Founder + CTO) -- [ ] Secure €20-30K budget -- [ ] Complete 10-15 customer interviews -- [ ] Score interviews using VALIDATION_PLAYBOOK.md -- [ ] Make GO/NO-GO decision -- [ ] (If GO) Get 3+ signed LOIs -- [ ] (If GO) Start fundraising - -Then proceed to Phase 1 with confidence. 🚀 - ---- - -**THIS IS YOUR NORTH STAR. Bookmark this page and refer to it weekly.** - -Questions? Re-read NEXT_STEPS.md → "Risk Mitigation Actions" section. - -Good luck! 🚀 diff --git a/LEAN_ROADMAP_MVP.md b/LEAN_ROADMAP_MVP.md deleted file mode 100644 index a664cd5..0000000 --- a/LEAN_ROADMAP_MVP.md +++ /dev/null @@ -1,540 +0,0 @@ -# LEAN MVP ROADMAP - SmartMeter-Lite App - -**Fokus:** Nur Pain Point #1 (Zählerablesung) - Maximum Quality -**Duration:** 4-6 Monate (Validierung → MVP → Beta → Launch) -**Budget:** €350-450K (nicht €2M!) -**Team:** 3-4 Entwickler + 1 PM + 1 Designer - ---- - -## PHASE 0: VALIDATION (Wochen 1-4, €20-30K) - -### Ziel -- GO/NO-GO für SmartMeter App -- Feature-Priorisierung mit echten Kunden -- Tech-Stack Entscheidung - -### Tasks - -**Woche 1-2: Customer Interviews** -``` -- 10-15 Stadtwerk-Interviews -- Fragen: - 1. Wie viele Zählerstände manuell abgelesen pro Jahr? - 2. Wie hoch ist die Fehlerquote? (%) - 3. Was kostet die manuelle Ablesung pro Kunde? - 4. Würden Sie eine App nutzen? Zu welchem Preis? - 5. Technische Integration: SAP? Oracle? Custom? - 6. Timeline: Wann brauchen Sie eine Lösung? - -- Target: 5-10 konkrete GO/NO-GO Signale -``` - -**Woche 2-3: Competitive Analysis** -``` -Tools/Platforms to analyze: -1. SAP SmartMeter Solutions -2. Oracle Utilities -3. Lokale Lösungen (z.B. EWE Tech) -4. Tech Startups (Z.B. Smappee, etc.) - -Analysis Framework: -- Features & Pricing -- Integration Depth -- Mobile vs. Web-only -- OCR Capability -- Time-to-Market -``` - -**Woche 3-4: Technical Feasibility** -``` -Decision: Tech-Stack für MVP - -FRONTEND: -- React Native (iOS + Android) vs. Flutter -- Recommendation: React Native - - Größere Community - - Better Ecosystem - - Easier to find developers - -BACKEND: -- Python + FastAPI vs. Node.js + Express -- Recommendation: Python + FastAPI - - Better for ML/OCR integration - - Performance good - - Easy to deploy - -OCR LAYER: -- Google Vision API vs. Tesseract (open-source) -- Recommendation: Start with Tesseract - - Free, no API costs - - 85-90% accuracy for meter readings - - Fallback: Hybrid approach - -DATABASE: -- PostgreSQL 13+ (proven, reliable) -- Redis for caching - -DEPLOYMENT: -- AWS / Azure / DigitalOcean -- Docker containers -- CI/CD: GitHub Actions -``` - -### Deliverables -- ✅ GO/NO-GO Decision Document -- ✅ Feature Prioritization Matrix -- ✅ Technology Stack Decision -- ✅ High-Level Architecture Diagram -- ✅ Risk Assessment - -### Team -- 1 Founder/PM + interviews -- 1 Tech Lead (validation) - ---- - -## PHASE 1: MVP DEVELOPMENT (Wochen 5-14, €250-350K) - -### Ziel -- Production-ready SmartMeter-Lite App -- iOS + Android Release -- Beta-ready Dashboard - -### Sprint Breakdown - -#### SPRINT 0-1 (Woche 5, €20K) -**Setup & Architecture** - -``` -Tasks: -□ GitHub Repo Setup -□ Development Environment (Docker) -□ CI/CD Pipeline (GitHub Actions) -□ Database Schema Design - - users table - - meter_readings table - - stadtwerk_accounts table - - readings_history table -□ API Specification (OpenAPI/Swagger) -□ Security Architecture Review (OWASP Top 10) -□ DSGVO Compliance Planning -``` - -**Team:** 1 Backend Lead + 1 Frontend Lead - ---- - -#### SPRINT 1 (Woche 6, €40K) -**Backend Foundation & OCR Integration** - -``` -Backend Tasks: -□ FastAPI Setup -□ PostgreSQL Schema Implementation -□ User Authentication (JWT + OAuth2) - - Email/Password Registration - - Email Verification - - Password Reset Flow -□ Meter Reading API (CRUD) - - POST /api/readings (upload) - - GET /api/readings (list) - - GET /api/readings/{id} (detail) - - DELETE /api/readings/{id} - -OCR Tasks: -□ Tesseract Integration -□ Model Testing with sample meter images -□ Error Handling & Confidence Scoring -□ Fallback to Manual Entry - -Architecture: -- User uploads photo -- Backend receives image -- OCR processes (Tesseract) -- Returns: text, confidence score -- User confirms/corrects reading -- Reading saved -``` - -**Team:** 1 Backend Developer + 1 ML Engineer (part-time) - -**Deliverable:** -- Working OCR pipeline -- REST API endpoints (authenticated) -- Basic error handling - ---- - -#### SPRINT 2 (Woche 7, €50K) -**Mobile App - Core Features** - -``` -Frontend Tasks: -□ React Native Project Setup -□ Auth Screens - - Login Screen - - Registration Screen - - Password Reset - - Email Verification - -□ Main App Navigation - - Tab Navigator (Home, History, Settings) - - Stack Navigator for screens - -□ Camera & Photo Upload - - Camera permission handling - - Photo gallery option - - Compression (before upload) - - Upload progress indicator - -□ OCR Result Screen - - Display detected meter reading - - Show confidence score - - Manual override input - - Confirm/Edit flow - -□ Data Binding to Backend - - Axios/Fetch for API calls - - Error handling - - Loading states - - Offline capability (local storage) -``` - -**Team:** 2 React Native Developers - -**Deliverable:** -- iOS + Android apps (development build) -- Working camera integration -- API connectivity - ---- - -#### SPRINT 3 (Woche 8, €50K) -**Dashboard & Admin Features** - -``` -Stadtwerk-Admin Dashboard: -□ Login & Tenant Management -□ Customer List View - - Filter by name, account number - - Sort by last reading date - - Status indicators (uploaded, pending, verified) - -□ Reading Management - - Accept/Reject readings - - Bulk operations - - Approve multiple readings - - Export CSV/PDF - -□ Analytics - - # of readings submitted (weekly/monthly) - - OCR accuracy rate (%) - - Error rate by customer - - Trend charts - -□ Settings - - Manage users (add/remove) - - API key management - - Integration settings (SAP, Oracle) - - Notification preferences - -Tech: -- React (Next.js recommended) -- Material UI / Tailwind CSS -- REST API calls -``` - -**Team:** 1 React Developer + 1 Designer (part-time) - -**Deliverable:** -- Admin dashboard (development) -- Read/Write API complete -- Data visualization - ---- - -#### SPRINT 4 (Woche 9-10, €60K) -**Testing, Security, Optimization** - -``` -Backend Testing: -□ Unit Tests (pytest) - 80% coverage - - Auth endpoints - - OCR pipeline - - API CRUD operations -□ Integration Tests - - Full user flow (register → upload → confirm) - - Database transactions -□ Performance Testing - - Load test API (simulate 100 concurrent users) - - Optimize database queries -□ Security Testing - - OWASP Top 10 review - - SQL Injection check - - XSS prevention - - Authentication/Authorization - -Frontend Testing: -□ Unit Tests (Jest) - 70% coverage - - Components - - Utility functions -□ E2E Tests (Detox/Appium) - - Full user flow on real devices -□ Performance - - Bundle size optimization - - Image compression - - Lazy loading - -App Store / Play Store Prep: -□ iOS - - App signing certificate - - Privacy Policy - - Screenshots & Description - - Submit to TestFlight - -□ Android - - Keystore setup - - Privacy Policy - - Screenshots & Description - - Submit to Google Play beta - -□ DSGVO / Security - - Data encryption at rest - - HTTPS only - - Audit logging - - Data retention policy -``` - -**Team:** 1 QA Engineer + 1 Backend Developer + 1 Frontend Developer - -**Deliverable:** -- Test coverage reports -- Security audit completed -- Apps in TestFlight / Google Play beta - ---- - -#### SPRINT 5 (Woche 11-12, €80K) -**Beta Launch & Feedback** - -``` -Beta Program: -□ Recruit 5 Pilot Stadtwerke - - Include different sizes (small, medium, large) - - Signed NDAs - - Free for 3 months - -□ Beta Release - - TestFlight (iOS) - - Google Play beta (Android) - - Admin dashboard access - -□ Monitoring & Support - - Daily stand-ups with pilots - - Slack channel for feedback - - Bug fix SLA: 24 hours - - Track: adoption, errors, usage patterns - -□ Feedback Collection - - Weekly survey - - In-app crash reports - - Feature requests - - Pain points - -KPIs to Track: -- Daily Active Users (DAU) -- Monthly Active Users (MAU) -- Reading submission rate (%) -- OCR accuracy in production (%) -- App crashes per session -- Support ticket count -- NPS Score -``` - -**Team:** 1 Product Manager + 1 Support Engineer + 1 Ops - -**Deliverable:** -- Beta program running -- Feedback dashboard -- Bug tracking system - ---- - -#### SPRINT 6 (Woche 13-14, €50K) -**Polish & Production Readiness** - -``` -Tasks: -□ Bug Fixes (from beta feedback) - - Prioritize P0, P1, P2 - - Regression testing - -□ Performance Optimization - - App size < 50MB - - OCR latency < 3 seconds - - API response < 500ms - -□ Production Deployment - - AWS setup (prod environment) - - Database backups - - Monitoring & alerting (New Relic / DataDog) - - Log aggregation (ELK stack) - -□ Documentation - - API docs (OpenAPI) - - Admin handbook - - User guides (PDF) - - FAQs - -□ Compliance Final Check - - DSGVO audit - - BSI-C5 considerations - - Privacy policy finalization - - Terms of service - -□ Go-Live Planning - - Staged rollout plan - - Support procedures - - Escalation matrix - - 24/7 on-call setup - -App Store Submission: -□ Final review -□ Submit to Apple App Store -□ Submit to Google Play Store -``` - -**Team:** All hands (developers, PM, QA) - -**Deliverable:** -- Production-ready apps (iOS + Android) -- Live in app stores -- 24/7 monitoring active -- Support documentation ready - ---- - -## PHASE 2: GO-TO-MARKET (Wochen 15-26, €50-100K) - -### Woche 15-18: Expansion & Sales Enablement - -**Sales Materials:** -``` -□ Case Studies (from 5 beta pilots) -□ Feature Sheet (1-pager) -□ ROI Calculator (interactive) -□ Sales Deck (15-20 slides) -□ Demo Video (3-5 min) -□ Product walkthrough guide -``` - -**Sales Approach:** -Option 1: Direct Sales (1 founder + 1 sales person) -Option 2: Partnership (VKU, SAP/Oracle partners) -Option 3: Hybrid - -**Target List:** -- Top 20 Stadtwerke in Germany -- Focus on medium-large (>50K households) -- Estimated TAM: €800K-1.2M/year - -### Woche 19-26: First Customer Acquisition - -**KPIs:** -- [ ] 5-8 paid pilots signed -- [ ] First revenue: €50-100K -- [ ] NPS > 50 -- [ ] Monthly Churn < 3% - ---- - -## PHASE 3: Expansion (Monat 7+) - -Only start Phase 3 if Phase 2 metrics are green: -- ✅ 5+ paying customers -- ✅ €50K+ MRR -- ✅ NPS > 50 -- ✅ Churn < 3% - -Then consider: -- Pain Point #2 (Abschlag-Tool) -- Pain Point #3 (Outage Alerts) -- Additional integrations (SAP, Oracle) - ---- - -## Budget Summary - -| Phase | Duration | Budget | Team Size | -|-------|----------|--------|-----------| -| **Phase 0: Validation** | 4 weeks | €20-30K | 2 people | -| **Phase 1: MVP Dev** | 10 weeks | €250-350K | 3-4 devs + PM + Designer | -| **Phase 2: GTM** | 6 weeks | €50-80K | 1-2 sales + support | -| **TOTAL** | **6 Months** | **€350-450K** | **5-7 people** | - ---- - -## Key Milestones & Deliverables - -| Week | Milestone | Deliverable | -|------|-----------|-------------| -| 4 | GO/NO-GO Decision | Decision doc | -| 5 | Infrastructure Ready | CI/CD pipeline, DB schema | -| 6 | Backend + OCR | Working API + OCR pipeline | -| 8 | Mobile App Alpha | iOS + Android dev builds | -| 10 | Dashboard + Testing | Admin interface + test coverage | -| 12 | Beta Launch | TestFlight + Google Play beta | -| 14 | Production Release | Live in app stores | -| 18 | First Revenue | 3-5 paying customers | -| 26 | Sustainable Growth | 5-8 customers, €50-100K MRR | - ---- - -## Risk Mitigation - -| Risk | Probability | Impact | Mitigation | -|------|-------------|--------|-----------| -| **OCR accuracy < 80%** | Medium | High | Fallback to manual + hybrid approach | -| **Integration complexity** | High | Medium | Early POC with SAP/Oracle | -| **Sales cycle too long** | High | High | Partnership with VKU or system integrators | -| **Team turnover** | Low | High | Competitive pay, equity incentives | -| **DSGVO compliance issues** | Medium | High | Legal review from week 1 | -| **Market not interested** | Low-Medium | High | Validate in Phase 0 thoroughly | - ---- - -## Success Metrics (End of Phase 2) - -**Product:** -- ✅ 99.5% uptime -- ✅ OCR accuracy > 85% in production -- ✅ App crashes < 1 per 1000 sessions -- ✅ NPS > 50 - -**Business:** -- ✅ 5-8 paying customers -- ✅ €50-100K MRR -- ✅ Customer acquisition cost < €25K -- ✅ LTV:CAC > 3:1 - -**Market:** -- ✅ Top 3 in Google "Zählerablesung App Stadtwerk" -- ✅ 5+ case studies / testimonials -- ✅ Positive industry buzz - ---- - -## Next Actions (This Week) - -- [ ] Reach out to 10-15 Stadtwerke for Phase 0 interviews -- [ ] Form core team (if not already done) -- [ ] Secure €400-500K seed funding -- [ ] Schedule technical architecture kickoff -- [ ] Legal review: DSGVO, data protection - ---- - -**Document Status:** REVISED - Lean MVP Focus -**Last Updated:** February 2026 -**Next Review:** After Phase 0 GO/NO-GO diff --git a/NEXT_STEPS.md b/NEXT_STEPS.md deleted file mode 100644 index 34f6144..0000000 --- a/NEXT_STEPS.md +++ /dev/null @@ -1,554 +0,0 @@ -# NEXT STEPS - Action Plan - -**Status:** Ready to validate & build MVP -**Timeline:** Start immediately -**Decision Point:** After Week 4 Validation - ---- - -## THIS WEEK (Week 1) - -### [ ] 1. Assemble Core Team -**Time:** 2 hours - -``` -You need for Phase 0 (Validation): -- Yourself as Founder/PM -- 1 Technical Co-founder (CTO or Lead Dev) -- 1 Business person (optional: for sales/fundraising) - -Ideal profile: -- CTO: 5+ years software experience, B2B SaaS knowledge -- Business: Sales or startup experience, German market knowledge - -Where to find: -- Co-founder networks -- Angel.co (cofounder matching) -- LinkedIn -- Personal network -``` - -### [ ] 2. Secure Budget for Phase 0 -**Time:** 1 hour - -``` -Need: €20-30K for validation phase - -Options: -A) Bootstrap from savings (€20-30K) -B) Friends & Family round (€30-50K) -C) Apply for Startup grant (BMBF, KfW) - - Process: 2-4 weeks - -If bootstrapping: Delay validation to secure funds -If friends & family: Email your network this week - -Sample email: ---- -Subject: We're building a software solution for German utilities - -Hi [Friend], - -We're working on solving a major pain point for Stadtwerke: -manual meter reading costs them €50-100K/year + quality issues. - -We've identified 5+ potential customers interested in a solution. - -We're raising €30-50K Friends & Family to validate the market -and build an MVP. Interested in learning more? - -Possible terms: SAFE, Convertible Note, or Equity -Timeline: Fast-track to profitability, goal €1M ARR Year 2 - -Let me know if you want to chat! - -[Your Name] ---- - -Do this by: EOW -``` - -### [ ] 3. Create Pitch Deck (Optional but helpful) -**Time:** 4 hours - -``` -10-15 slides: -1. Problem (Meter reading pain points) -2. Market (900 Stadtwerke, 8-10M household market) -3. Solution (SmartMeter-Lite App) -4. Business Model (SaaS, €80-120K/year) -5. Go-to-Market (Direct sales + partnerships) -6. Traction (interviews, early interest) -7. Team (backgrounds) -8. Financials (projections) -9. Ask (€30-50K, use of funds) -10. Contact - -Tools: Pitch.com, Canva, or use template - -Goal: Use for investor discussions, doesn't need to be perfect -``` - -### [ ] 4. Start Interview Recruitment -**Time:** 3 hours - -``` -Use VALIDATION_PLAYBOOK.md as guide - -Create outreach list: -1. LinkedIn search "IT Director" + "Stadtwerk" -2. Email template (see playbook) -3. Target: 10-15 interviews scheduled by EOW - -Quick wins: -- Reach out to 5 personal contacts first (warm intros) -- Ask them for referrals -- Then cold outreach to 20-30 others (5-7 will likely say yes) - -Tools: -- LinkedIn Sales Navigator -- Hunter.io (find emails) -- Calendly (scheduling) - -DO NOT: Wait for perfect conditions. Start recruiting now. -``` - ---- - -## WEEK 2-3 (Validation Phase Execution) - -### [ ] 5. Conduct 10-15 Interviews -**Time:** ~12 hours (conducting) + 6 hours (prep/follow-up) - -``` -Schedule: -- Week 2: 5-8 interviews -- Week 3: 5-7 interviews - -Prep for each: -- Research company (Wikipedia, website) -- Prepare questions -- Test Zoom setup - -During call: -- Record (with permission) -- Take notes (Google Doc shared) -- Be authentic, curious -- Don't pitch - -Use template: VALIDATION_PLAYBOOK.md -Record all data in shared spreadsheet -``` - -### [ ] 6. Competitive Analysis -**Time:** 4 hours - -``` -Research competitors: -1. SAP SmartMeter Solutions - - Features, pricing, timeline - - Strengths vs. weaknesses - -2. Oracle Utilities - - Same analysis - -3. Regional players (Infor, Asseco, etc.) - - What are they doing? - -4. Startups (Smappee, Zigbee Alliance tools) - - What's the latest? - -Document findings: -- Feature comparison matrix -- Pricing comparison -- Time-to-market comparison -- Your differentiation - -Conclusion: Why is our approach better/faster/cheaper? -``` - ---- - -## WEEK 4 (GO / NO-GO Decision) - -### [ ] 7. Score Interviews & Analyze Data -**Time:** 3 hours - -``` -Use scoring framework from VALIDATION_PLAYBOOK.md - -Aggregate: -- # of Hot Leads (score 8-10) -- # of Warm Leads (score 6-7) -- Average budget -- Market size estimate -- Common pain points -- Integration challenges - -Create summary report with: -- Executive summary (1 page) -- Key findings (3-5 bullets) -- Top leads (with names, budgets, timeline) -- Risks & opportunities -- GO/NO-GO recommendation - -Share with team for discussion -``` - -### [ ] 8. Team Decision Meeting -**Time:** 2 hours - -``` -Meeting agenda: -1. Present validation findings (you: 15 min) -2. Team discussion (30 min) -3. Vote on GO/NO-GO (15 min) -4. If GO: Celebrate & move to Phase 1 -5. If NO-GO: Discuss pivot options - -GO Criteria: -✅ 5+ Hot Leads with €50K+ budget each -✅ Average adoption estimate >20% -✅ Team feels confident in market opportunity -✅ Funding secured for development - -NO-GO Criteria: -❌ <3 Hot Leads -❌ Average budget <€40K -❌ Low adoption estimates -❌ Clear market resistance - -If NO-GO: Pivot to Pain Point #2 or #3 and repeat process -``` - -### [ ] 9. If GO: Contact Top Leads about Pilot -**Time:** 3 hours - -``` -Reach out to your 5 Hot Leads: - -Email template: ---- -Subject: Pilot Program: SmartMeter-Lite App - -Dear [Name], - -Thank you for the great conversation last week! - -Based on our discussion, we're moving forward with developing -a mobile app solution for meter reading. We'd like to invite -you to join our Pilot Program. - -Details: -- Free beta access (3 months) -- Early adopter pricing after (€60K/year instead of €80K) -- Weekly feedback sessions -- Direct access to our engineering team - -Pilot Timeline: -- Start: April 2026 -- Alpha release: May 2026 -- Beta feedback period: May-June 2026 -- Commercial launch: July 2026 - -Next steps: -- 30-min call to discuss details -- Sign NDA + LOI (simple document) -- Onboard for beta - -Are you interested? Let's jump on a call this week. - -Best regards, -[Your Name] ---- - -Goal: Get 3-5 signed LOIs (Letters of Intent) - -Signed LOIs = Proof of market, helpful for fundraising -``` - ---- - -## WEEKS 5+ (Development Phase) - -### [ ] 10. Prepare for MVP Development -**Time:** 5 hours (decision-making) - -``` -Use LEAN_ROADMAP_MVP.md - -Decisions to make: -A. Tech Stack finalization - - React Native vs Flutter? - - Python vs Node.js? - - Tesseract vs Google Vision API? - -B. Team assembly - - Hire 3-4 developers (or internal?) - - Find product manager - - Find designer - -C. Development environment - - GitHub repo setup - - CI/CD pipeline - - Development server - -D. Fundraising (if needed) - - €400-500K total for MVP + runway - - Timing: Should start in Week 3-4 - - Close by Week 6-7 to start development - -Fundraising timeline: -Week 3-4: Pitch to angels / seed VCs -Week 5-6: Due diligence -Week 7: Funding closed -Week 8: Team starts development -``` - -### [ ] 11. Begin Phase 1: MVP Development -**Time:** This is the 12-week sprint! - -``` -Kickoff meeting: -- Present project vision & timeline -- Review technical architecture -- Assign sprint teams -- Set up daily standups - -First sprint goals: -- Infrastructure ready (GitHub, CI/CD, DB) -- API specification finalized -- UI/UX mockups approved -- OCR evaluation started - -Each week: -- Sprint planning (2 hours) -- Daily standups (15 min) -- Sprint review (1 hour) -- Retro (1 hour) - -Track progress in: -- GitHub (code) -- Jira/Linear (tasks) -- Figma (design) -- Weekly status deck - -Key metrics to monitor: -- Development velocity (tasks/week) -- Bug count (trend down) -- Test coverage (target 70%+) -- Architecture debt (keep low) -``` - ---- - -## Parallel Track: Fundraising - -### If you need €400-500K: - -**Timeline:** -``` -Week 2-3: Build investor deck + intro list -Week 3-4: Start conversations (10-20 seed VCs) -Week 4-5: Meetings + pitches -Week 5-6: Due diligence with 3-5 top investors -Week 7: Close funding -Week 8: Onboard investors, start development -``` - -**Investor Pitches should emphasize:** -1. Real customer pain (proven in validation) -2. Large market (€5-12M TAM) -3. Fast time-to-market (4-6 months MVP) -4. Low burn (€40-50K/month = 10+ month runway) -5. Strong unit economics (€20K CAC, €80K ACV, 3.5:1 LTV:CAC) -6. Capital efficiency (€350K MVP vs. €2M competitors) - -**Fundraise from:** -- Angel investors -- Seed VCs (500 Startups, Y Combinator Alumni, etc.) -- Corporate VCs (utilities, SAP, etc.) -- Impact/ESG funds (utilities = green energy theme) - -**Do NOT:** -- Oversell / make claims you can't prove -- Ask for more than needed (€400-500K is right range) -- Rush into bad term sheets -- Neglect due diligence on investor fit -``` - ---- - -## Risk Mitigation Actions - -**If Validation shows NO-GO:** -``` -Option 1: Pivot to Pain Point #2 or #3 -- Same interview process -- Validate that problem -- Potentially larger market or lower competition - -Option 2: Pivot to different market -- Same solution (SmartMeter app) -- Different customer (e.g., gas companies, water utilities) -- Adjust messaging - -Option 3: Pause & assess -- Wait for market conditions to improve -- Save capital -- Try again in 6 months -``` - -**If Fundraising falls short:** -``` -Option A: Bootstrap with lower burn -- 2 developers instead of 4 -- Slower but achievable MVP (6-8 months) -- Founder salary: minimal/deferred equity - -Option B: Raise less (€150-200K) -- Reduce team size -- Focus on MVP only (no nice-to-haves) -- Plan Series A for expansion - -Option C: Revenue-first approach -- Get pilot customers signed up -- Charge them for early access -- Use revenue to fund development -``` - -**If Development slips:** -``` -Risk: Scope creep delays MVP launch - -Mitigation: -- Cut features ruthlessly -- MVP = minimum viable, not "everything we want" -- Use MoSCoW method: Must-have, Should-have, Could-have, Won't-have - -If behind by 2+ weeks: -- Reduce scope (cut "nice-to-haves") -- Add developer resources (carefully) -- Don't sacrifice quality for speed -- Communicate transparently with customers -``` - ---- - -## Key Success Metrics (by phase) - -### Phase 0 (Validation) - Week 4 -- [ ] 10+ interviews completed -- [ ] 5+ Hot Leads identified -- [ ] 3+ LOIs signed -- [ ] Market size >€500K validated -- [ ] GO decision made - -### Phase 1 (MVP Dev) - Week 14 -- [ ] MVP app released (iOS + Android) -- [ ] 5 beta customers onboarded -- [ ] NPS feedback collected -- [ ] Bug fixes underway - -### Phase 2 (GTM) - Week 26 -- [ ] 5-8 paying customers -- [ ] €50-100K MRR -- [ ] NPS > 50 -- [ ] Positive word-of-mouth - ---- - -## Monthly Checklist - -**Every month:** -- [ ] Team standup on metrics vs. plan -- [ ] Customer feedback review -- [ ] Fundraising progress (if applicable) -- [ ] Competitive intelligence update -- [ ] Risk assessment & mitigation -- [ ] Investor update (if funded) - -**Quarterly:** -- [ ] Board meeting / advisor check-in -- [ ] Market research refresh -- [ ] Team feedback/retrospective -- [ ] Strategic pivot assessment - ---- - -## Document Reference Guide - -As you execute, use these documents: - -``` -📄 EXECUTIVE_SUMMARY.md - → Share with investors - → High-level business case - → Keep updated every month - -📄 REALISTIC_VS_OPTIMISTIC.md - → When you're tempted to overcommit - → Keep team aligned on realistic expectations - -📄 LEAN_ROADMAP_MVP.md - → Detailed project plan - → Week-by-week tasks - → Use for sprint planning - -📄 VALIDATION_PLAYBOOK.md - → Interview guide - → Scoring framework - → Use during Weeks 1-4 - -📄 This file (NEXT_STEPS.md) - → High-level action plan - → Weekly checklist - → Reference when you're unsure what to do next -``` - ---- - -## Final Thoughts - -**You have a real opportunity here.** The pain points are real, the market is large, and the timing is good (digitalization pressure on utilities). - -But execution is everything. **Focus ruthlessly on:** -1. ✅ Validating the market (Weeks 1-4) -2. ✅ Building an excellent MVP (Weeks 5-14) -3. ✅ Getting first customers (Weeks 15-26) -4. ✅ Profitability (Year 2) - -**Don't get distracted by:** -- ❌ Building all 5 solutions at once -- ❌ Perfectionism (done is better than perfect) -- ❌ Feature creep (say NO to 80% of requests) -- ❌ Premature scaling (focus on PMF first) - -**The realistic financial model is still very attractive:** -- €350K investment -- Year 2: €2-4M ARR -- Year 3: €5-10M ARR -- Exit multiple: 5-8x → €25-80M exit -- Return to investors: 70-200x - -That's a winning business. Go execute! 🚀 - ---- - -**Start this week. Don't wait.** - -Week 1 Checklist (4 tasks): -- [ ] Assemble core team -- [ ] Secure budget -- [ ] Create pitch deck -- [ ] Start interview recruitment - -Deadline: End of Friday - -Then report back on progress. 💪 - ---- - -**Document Status:** Action-ready, living document -**Last Updated:** February 2026 -**Next Milestone:** Week 4 GO/NO-GO Decision diff --git a/ONBOARDING_FLOWS.md b/ONBOARDING_FLOWS.md new file mode 100644 index 0000000..4084772 --- /dev/null +++ b/ONBOARDING_FLOWS.md @@ -0,0 +1,263 @@ +# InnungsApp — Onboarding Flows + +--- + +## 1. Flow: Neue Innung einrichten (Admin) + +**Dauer:** ~15 Minuten | **Kanal:** Web Admin Dashboard + +``` +Schritt 1: Registrierung (Admin-Konto) +───────────────────────────────────── +→ Admin bekommt Einladungslink von InnungsApp-Team +→ Klickt Link → Magic Link Login → Konto aktiviert + +Schritt 2: Setup-Wizard (Innung konfigurieren) +────────────────────────────────────────────── +Screen 1: "Willkommen! Wie heißt Ihre Innung?" + └─ Eingabe: Innungsname, Slug (auto-generiert) + +Screen 2: "Laden Sie Ihr Logo hoch" + └─ Upload: PNG/SVG, max 2 MB + └─ Vorschau sofort sichtbar + +Screen 3: "Welche Sparten hat Ihre Innung?" + └─ Multi-Select: Elektro, SHK, Bau, Dachdecker, Maler, ... + └─ Freitext: eigene Sparte hinzufügen + +Screen 4: "Kontaktdaten der Innung" + └─ Felder: Adresse, Telefon, E-Mail, Website + +Screen 5: "Mitglieder importieren" + └─ Option A: CSV hochladen (Vorlage herunterladen) + └─ Option B: "Ich füge Mitglieder später manuell hinzu" + └─ Validierung: Fehlende Felder anzeigen, Duplikate warnen + +Screen 6: "Einladungen senden" + └─ Liste der importierten Mitglieder mit E-Mail + └─ Checkbox: "Einladungsmail sofort senden" + └─ Button: "Setup abschließen" + +→ Dashboard wird gezeigt: "Ihre Innung ist bereit!" +``` + +--- + +## 2. Flow: Mitglied lädt sich ein (Erstkontakt) + +**Dauer:** ~2 Minuten | **Kanal:** E-Mail → Mobile App + +``` +E-Mail bei Mitglied +──────────────────── +Betreff: "Sie sind eingeladen: [Innungsname] in der InnungsApp" +Absender: noreply@innungsapp.de + +Inhalt: + "Liebe/r [Vorname], + [Innungsname] hat Sie zur InnungsApp eingeladen. + Klicken Sie den Button, um Ihren kostenlosen Zugang zu aktivieren." + + [Jetzt beitreten] ← Magic Link (7 Tage gültig) + + "Kein Konto anlegen, kein Passwort nötig." + +────────────────────────────────────────────── + +Mitglied klickt Link (Mobile/Desktop) +────────────────────────────────────── +→ Deep Link öffnet InnungsApp (falls installiert) + ODER → Browser: "App herunterladen?" Popup + +→ Account wird automatisch erstellt +→ Redirect zu: First-Use-Onboarding + +────────────────────────────────────────────── + +First-Use Onboarding (Mobile App) +────────────────────────────────── +Screen 1: "Willkommen bei [Innungsname]!" + └─ Logo der Innung wird angezeigt + └─ "Sie sind jetzt Mitglied der [Innungsname] in der App" + [Weiter] + +Screen 2: "Push-Benachrichtigungen erlauben?" + └─ Erklärung: "Erhalten Sie wichtige Mitteilungen sofort" + └─ System-Dialog für Erlaubnis + [Erlauben] / [Später] + +Screen 3: "Was finden Sie in der App?" + └─ Quick Tour: 4 Slides mit Icons + 1. "Mitglieder — Alle Betriebe auf einen Blick" + 2. "Mitteilungen — Keine wichtige Info mehr verpassen" + 3. "Termine — Anmelden mit einem Klick" + 4. "Lehrlingsbörse — Azubis finden oder werden" + [Los geht's] + +→ Redirect zu: Dashboard (Tab Bar) +``` + +--- + +## 3. Flow: Admin lädt Mitglied manuell ein + +**Kanal:** Admin Web Dashboard + +``` +1. Admin navigiert zu: Mitglieder → Neues Mitglied + +2. Formular ausfüllen: + ┌─────────────────────────────────────────┐ + │ Vorname: [Max ] │ + │ Nachname: [Müller ] │ + │ Betrieb: [Müller Sanitär GmbH] │ + │ Sparte: [SHK ▼ ] │ + │ E-Mail: [max@mueller.de ] │ + │ Telefon: [0711-98765 ] │ + │ Ort: [Stuttgart ] │ + │ Status: [Aktiv ▼ ] │ + │ ☑ Ausbildungsbetrieb │ + └─────────────────────────────────────────┘ + [Speichern & Einladung senden] + [Nur Speichern] + +3. Einladungsmail wird sofort gesendet (oder bei Button "Einladung senden" im Mitglied-Profil) + +4. Admin sieht in der Mitgliederliste: + - "Eingeladen am: 15.03.2026" (solange noch kein Login) + - Wechselt zu "Aktiv seit: 15.03.2026" nach erstem Login +``` + +--- + +## 4. Flow: Passwortloser Login (Wiederkehrender Nutzer) + +``` +App öffnen +──────────── +→ Gespeicherte Session vorhanden? + JA → Direkt zu Dashboard (kein Login nötig, Supabase Session ~7 Tage) + NEIN → Login Screen + +Login Screen +──────────── +┌────────────────────────────────────────┐ +│ [Innung Logo] │ +│ │ +│ Melden Sie sich an │ +│ │ +│ E-Mail: [________________] │ +│ │ +│ [Link anfordern] │ +│ │ +│ "Wir schicken Ihnen einen Login-Link." │ +└────────────────────────────────────────┘ + +→ E-Mail erscheint im Postfach innerhalb ~10 Sekunden +→ Klickt Link → App öffnet sich → Eingeloggt + +Fallback: "Kein Link erhalten?" +→ "Link erneut anfordern" (nach 60 Sekunden) +→ "Wenden Sie sich an Ihren Innungsgeschäftsführer" +``` + +--- + +## 5. Flow: Lehrstellenanzeige aufgeben (Mitglied) + +``` +Voraussetzung: Mitglied hat "ausbildungsbetrieb = true" + +1. Tab "Lehrlingsbörse" öffnen +2. Button: "Stelle anbieten" (nur sichtbar wenn ausbildungsbetrieb) + +3. Formular: + ┌──────────────────────────────────────────┐ + │ Beruf: [Elektroniker für Energie- u...] │ + │ Sparte: [Elektrotechnik ▼ ] │ + │ Anzahl Stellen: [2 ▼ ] │ + │ Ausbildungsstart: [August 2026 ] │ + │ Lehrjahr: [1. Lehrjahr ▼ ] │ + │ │ + │ Vergütung: │ + │ 1. Lehrjahr: [800 ] €/Monat │ + │ 2. Lehrjahr: [920 ] €/Monat │ + │ 3. Lehrjahr: [1020 ] €/Monat │ + │ │ + │ Schulabschluss: [Kein ▼ ] │ + │ │ + │ Kontakt: │ + │ Name: [Max Müller ] │ + │ E-Mail: [ausbildung@mueller.de ] │ + │ Telefon: [0711-98765 ] │ + └──────────────────────────────────────────┘ + [Stelle veröffentlichen] + +4. Stelle erscheint sofort in der öffentlichen Lehrlingsbörse +5. Push-Notification an Admin: "Neue Lehrstellenanzeige von Müller Sanitär" +``` + +--- + +## 6. Flow: Azubi-Bewerber (ohne Login) + +``` +Einstieg: Browser oder App (öffentlicher Bereich) +─────────────────────────────────────────────────── +Landing Page: "Ausbildungsplätze bei [Innung]" + +→ Suchzeile: [Beruf oder Ort suchen] +→ Filter: Sparte | Ort | Ausbildungsstart | Lehrjahr + +Suchergebnis: +┌──────────────────────────────────────────────────┐ +│ 🔧 Elektroniker/in │ +│ Müller Elektro GmbH · Stuttgart │ +│ 2 Stellen · ab August 2026 │ +│ Vergütung: 800 € → 920 € → 1.020 € │ +│ [Mehr erfahren] [Jetzt bewerben] │ +└──────────────────────────────────────────────────┘ + +Detailansicht: +→ Vollständige Berufsbeschreibung +→ Vergütungstabelle alle Lehrjahre +→ Anforderungen +→ Betriebsprofil + +Kontaktaufnahme (ohne Login): +Option A: [Anrufen] → tel: Link +Option B: [E-Mail] → mailto: Link +Option C: [Bewerben] → (Post-MVP: In-App-Profil + Chat) +``` + +--- + +## 7. Fehler-Flows + +### Magic Link abgelaufen (7 Tage) + +``` +Nutzer klickt alten Link +───────────────────────── +→ App/Browser zeigt: "Dieser Link ist abgelaufen." +→ "Neuen Link anfordern" Button +→ Gibt E-Mail ein → Neuer Link wird gesendet +``` + +### Nutzer nicht in der Innung (falsche E-Mail) + +``` +→ Login erfolgreich ABER kein user_roles-Eintrag gefunden +→ Screen: "Kein Innungszugang gefunden" +→ "Wenden Sie sich an Ihren Innungsgeschäftsführer" +→ E-Mail-Adresse Ihres Ansprechpartners anzeigen +``` + +### Keine App installiert (Link-Klick im Browser) + +``` +→ Smart App Banner / Universal Link Fallback +→ Browser zeigt: "Öffnen Sie den Link in der InnungsApp" +→ [App im App Store herunterladen] Button +→ Nach Installation: Deep Link wird verarbeitet (Token im Clipboard) +``` diff --git a/PERSONAS.md b/PERSONAS.md new file mode 100644 index 0000000..6413073 --- /dev/null +++ b/PERSONAS.md @@ -0,0 +1,165 @@ +# InnungsApp — User Personas + +--- + +## Persona 1: "Sabine" — Innungsgeschäftsführerin + +**Alter:** 47 | **Ort:** Stuttgart | **Innung:** Innung Elektrotechnik Region Stuttgart (180 Mitglieder) + +### Biografie +Sabine arbeitet seit 12 Jahren als Geschäftsführerin der Elektrotechnik-Innung. Sie hat die Stelle damals von ihrem Vorgänger übernommen und sich alles selbst beigebracht. Sie ist die zentrale Ansprechperson für alle 180 Mitgliedsbetriebe — von der Beitragserhebung bis zur Organisation der Gesellenprüfungen. + +### Ein typischer Tag +- 07:30 Uhr: E-Mails checken — 3 Anmeldungen für den nächsten Kurs per E-Mail, 2 Telefonanfragen wegen Mitgliedsbeiträgen +- 09:00 Uhr: Excel aktualisieren — neues Mitglied, altes ausgetreten +- 11:00 Uhr: Rundschreiben als PDF erstellen, an E-Mail-Verteiler schicken, hoffen dass alle es sehen +- 14:00 Uhr: Teilnehmerliste für die Innungsversammlung — verschiedene WhatsApp-Nachrichten zählen + +### Ziele +- Verwaltungsaufwand reduzieren +- Sicherstellen, dass alle Mitglieder wichtige Infos erhalten +- Mehr Zeit für echte Aufgaben statt Koordination + +### Frustrationen +- **"Ich weiß nie, ob das Rundschreiben gelesen wurde."** +- WhatsApp-Gruppen sind DSGVO-Problem, aber Mitglieder wollen es trotzdem +- Excel ist auf ihrem Laptop — wenn sie krank ist, kommt niemand ran +- Mitglieder rufen sie für Infos an, die sie selbst nachschlagen könnten +- Lehrstellenliste auf der Website ist immer veraltet + +### Tech-Affinität +Mittel. Nutzt täglich Office, E-Mail, WhatsApp. Hat kein Interesse an komplexen Tools. Will klare, einfache Lösungen. + +### Zitat +> "Wenn ich eine neue Software einführe, muss ich auch noch die 180 Mitglieder beibringen, wie sie funktioniert. Das ist das Eigentliche." + +### Was sie von InnungsApp erwartet +- Zeitersparnis bei Routinetätigkeiten (Min. 3h/Woche) +- Endlich wissen, wer Mitteilungen gelesen hat +- Mitglieder können selbst nachschauen statt anzurufen +- DSGVO-konforme Alternative zu WhatsApp + +--- + +## Persona 2: "Markus" — Innungsmitglied (Betriebsinhaber) + +**Alter:** 52 | **Ort:** Esslingen | **Betrieb:** Müller Sanitär GmbH (8 Mitarbeiter, 2 Azubis) + +### Biografie +Markus hat seinen Betrieb vor 18 Jahren von seinem Vater übernommen. Handwerk ist für ihn Leidenschaft. Er ist Mitglied der SHK-Innung seit Anfang an. Die Innung schätzt er für die Geselligkeit und die gemeinsame Interessenvertretung — nicht für ihre Digitalisierung. + +### Ein typischer Tag +- 06:00 Uhr: Auf der Baustelle. Kein Laptop, nur Smartphone +- 10:00 Uhr: Kurze Pause — WhatsApp-Nachrichten checken +- 12:00 Uhr: Mittagspause im Büro. E-Mails. Meist zu viele, überfliegt sie +- 14:00 Uhr: Zurück auf Baustelle +- 17:00 Uhr: Bürokram, Rechnungen, nächsten Tag planen + +### Ziele +- Seinen Betrieb und seine Azubis sauber managen +- Neue Azubis finden — er hat seit 2 Jahren eine unbesetzte Stelle +- Informationen von der Innung schnell und einfach bekommen + +### Frustrationen +- **"Ich vergesse Innungstermine, weil die E-Mail im Spam landet."** +- Azubi-Suche über die Innung ist kompliziert — Formular ausfüllen, auf Website warten +- Hat keine Zeit für langsame digitale Prozesse +- Will keine zehn verschiedenen Apps + +### Tech-Affinität +Niedrig bis mittel. Nutzt Smartphone intensiv (WhatsApp, Google Maps, Bankapp). Hat keinen Laptop auf der Baustelle. Hates Apps die mehr als 2 Klicks brauchen. + +### Zitat +> "Ich brauche das auf dem Handy, einfach. Wenn es kompliziert ist, mache ich es nicht." + +### Was er von InnungsApp erwartet +- Push-Notifications für wirklich wichtige Neuigkeiten +- Einen Azubi finden über die Innung (Lehrlingsbörse) +- Schnell sehen, wann der nächste Innungstermin ist und sich anmelden + +--- + +## Persona 3: "Lukas" — Azubi-Bewerber (Gen Z) + +**Alter:** 16 | **Ort:** Heilbronn | **Schulform:** Realschule (Klasse 10) + +### Biografie +Lukas interessiert sich fürs Handwerk — sein Onkel ist Elektriker, und Lukas hat ihm manchmal geholfen. Er weiß aber nicht genau, was er machen will. Er googelt manchmal "Ausbildung Elektriker", landet auf veralteten Websites der Innung mit kaputten Links. + +### Verhalten +- 5+ Stunden täglich auf dem Smartphone +- TikTok, Instagram, YouTube, Snapchat +- Hat noch nie einen "formellen" Bewerbungsprozess erlebt +- Würde keinen CV auf Papier schicken — kennt das Konzept kaum +- Entscheidet visuell und emotional, nicht rational + +### Ziele +- Einen coolen Ausbildungsplatz finden, der zu ihm passt +- Herausfinden, was Handwerk-Berufe wirklich bedeuten (nicht Theorie, sondern Praxis) +- Möglichst wenig Aufwand für die Bewerbung + +### Frustrationen +- Websites der Innungen / Betriebe sind hässlich und unübersichtlich +- **"Bewerbung per Post? Wer macht das noch?"** +- Keine echten Bilder oder Videos vom Arbeitsalltag +- Tabellarischer Lebenslauf fühlt sich wie Chinesisch an + +### Tech-Affinität +Sehr hoch (Konsument). Erwartet mobile-first, visuell, schnell. + +### Zitat +> "Wenn ich auf einer Website surfe und es sieht aus wie 2005, gehe ich sofort weg." + +### Was er von InnungsApp erwartet (Azubi-Modul) +- Videos von echten Azubis, die ihren Job zeigen +- Transparente Vergütungsinfo ("Was verdiene ich wirklich?") +- 1-Click Bewerbung: kein PDF, kein Lebenslauf — ein Profil reicht +- Antwort vom Betrieb per Chat + +--- + +## Persona 4: "Fatima" — Azubine (im 2. Lehrjahr) + +**Alter:** 18 | **Ort:** Mannheim | **Beruf:** Anlagenmechanikerin SHK + +### Biografie +Fatima ist im 2. Lehrjahr ihrer SHK-Ausbildung. Sie mag ihren Job, aber das Berichtsheft nervt sie massiv. Jeden Abend schreibt sie mit der Hand rein, was sie tagsüber gemacht hat. Manchmal vergisst sie es. + +### Ziele +- Ihre Ausbildung erfolgreich abschließen +- Den Berufsschulstoff nachvollziehen +- Weniger Papierkram + +### Frustrationen +- **"Das Berichtsheft ist so ein Aufwand. Ich mache das spät nachts."** +- Prüfungsvorbereitung: Es gibt keine gute App für SHK-Fachwissen +- Termine der Innung (Lossprechung, Zwischenprüfung) erfährt sie vom Betrieb, nicht direkt + +### Was sie von InnungsApp erwartet (Post-MVP) +- Digitales Berichtsheft: Fotos machen, Sprachnotiz, fertig +- Prüfungsfragen als tägliches Quiz +- Push-Notification bei ihren Innungsterminen + +--- + +## Persona 5: "Georg" — Obermeister + +**Alter:** 64 | **Ort:** Freiburg | **Funktion:** Obermeister Dachdecker-Innung Südbaden + +### Biografie +Georg ist seit 8 Jahren Obermeister. Er führt den Vorsitz ehrenamtlich neben seinem eigenen Betrieb (15 Mitarbeiter). Er repräsentiert die Innung nach außen, hält Reden bei Freisprechungen, verhandelt mit der HWK. + +### Ziele +- Die Innung modernisieren, ohne die Tradition zu verlieren +- Dem Vorstand regelmäßig Rechenschaft über den Mitgliederservice ablegen +- Ein attraktives Bild der Innung nach außen zeigen + +### Frustrationen +- Keine Übersicht, wie viele Mitglieder aktiv sind +- Muss für Statistiken die Geschäftsführerin anrufen +- **"Ich will zeigen, dass unsere Innung digital ist. Aber womit?"** + +### Was er von InnungsApp erwartet +- Repräsentatives Auftreten der Innung mit Logo und Farben +- Einfaches Reporting für den Vorstand +- Lehrlingsbörse als Aushängeschild nach außen diff --git a/PRD.md b/PRD.md new file mode 100644 index 0000000..4cdf33f --- /dev/null +++ b/PRD.md @@ -0,0 +1,253 @@ +# InnungsApp — Product Requirements Document (PRD) + +> **Version:** 2.0 | **Status:** In Review | **Owner:** Timo Knuth +> **Zielmarkt:** Innungen & Kreishandwerkerschaften in Deutschland + +--- + +## 1. Problemdefinition + +### 1.1 Status Quo bei Innungen + +Deutsche Handwerksinnungen verwalten ihre Mitglieder und kommunizieren heute mit: +- **Excel-Tabellen** für Mitgliederverwaltung (lokal, nicht synchronisiert) +- **WhatsApp-Gruppen** für interne Kommunikation (DSGVO-Problem) +- **E-Mail-Verteiler** für Rundschreiben (kein Tracking, kein Self-Service) +- **PDF-Formulare** per Post für Anmeldungen (langsam, fehleranfällig) +- **Vereinzelte Websites** für die Lehrstellenbörse (veraltet, schlecht mobil) + +### 1.2 Konkrete Pain Points + +**Geschäftsführer / Admin:** +- Mitgliederdaten pflegen ist zeitaufwendig (manuelle Excel-Updates) +- Keine Ahnung, ob Rundschreiben gelesen wurden +- Terminanmeldungen kommen per Telefon und E-Mail — chaotisch +- Lehrstelleninserate manuell auf Website pflegen + +**Innungsmitglied (Betrieb):** +- Verpasst wichtige Informationen, weil E-Mails übersehen werden +- Keine Möglichkeit, Ausbildungsstellen einfach zu veröffentlichen +- Muss für jede Kleinigkeit den Geschäftsführer anrufen + +**Azubi-Bewerber (Gen Z):** +- Stellenangebote auf Websites sind veraltet und langweilig +- Muss PDF-Bewerbungen per E-Mail schicken (antiquiert) +- Kein Einblick in den Berufsalltag + +### 1.3 Warum jetzt? + +1. **Fachkräftemangel als Treiber:** ~250.000 unbesetzte Ausbildungsplätze in Deutschland (2025) +2. **Digitalisierungsdruck:** Post-Corona haben Innungen erkannt, dass digitale Tools fehlen +3. **Generationenwechsel:** Jüngere Obermeister und Geschäftsführer sind technikaffin +4. **Fördergelder:** BMWi und HWKs haben Digitalisierungsprogramme mit Budget + +--- + +## 2. Produktvision + +**Vision Statement:** +> InnungsApp wird die Standard-Infrastruktur des deutschen Handwerks — die Plattform, auf der Innungen verwalten, kommunizieren, Azubis finden und ihre Mitglieder vernetzen. + +**Mission:** +> Das deutsche Handwerk digital und zukunftsfähig machen — beginnend mit dem direkten Werkzeug jeder Innung. + +--- + +## 3. Zielgruppe & Rollen + +### Primäre Käufer (B2B) + +| Rolle | Beschreibung | Hauptmotivation | +|---|---|---| +| **Innungsgeschäftsführer** | Hauptadmin, verwaltet alles | Zeitersparnis, Übersicht | +| **Obermeister** | Vorsitzender der Innung | Reputation, Mitgliederservice | + +### Primäre Nutzer (Enduser) + +| Rolle | Beschreibung | Hauptbedürfnis | +|---|---|---| +| **Mitglied (Betrieb)** | Inhaberin/Inhaber des Mitgliedsbetriebs | Information, Azubi finden | +| **Azubi-Bewerber** | 15–20 Jahre, sucht Ausbildungsplatz | Einfache, moderne Bewerbung | +| **Lernender (Azubi)** | In der Ausbildung | Berichtsheft, Prüfungsvorbereitung | + +### Sekundäre Nutzer (Post-MVP) + +- Prüfungsausschüsse (Gesellenprüfungen) +- HWK-Mitarbeiter (übergeordnete Verwaltung) +- Lieferanten / Hersteller (Marktplatz-Modul) + +--- + +## 4. Feature-Scope MVP + +### 4.1 Modul: Mitgliederverzeichnis + +**Ziel:** Zentrales, durchsuchbares Verzeichnis aller Mitgliedsbetriebe. + +**User Stories:** +- Als Mitglied möchte ich andere Betriebe in meiner Innung finden, um mich zu vernetzen +- Als Admin möchte ich Mitglieder anlegen, bearbeiten und deaktivieren + +**Funktionen:** +- Liste aller Mitgliedsbetriebe mit Suche und Filter +- Filter: Sparte, Ort, Ausbildungsbetrieb ja/nein, Status +- Detailansicht: Name, Betrieb, Sparte, Ort, Telefon, E-Mail, Website, Ausbildungsbetrieb +- Direktkontakt: Tap-to-Call, Tap-to-Mail +- Admin-CRUD: Mitglied anlegen, bearbeiten, deaktivieren, Einladungs-E-Mail senden +- Status-Management: aktiv / ruhend / ausgetreten + +**Nicht im MVP:** +- Öffentliches Unternehmensverzeichnis (für Endkunden) +- Bewertungssystem +- Karten-/Geo-Ansicht +- CRM-Integration + +--- + +### 4.2 Modul: Mitteilungen & News + +**Ziel:** Gesteuerter Kommunikationskanal von der Innung an ihre Mitglieder. + +**User Stories:** +- Als Admin möchte ich Mitteilungen mit Push-Notification versenden, um sicherzustellen, dass alle erreicht werden +- Als Mitglied möchte ich wichtige Mitteilungen einfach finden und nicht in E-Mails suchen müssen + +**Funktionen:** +- Feed aller Beiträge, chronologisch sortiert +- Kategorien: Wichtig / Prüfung / Förderung / Veranstaltung / Allgemein +- Push-Notification bei neuem Beitrag (optional konfigurierbar) +- Ungelesen/Gelesen-Status pro Nutzer und Beitrag +- PDF-Anhänge (Rundschreiben, Formulare) +- Admin: Beitrag erstellen, bearbeiten, löschen, zeitgesteuert veröffentlichen +- Admin: Leserate pro Beitrag einsehen + +**Nicht im MVP:** +- Kommentarfunktion (erhöht Moderationsaufwand) +- Mitglieder-Posts (asymmetrischer Kanal gewollt) +- Direktnachrichten / Chat + +--- + +### 4.3 Modul: Lehrlingsbörse (Basic) + +**Ziel:** Ausbildungsplätze der Mitgliedsbetriebe einfach veröffentlichen und finden. + +**User Stories:** +- Als Betrieb möchte ich meine Ausbildungsstellen einfach einstellen, ohne die Innung fragen zu müssen +- Als Bewerber möchte ich Stellen ohne Registrierung durchsuchen + +**Funktionen (Betrieb):** +- Stelle anlegen: Sparte, Anzahl, Vergütung nach Lehrjahr, Ausbildungsstart, Kontakt +- Stelle aktivieren / pausieren / löschen +- Bewerbungskontakt: E-Mail oder Telefon + +**Funktionen (Bewerber, öffentlich ohne Login):** +- Stellenliste durchsuchen +- Filter: Sparte, Ort, Lehrjahr, Ausbildungsstart +- Direktkontakt zum Betrieb (E-Mail / Telefon) + +**Nicht im MVP:** +- In-App Bewerbungsformular +- Matching-Algorithmus +- Video-Feed (→ Azubi-Modul Advanced, Q2) +- Berichtsheft + +--- + +### 4.4 Modul: Termine & Veranstaltungen + +**Ziel:** Veranstaltungskalender mit An-/Abmeldefunktion und Teilnehmermanagement. + +**User Stories:** +- Als Admin möchte ich Termine anlegen und die Teilnehmerliste einsehen +- Als Mitglied möchte ich mich für Veranstaltungen anmelden und den Termin in meinen Kalender exportieren + +**Funktionen:** +- Terminliste mit Typ-Tags: Prüfung / Versammlung / Kurs / Event / Lossprechung +- Termindetail: Titel, Datum, Uhrzeit, Ort, Beschreibung, Typ +- An-/Abmeldung mit E-Mail-Bestätigung +- Kalenderexport: iCal / Google Calendar / Outlook +- Admin: Termin anlegen, Teilnehmerliste exportieren (CSV) +- Push-Notification 24h vor Termin + +**Nicht im MVP:** +- Bezahlte Events / Ticketing +- Wartelisten-Management +- Videokonferenz-Links (Q2) +- Saalplan / Sitzordnung + +--- + +### 4.5 Modul: Admin-Dashboard (Web) + +**Ziel:** Webbasiertes Backend für Innungsgeschäftsführer. + +**Funktionen:** +- Übersicht: Mitgliederzahl, aktive Nutzer, ungelesene Beiträge +- Mitgliederverwaltung: CRUD, Massenimport via CSV, Einladungsversand +- Newsroom: Beiträge erstellen, planen, Leserate sehen +- Terminverwaltung: CRUD, Teilnehmerliste +- Lehrstellenverwaltung: Alle Stellen aller Betriebe einsehen und moderieren +- Einstellungen: Innungslogo, Farbe, Kontaktdaten, Spartenverzeichnis +- Einfache Analytics: DAU/MAU, Aktivierungsrate, meistgelesene Beiträge + +**Tech:** Next.js Web-App auf `app.innungsapp.de/admin` + +--- + +## 5. Out of Scope — MVP + +| Feature | Begründung | Roadmap | +|---|---|---| +| Chat / Direktnachrichten | Moderation, DSGVO-Komplexität | Q3 2026 | +| Dokumentenarchiv | Fokus zuerst auf Kernkommunikation | Q2 2026 | +| Prüfungsverwaltung | Hochreguliert, eigenes Produkt | Q4 2026 | +| Mitgliederbeiträge / Buchhaltung | Buchhaltungsintegration nötig | 2027 | +| Video-Feed (TikTok-Style) | Eigenes Azubi-Modul | Q2 2026 | +| Berichtsheft digital | Komplex, eigenes Feature | Q3 2026 | +| Mehrsprachigkeit | Zielgruppe DE-only | 2027 | +| White-Label für HWK | Post Product-Market-Fit | Q4 2026 | +| Marktplatz / Lieferantenportal | Separate Business Unit | 2027 | + +--- + +## 6. Nicht-funktionale Anforderungen + +### Performance +- App-Ladezeit (Cold Start): < 3 Sekunden +- Feed-Ladezeit: < 1 Sekunde +- Push-Notification-Delivery: > 95 % innerhalb 30 Sekunden + +### Sicherheit & Datenschutz +- DSGVO-konform: Datenverarbeitung nur in EU (Frankfurt) +- AVV (Auftragsverarbeitungsvertrag) mit jeder Innung +- Row Level Security: Jede Innung sieht ausschließlich ihre eigenen Daten +- Keine Weitergabe von Mitgliederdaten an Dritte +- Datenlöschung auf Anfrage innerhalb 30 Tage + +### Verfügbarkeit +- Uptime-Ziel: 99,5 % (Supabase SLA) +- Geplante Wartungsfenster: nachts 02:00–04:00 Uhr + +### Skalierbarkeit +- MVP-Kapazität: 100 Innungen, je bis 500 Mitglieder +- Skalierung auf 10.000 Innungen ohne Architekturänderung (Supabase managed) + +### Barrierefreiheit +- iOS: Unterstützung für Dynamic Type und VoiceOver +- Mindest-Textgröße: 14pt +- Kontrastverhältnis: WCAG AA + +--- + +## 7. Akzeptanzkriterien MVP + +| Feature | Kriterium | +|---|---| +| Login | Nutzer kann sich via Magic Link in < 60 Sek. einloggen | +| Mitgliederverzeichnis | Admin kann Mitglied in < 2 Minuten anlegen | +| News | Beitrag ist nach Veröffentlichung in < 10 Sek. für alle sichtbar | +| Push-Notification | 95 % der Nutzer empfangen Push innerhalb 30 Sek. | +| Lehrlingsbörse | Stelle ist öffentlich sichtbar ohne Login | +| Termine | Anmeldung + Kalenderexport in < 3 Klicks | +| Multi-Tenancy | Kein Mitglied sieht Daten einer anderen Innung | diff --git a/README.md b/README.md index f718880..3d1ac99 100644 --- a/README.md +++ b/README.md @@ -1,297 +1,73 @@ -# Analyse: Pain Points deutscher Stadtwerke und Softwarelösungen +# InnungsApp — Projektübersicht -**Gesamtes Projekt-Archiv für Geschäftsidee-Evaluierung** +> **SaaS-Plattform für Innungen & Kreishandwerkerschaften in Deutschland** +> **Version:** 2.0 | **Status:** Pre-MVP | **Stand:** Februar 2026 --- -## 📋 Überblick +## Was ist InnungsApp? -Diese Analyse untersucht die **5 größten operativen Probleme** deutscher Stadtwerke und präsentiert **konkrete, schnell umsetzbare Softwarelösungen**. Der Gesamtmarkt wird auf **10-25 Millionen EUR** in den nächsten 3 Jahren geschätzt. +InnungsApp ist eine mobile-first SaaS-Plattform, die Innungen und Kreishandwerkerschaften digitalisiert. Sie löst zwei akute Probleme gleichzeitig: -**Zielgruppe:** Geschäftsführer, Investoren, Softwareentwickler, Stadtwerk-Manager +1. **Innungsverwaltung:** Mitglieder, News, Termine und interne Kommunikation aus Excel und WhatsApp-Gruppen heraus in eine professionelle App +2. **Azubi-Recruiting:** Fachkräftemangel bekämpfen — durch eine TikTok-inspirierte Lehrstellenbörse, die Gen Z dort abholt, wo sie ist ---- +## Marktgröße -## 📁 Dokumentstruktur +| Segment | Anzahl | Adressierbar | +|---|---|---| +| Innungen in Deutschland | ~7.500 | Ja | +| Kreishandwerkerschaften | ~500 | Ja | +| Mitgliedsbetriebe | ~500.000 | Indirekt | +| Offene Ausbildungsplätze | ~250.000 | Ja | -### 1. **EXECUTIVE_SUMMARY.md** (5-10 Min Lesedauer) - - Für: C-Level, Investoren, schnelle Übersicht - - Inhalt: - - Kernfinding & Top 5 Pain Points - - Marktgröße & Geschäftsmodell - - Finanzielle Projektion (Revenue, Break-Even, Exit Multiple) - - Investment Thesis - - Nächste Schritte +## Kern-These - **Wann lesen:** Zuerst! (Executive Overview) +> 7.500 Innungen verwalten ihre Mitglieder heute mit Excel und WhatsApp. +> Eine branchenspezifische App mit 200 €/Monat × 500 Kunden = **1,2 Mio. € ARR**. +> Der Azubi-Mangel macht dieses Tool zum **Überlebenswerkzeug** — kein Nice-to-have. ---- +## Dokumente -### 2. **quick_reference.txt** (10-15 Min Lesedauer) - - Für: Quick Lookup, Meeting Vorbereitung - - Inhalt: - - One-Page Übersicht aller 5 Pain Points - - Timing, Pricing, TTM - - Implementierungs-Timeline - - GO-to-Market Strategie - - Finanzielle Projekte +| Datei | Inhalt | +|---|---| +| `PRD.md` | Vollständige Produktspezifikation | +| `ARCHITECTURE.md` | Technische Architektur | +| `DATABASE_SCHEMA.md` | Datenbankschema (SQL) | +| `USER_STORIES.md` | User Stories nach Rolle | +| `PERSONAS.md` | Nutzerprofile | +| `BUSINESS_MODEL.md` | Preismodell & Unit Economics | +| `ROADMAP.md` | Entwicklungsplan | +| `COMPETITIVE_ANALYSIS.md` | Wettbewerbsanalyse | +| `FEATURES_BACKLOG.md` | Feature Backlog | +| `API_DESIGN.md` | API-Endpunkte | +| `ONBOARDING_FLOWS.md` | Onboarding-Flows | +| `GTM_STRATEGY.md` | Go-to-Market Strategie | +| `VALIDATION_PLAYBOOK.md` | Validierungsstrategie | +| `AZUBI_MODULE.md` | Azubi-Recruiting Modul | +| `DSGVO_KONZEPT.md` | Datenschutz & Compliance | - **Wann lesen:** Zweites! (Für schnelle Referenz während Meetings) +## Tech Stack (Überblick) ---- +- **Mobile:** React Native + Expo +- **Web Admin:** Next.js +- **Backend:** Supabase (PostgreSQL, Auth, Storage, Realtime) +- **Video:** Mux / Cloudflare Stream +- **Hosting:** Vercel +- **Analytics:** PostHog -### 3. **stadtwerke_analysis.md** (30-40 Min Lesedauer) - - Für: Detaillierte Analyse, Product Manager, Technische Teams - - Inhalt: - - Umfassende Analyse aller 5 Pain Points: - 1. Zählerablesung (SmartMeter-Lite) - 2. Abschlagsrechnung (AbschlagAssistant) - 3. Entstörung (OutageAlert Pro) - 4. Kundenservice (Kundenservice 360) - 5. Abrechnung (RechnungsAnalyzer+) - - Für jeden Pain Point: - - Problem Beschreibung - - Konkrete Lösung - - Tech-Stack - - Time-to-Market - - Verkaufspotenzial & ROI - - Implementierungs-Roadmap (Phase 1-3) - - Geschäftsmodell-Optionen - - Critical Success Factors +## Quickstart - **Wann lesen:** Für tiefes Verständnis und Konzept-Validation +```bash +# Repo klonen +git clone https://gitea.bizmatch.net/tknuth/stadtwerke.git +cd stadtwerke ---- - -### 4. **implementation_roadmap.md** (40-50 Min Lesedauer) - - Für: Entwicklungsteams, Projektmanager, CTO - - Inhalt: - - Detaillierte 6-Monats-Timeline - - Sprint-by-Sprint Breakdown für jede Lösung - - Team-Struktur & Org Design - - Tech Stack Empfehlungen - - Sicherheits-Anforderungen - - Success Metrics & KPIs - - Risk & Mitigation Strategies - - Budget Breakdown - - Next Immediate Steps - - **Wann lesen:** Für Implementierungsplanung und Team-Onboarding - ---- - -### 5. **detailed_use_cases.md** (20-30 Min Lesedauer) - - Für: Sales, Marketing, Product Owner, Investoren - - Inhalt: - - 5 Detaillierte Kundenszenarien: - * Anna Mueller (Zählerablesung Problem) - * Klaus Schmidt (Abschlag Verwirrung) - * Familie Bergmann (Stromausfall Angst) - * Sabine Weber (Customer Service Frustration) - * Hans Mueller (Abrechnungs-Unklarheit) - - Vorher/Nachher Vergleiche - - Emotionale Impact & Metriken - - Business Outcomes mit konkreten Zahlen - - **Wann lesen:** Für Empathie-Building und Sales Pitch Entwicklung - ---- - -## 🎯 Lesepfade nach Rolle - -### 👔 **Geschäftsführer / Investor** -1. EXECUTIVE_SUMMARY.md (5 min) -2. quick_reference.txt - Finanzen Section (3 min) -3. detailed_use_cases.md - Executive Summary (5 min) - -**Total: 13 Minuten** - ---- - -### 💻 **CTO / Technischer Leiter** -1. EXECUTIVE_SUMMARY.md (10 min) -2. stadtwerke_analysis.md - Tech Stack Sections (15 min) -3. implementation_roadmap.md - Tech Stack & Architecture (20 min) -4. quick_reference.txt - Timeline Section (10 min) - -**Total: 55 Minuten** - ---- - -### 📊 **Product Manager** -1. EXECUTIVE_SUMMARY.md (10 min) -2. stadtwerke_analysis.md - Alle Pain Points (35 min) -3. detailed_use_cases.md - Alle Use Cases (25 min) -4. implementation_roadmap.md - Success Metrics (10 min) - -**Total: 80 Minuten (Deep Dive)** - ---- - -### 🎤 **Sales / Business Development** -1. EXECUTIVE_SUMMARY.md (10 min) -2. detailed_use_cases.md - Alle Szenarien (25 min) -3. quick_reference.txt - GO-to-Market Section (8 min) -4. stadtwerke_analysis.md - Pain Points Overview (15 min) - -**Total: 58 Minuten** - ---- - -### 👨‍💼 **Stadtwerk-Manager (Prospect)** -1. EXECUTIVE_SUMMARY.md (10 min) -2. detailed_use_cases.md - Relevant pain points (10 min) -3. stadtwerke_analysis.md - Your Problem + Solution (15 min) -4. implementation_roadmap.md - Implementation Plan (10 min) - -**Total: 45 Minuten** - ---- - -## 🔑 Key Takeaways - -### Top 5 Pain Points (Priorität) - -| # | Problem | Lösung | TTM | Marktpotenzial | -|---|---------|--------|-----|-----------------| -| 1 | **Zählerablesung** Manuelle Prozesse, 30-40% Fehler | SmartMeter-Lite App | 8-12 Wo | 4-8M EUR/Y2-3 | -| 2 | **Abschlag** Unklar, 45% unzufrieden | AbschlagAssistant Tool | 6-10 Wo | 3-6M EUR/Y1 | -| 3 | **Entstörung** Keine Info, 30-60 min Wartezeit | OutageAlert Pro | 10-14 Wo | 2-4M EUR/Y2-3 | -| 4 | **Support** Fragmentiert, lange Wartezeit | Kundenservice 360 | 12-16 Wo | 3-6M EUR/Y2-3 | -| 5 | **Abrechnung** Komplex, 25-30% Beschwerde | RechnungsAnalyzer+ | 10-14 Wo | 1-3M EUR/Y2-3 | - ---- - -## 💰 Finanzielle Highlights - -### Geschäftsmodell: B2B SaaS -- **Basis-Preis:** 1.000 - 20.000 EUR/Monat (je nach Stadtwerk-Größe) -- **Average ACV:** 120.000 EUR/Jahr -- **CAC (Customer Acq. Cost):** 40K EUR -- **LTV:CAC Ratio:** 3:1 (healthy) - -### Revenue Projektion -- **Year 1:** 2.0M EUR (880K EUR Conservative) -- **Year 2:** 8.0M EUR (3.6M EUR Conservative) -- **Year 3:** 18.0M EUR (7.2M EUR Conservative) - -### Investment & Return -- **Required Capital:** 2.0 - 3.0M EUR -- **Break-Even:** Month 18-20 -- **3-Year Exit Multiple:** 45x+ Return (bei 5-8x Revenue Multiple) -- **Expected Exit Value:** 90-144M EUR - ---- - -## 🚀 Nächste Schritte - -1. **Diese Woche:** - - [ ] EXECUTIVE_SUMMARY.md lesen (5 min) - - [ ] Quick Reference speichern als mobile Reference (5 min) - - [ ] Team zusammenstellen (1-2 Std) - -2. **Nächste Woche:** - - [ ] Stakeholder Interviews vorbereiten (3 Stadtwerke) - - [ ] Technical Architecture Review - - [ ] Competitive Landscape Deep-Dive - -3. **In 2 Wochen:** - - [ ] Product Requirements Document (PRD) verfassen - - [ ] MVP Development starten (Pain Point #1) - - [ ] Investor Pitch finalisieren - ---- - -## 📊 Statistiken auf einen Blick +# Supabase lokal starten +npx supabase init +npx supabase start +# Expo App starten +cd apps/mobile +npx expo start ``` -Gesamtmarktgröße (3 Jahre): 10-25 Millionen EUR -Zielmarkt Haushalte: 8-10 Millionen -Zielmarkt Stadtwerke: Top 100 von 900+ -Durchschnitt Support-Anfragen: 60-70% vermeidbar -Durchschn. NPS-Improvement: +70 Punkte -Durchschn. Support-Kostensparnis: -40% bis -70% -Customer Satisfaction: +35% bis +75% -``` - ---- - -## 🛠️ Verwendete Methoden - -Diese Analyse basiert auf: -- ✅ **Branchenkenntnisse** zu deutschen Stadtwerken -- ✅ **Recherchen** bei Top 20 Stadtwerken (München, Berlin, Hamburg, Köln, etc.) -- ✅ **Customer Pain Point Analysis** (Support-Kanäle, FAQ, Beschwerde-Datenbanken) -- ✅ **Competitive Intelligence** (SAP, Oracle, Zendesk, etc.) -- ✅ **Financial Modeling** (Unit Economics, Revenue Projections) -- ✅ **Technical Feasibility** (Tech Stack, TTM Estimation) - ---- - -## ⚠️ Disclaimer - -Diese Analyse basiert auf öffentlich verfügbaren Informationen und Branchenkenntnissen. Die Zahlen sind Schätzungen und können variieren je nach: -- Spezifischen Stadtwerk-Anforderungen -- Marktdynamiken -- Technologischen Änderungen -- Regulatory Landscape - -Für Investitionsentscheidungen wird empfohlen: -- Detaillierte Due Diligence mit Stadtwerken -- Technical Proof-of-Concept -- Unabhängige Finanzprüfung -- Legal Review - ---- - -## 📞 Kontakt & Support - -Für Fragen zu dieser Analyse: - -- **Technische Fragen:** [Technical Lead] -- **Geschäftsfragen:** [Product Manager] -- **Sales/Partnership:** [Business Development] -- **Finanzielle Modelle:** [CFO/Finance] - ---- - -## 📅 Dokumentversionierung - -| Version | Datum | Änderungen | -|---------|-------|-----------| -| 1.0 | Feb 2026 | Initial Analysis | - -**Nächste Review:** November 2026 - ---- - -## 🎓 Bildungs-Ressourcen - -Falls Sie mehr über diese Themen lernen möchten: - -### Deutsches Stadtwerk-System -- VKU (Verband Kommunaler Unternehmen): www.vku.de -- WAGA (Wasser Abwasser Energie): www.waga-fachtagung.de - -### SaaS & Business Model -- "The SaaS Playbook" (Blake Bartlett) -- "Crossing the Chasm" (Geoffrey Moore) - -### Kundenservice Excellence -- "The Service Profit Chain" (Harvard Business Review) -- "Net Promoter System" (Fred Reichheld) - ---- - -## 🏁 Schlusswort - -Diese Analyse identifiziert eine **attraktive Marktgelegenheit** im deutschen Stadtwerk-Sektor. Mit den richtigen Teams, Technologie und Geduld (Sales Cycle: 60-90 Tage) ist ein **Multi-Million Euro Geschäft** innerhalb von 3 Jahren aufzubauen. - -**Kernerfolgsfaktor:** Schnelle MVP-Entwicklung, starke Product-Market-Fit durch direkte Kunden-Zusammenarbeit, und konsequente Fokussierung auf konkrete Pain Points. - ---- - -**Last Updated:** Februar 2026 -**Document Status:** FINAL für Sharing -# stadtwerke - \ No newline at end of file diff --git a/REALISTIC_VS_OPTIMISTIC.md b/REALISTIC_VS_OPTIMISTIC.md deleted file mode 100644 index 5fb27cd..0000000 --- a/REALISTIC_VS_OPTIMISTIC.md +++ /dev/null @@ -1,290 +0,0 @@ -# Realistic vs. Optimistic Scenario - -**Datum:** Februar 2026 -**Status:** REVISED - Focused on MVP-only approach - ---- - -## 🎯 The Fundamental Question - -**Scenario 1 (OPTIMISTIC):** -- Build all 5 Solutions at once -- €2M Investment -- Y1: 2M EUR ARR -- Y3: 18M EUR ARR - -**Scenario 2 (REALISTIC):** -- Build SmartMeter-App (#1 only) -- €350-450K Investment -- Y1: 500K-1.2M EUR ARR -- Y3: 5-10M EUR ARR - ---- - -## Side-by-Side Comparison - -### Development & Product - -| Aspekt | Optimistic (❌ NICHT EMPFOHLEN) | Realistic (✅ EMPFOHLEN) | -|--------|----------------------------------|-------------------------| -| **Scope** | All 5 Pain Points parallel | Only #1 (SmartMeter) MVP | -| **Development Time** | 6 Monate (alle 5) | 4-6 Wochen (nur #1) | -| **Team Size** | 10+ Developer | 3-4 Developer | -| **Tech Stack** | Multiple (Web, Mobile, OCR, KI) | Focused (React Native, OCR) | -| **Complexity** | Very High | Medium | -| **Time-to-Market** | 6 Monate | 4-6 Wochen ✅ | -| **Quality** | Schnell & shallow | Tiefgehendes & poliert ✅ | - -### Investment & Burn - -| Aspekt | Optimistic | Realistic ✅ | -|--------|-----------|-----------| -| **MVP Investment** | €700K - 1.1M | €250-350K | -| **Total Seed** | €2.0-3.0M | €600-800K | -| **Monthly Burn** | €120-150K | €40-50K | -| **Runway (mit 600K)** | 4-5 Monate | 12-15 Monate | -| **Runway (mit 1M)** | 6-7 Monate | 20+ Monate | - -**Kritik:** Mit €2M für MVP ist man unter Druck, schnell Umsatz zu machen. Mit €350K ist der Druck niedriger, aber fokussierter. - -### Sales & GTM - -| Aspekt | Optimistic | Realistic ✅ | -|--------|-----------|-----------| -| **Sales Approach** | Direct + Inbound | Partnership-First oder Direct | -| **Sales Team Y1** | 2-3 Personen | 1 Founder + 1 Partner | -| **Pilot Kunden** | 10+ | 5 (kostenlos) | -| **First Paying Customer** | Month 6-9 | Month 6-8 | -| **Sales Cycle** | 60-90 Tage | 60-90 Tage (same) | -| **Kunden Y1 Ende** | 15-20 | 5-10 | - -**Kritik:** Die optimistische Version braucht 2-3 Sales Personen. Das ist teuer in der Früh-Phase. - -### Revenue & Profitability - -| Metrik | Optimistic | Realistic ✅ | -|--------|-----------|-----------| -| **Y1 ARR** | €2.0M | €500K-1.2M | -| **Y2 ARR** | €8.0M | €2-4M | -| **Y3 ARR** | €18.0M | €5-10M | -| **Y1 Customers** | 15-20 | 5-10 | -| **Y2 Customers** | 40+ | 20-35 | -| **Break-Even** | Month 18-20 | Month 18-22 | -| **EBITDA Y2** | 20%+ | 0-15% | - -**Kritik:** Optimistic ist zu aggressive. Realistic ist mehr defensiv. - ---- - -## Why Realistic is Better - -### 1. **Lower Burn Rate = More Time** -- Optimistic: €120-150K/Monat → Need revenue in 6 months -- Realistic: €40-50K/Monat → Can grow more deliberately - -### 2. **Product Quality > Speed** -- Optimistic: 5 features, all decent -- Realistic: 1 feature, absolutely excellent ✅ - -**Impact:** A great SmartMeter app sells itself. A mediocre 5-in-1 platform doesn't. - -### 3. **Lower Risk for Investors** -- Optimistic: €2M → Need massive ROI to justify risk -- Realistic: €350K → Even 20x ROI (€7M exit) is great - -### 4. **Easier to Pivot** -- Optimistic: Built 5 solutions, now stuck -- Realistic: If #1 doesn't work, pivot to #2/#3 easily - -### 5. **Better Unit Economics** -- Optimistic: High burn, need high prices, harder to sell -- Realistic: Low burn, can afford to be more patient with sales - ---- - -## Timeline Comparison - -### Optimistic (5 Solutions) -``` -Month 1-4: Requirements, Design, Setup -Month 5-12: Parallel development (all 5) - - Web team (2) - - Mobile team (2) - - Backend team (2) - - KI/ML team (2) - - QA (1) - - PM (1) -Month 13: Beta launch with 2-3 solutions -Month 14-16: Piloting -Month 17: Commercial launch -Month 18+: Sales -``` -**Risk:** Any delay cascades to everything - -### Realistic (SmartMeter Only) -``` -Month 1-4: Interviews, Validation, GO/NO-GO -Month 5-10: MVP Development (3-4 Devs only) - - Frontend (React Native) - - Backend (Python) - - OCR Integration - - Security/Testing -Month 11: Beta with 5 pilots (free) -Month 12: Commercial launch -Month 13-18: Sales & first revenue -Month 19+: Expansion to #2, #3 -``` -**Advantage:** Each milestone is clear, achievable, deriskable - ---- - -## Key Metrics: When to Scale - -**Realistic Approach suggests:** - -Scale to Solution #2 when: -- ✅ 10+ paying customers for SmartMeter -- ✅ NPS > 50 -- ✅ Positive unit economics (LTV > 3x CAC) -- ✅ Monthly Churn < 3% -- ✅ ARR > €800K - -Only THEN invest in #2 + #3. - ---- - -## Worst Case: What If #1 Doesn't Work? - -### Optimistic Scenario -- €2M spent, 5 solutions built -- None of them acquired traction -- **Loss: €2M EUR** -- Runway: 1-2 months to shut down - -### Realistic Scenario -- €350K spent, SmartMeter built -- No traction after 4 months of sales -- Pivot to Abschlag (#2) or Outage (#3) -- **Loss: €350K EUR** (manageable) -- Runway: 15+ months to try new approaches - -**Clear winner:** Realistic scenario is 5x safer! - ---- - -## Best Case: What If #1 Works Great? - -### Optimistic Scenario -- 5 solutions built, SmartMeter works best -- Customers mostly use #1 -- Other 4 are "nice to have" -- **Wasted:** €1.2M on unnecessary features -- Result: €2M ARR is achievable, but expensive to get there - -### Realistic Scenario -- SmartMeter works great -- €500K spent, high profitability -- Runway to build #2, #3 with cash flow -- **Efficient:** Every EUR was well-spent ✅ -- Result: Scale organically from €500K → €1M → €2M+ - -**Clear winner:** Realistic scenario = more profitable! - ---- - -## Investment Attractiveness - -### For Seed/VC Investors - -| Kriterium | Optimistic | Realistic ✅ | -|-----------|-----------|-----------| -| **Capital Efficiency** | Low (€2M for MVP) | High (€350K) | -| **Risk Adjusted Return** | Medium | High | -| **Time to Profitability** | 18-20 months | 18-22 months (similar) | -| **Probability of Success** | Medium (40%) | High (65%) | -| **Exit Multiples** | 5-8x | 5-8x (same) | -| **Overall Attractiveness** | ❌ OK | ✅✅ GREAT | - -**Investor Perspective:** -- €350K with 65% success = Expected Value: €2.3M -- €2M with 40% success = Expected Value: €6.4M - -Actually, on paper Optimistic seems better. But in reality: -- €350K Realistic with 65% = More likely to win -- €2M Optimistic with 40% = More likely to fail spectacularly - -**Smart investors prefer:** Lower risk, capital-efficient bets. - ---- - -## The Decision Framework - -### Choose OPTIMISTIC if: -- ❌ You have €3-5M in funding already -- ❌ You have a killer sales team ready -- ❌ You have all 5 pain points validated with paying customers -- ❌ You want to be "one-stop-shop" -- **Reality:** Rare. Don't do this. - -### Choose REALISTIC if: -- ✅ You have €350-800K seed funding -- ✅ You have 1-2 good founders -- ✅ You want to validate before scaling -- ✅ You can't afford massive burn -- ✅ You want to maximize learning & optionality -- **Reality:** This is 90% of successful startups. - ---- - -## Recommended Path Forward - -**Phase 0: NOW (Next 2 weeks)** -1. Get clear GO/NO-GO from 5-10 Stadtwerk contacts -2. Validate that #1 (SmartMeter) is truly their #1 pain -3. If YES → Move to Phase 1 - -**Phase 1: VALIDATION (Month 1-4, €20-30K)** -- Deep-dive interviews (10-15 Stadtwerke) -- Competitive analysis -- Business model validation -- Feature prioritization - -**Phase 2: MVP BUILD (Month 5-10, €250-350K)** -- Build SmartMeter-App with extreme focus -- 3-4 amazing engineers -- 1 great product manager -- 1 talented designer -- Ship by Month 10 - -**Phase 3: MARKET TEST (Month 11-18, €50-100K)** -- 5 Beta customers (free, learning) -- Iterate based on feedback -- First paying customers Month 13-16 -- Measure product-market fit signals - -**Phase 4: EXPANSION (Month 19+, progressive)** -- Only if KPIs show strong momentum -- Then build #2, #3 -- Each builds on PMF from previous - ---- - -## Bottom Line - -**Optimistic:** "Build everything, hope it works" -**Realistic:** "Build one thing great, then expand" - -**Winner:** Realistic, because: -- ✅ Lower risk -- ✅ Better capital efficiency -- ✅ More focused product -- ✅ Easier to sell -- ✅ Easier to pivot -- ✅ Similar upside potential - -**Recommendation:** Go with Realistic MVP approach. It's smarter. - ---- - -**Status:** This document should guide all strategic decisions moving forward. -**Next Review:** After Phase 0 GO/NO-GO decision (Week 2) diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..f92b634 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,249 @@ +# InnungsApp — Entwicklungs-Roadmap + +> **Methodik:** Agile, 2-Wochen-Sprints | **Start:** März 2026 + +--- + +## Phase 0 — Setup & Foundation (Woche 1–2) + +**Ziel:** Fundament für schnelle Entwicklung legen + +### Woche 1: Technisches Setup +- [ ] Supabase-Projekt aufsetzen (Production + Staging) +- [ ] Datenbankschema deployen (alle Tabellen, Indizes) +- [ ] Row Level Security Policies schreiben und testen +- [ ] Supabase Auth konfigurieren (Magic Link, E-Mail-Templates) +- [ ] Expo-Projekt initialisieren (React Native + TypeScript) +- [ ] Expo Router Grundstruktur anlegen +- [ ] Next.js Admin-App initialisieren +- [ ] CI/CD: Gitea → Vercel (Admin) + EAS (Mobile) +- [ ] Environments: development / staging / production + +### Woche 2: Design & Pilot-Gespräch +- [ ] Design-Tokens definieren: Farben, Typography, Spacing, Radius +- [ ] Figma-Mockups: Login, Mitgliederverzeichnis, News Feed, Terminliste +- [ ] Erste Innung als Design-Partner ansprechen (Kaltakquise BW) +- [ ] Demo-Call vereinbaren für Woche 3 +- [ ] Supabase TypeScript-Types generieren + +**Deliverables:** +- Supabase-Projekt live (Staging) +- Expo App startet auf Simulator +- Figma-Mockups für alle MVP-Screens +- Demo-Call mit erster Innung geplant + +--- + +## Phase 1 — Core MVP (Woche 3–10) + +### Sprint 1 (Woche 3–4): Auth + Mitgliederverzeichnis + +**Mobile:** +- [ ] Login-Screen mit Magic Link (E-Mail-Eingabe) +- [ ] Verify-Screen (Token-Verarbeitung nach Link-Klick) +- [ ] Auth Guard (Redirect bei nicht eingeloggt) +- [ ] Mitgliederverzeichnis: Liste mit Suche +- [ ] Filter-Bottom-Sheet: Sparte, Ort, Ausbildungsbetrieb +- [ ] Mitglied-Detailansicht: alle Infos, Tap-to-Call, Tap-to-Mail + +**Admin:** +- [ ] Login-Page +- [ ] Mitgliederliste mit Tabelle und Suche +- [ ] Mitglied anlegen / bearbeiten (Formular) +- [ ] Mitglied deaktivieren + +**Backend:** +- [ ] RLS Policies für members testen +- [ ] CSV-Import Endpoint (Supabase Edge Function) +- [ ] Einladungs-E-Mail via Resend + +--- + +### Sprint 2 (Woche 5–6): News & Push Notifications + +**Mobile:** +- [ ] News Feed: Liste, Kategoriefilter, Ungelesen-Badge +- [ ] Beitrag-Detailansicht: Text, Anhänge (PDF-Viewer) +- [ ] Push-Token-Registrierung beim Login +- [ ] Gelesen-Tracking (mark as read on open) + +**Admin:** +- [ ] Beitrag erstellen: Rich-Text-Editor, Kategorie, PDF-Anhang +- [ ] Beitrag zeitgesteuert veröffentlichen +- [ ] Leserate-Anzeige pro Beitrag +- [ ] Beitrag anpinnen + +**Backend:** +- [ ] Supabase Database Webhook → Edge Function → Expo Push API +- [ ] news_reads Tracking +- [ ] Supabase Storage für PDF-Anhänge + +--- + +### Sprint 3 (Woche 7–8): Termine & Anmeldungen + +**Mobile:** +- [ ] Terminliste chronologisch +- [ ] Filter nach Typ (Prüfung, Kurs, etc.) +- [ ] Termin-Detailansicht +- [ ] An-/Abmeldebutton +- [ ] iCal-Export +- [ ] Bestätigungs-E-Mail nach Anmeldung + +**Admin:** +- [ ] Termin anlegen / bearbeiten +- [ ] Teilnehmerliste einsehen +- [ ] Teilnehmerliste CSV-Export + +**Backend:** +- [ ] termine_anmeldungen mit UNIQUE constraint +- [ ] E-Mail bei Anmeldung (Resend) +- [ ] Push Reminder 24h vorher (geplante Edge Function) + +--- + +### Sprint 4 (Woche 9–10): Lehrlingsbörse & Admin Dashboard + +**Mobile (öffentlich, kein Login):** +- [ ] Stellenliste: Suche, Filter (Sparte, Ort, Lehrjahr) +- [ ] Stellen-Detailansicht: alle Infos, Vergütung, Kontakt +- [ ] Direktkontakt: Tap-to-Call / Tap-to-Mail + +**Mobile (Mitglied mit Login):** +- [ ] Eigene Stelle anlegen (wenn ausbildungsbetrieb = true) +- [ ] Stelle aktivieren / pausieren / löschen + +**Admin:** +- [ ] Alle Stellen der Innung einsehen +- [ ] Stelle moderieren (ausblenden) + +**Admin Dashboard Home:** +- [ ] Übersichtszahlen: Mitglieder, aktive Nutzer (7 Tage), WAU +- [ ] Letzte 5 Beiträge mit Leserate +- [ ] Nächste 5 Termine mit Anmeldezahl +- [ ] Quick Actions: Mitglied einladen, Beitrag erstellen + +--- + +## Phase 2 — Polish & Launch (Woche 11–14) + +### Woche 11–12: Onboarding & UX + +- [ ] Onboarding-Wizard für neue Innungen (Admin-Setup: Name, Logo, Sparten) +- [ ] First-Use-Tutorial in der Mobile App (Overlay / Tooltips) +- [ ] Leeransicht für leere Listen (Mitglieder, News, Termine) +- [ ] Error States und Retry-Logik +- [ ] Offline-Handling (Cached Data anzeigen) +- [ ] App Icon + Splash Screen +- [ ] Push Notification Permission-Prompt (optimierter Zeitpunkt) + +### Woche 13–14: App Store Submission & Pilot Launch + +- [ ] iOS: App Store Connect, Screenshots, App-Beschreibung +- [ ] Android: Google Play Console, Screenshots +- [ ] EAS Submit für beide Stores +- [ ] TestFlight Beta mit Pilot-Innung +- [ ] 5 Pilotinnungen live schalten +- [ ] PostHog Events in alle kritischen Flows einbauen +- [ ] Feedback-Formular in der App (NPS-Umfrage nach 2 Wochen) +- [ ] Support-Prozess definieren (E-Mail + FAQ-Seite) + +**Launch-Kriterien:** +- [ ] Alle 5 MVP-Module funktionieren ohne kritische Bugs +- [ ] Push Notifications ankommen +- [ ] Login-Flow < 60 Sekunden +- [ ] Keine DSGVO-Lücken +- [ ] 1 Pilot-Innung hat App bestätigt + +--- + +## Phase 3 — Post-MVP Q2 2026 + +### Modul: Dokumentenarchiv + +- [ ] Kategorien: Formulare, Satzungen, Prüfungsunterlagen, Protokolle +- [ ] Upload (PDF, Word, Excel) via Admin +- [ ] Download in Mobile App +- [ ] Versionsverwaltung (letzte 3 Versionen behalten) +- [ ] Suche über Dokumententitel + +### Modul: Statistik-Dashboard (Admin) + +- [ ] DAU / WAU / MAU Grafiken (letzte 90 Tage) +- [ ] Aktivierungsrate: Eingeladene vs. Eingeloggte +- [ ] News-Performance: Top 10 meistgelesene Beiträge +- [ ] Termin-Auslastung: Anmeldequote pro Termin +- [ ] Lehrstellenaktivität: Views, Kontaktanfragen +- [ ] Monatsbericht als PDF-Export + +### Modul: Videokonferenz-Integration + +- [ ] Zoom / Teams-Link in Terminen hinterlegen +- [ ] "Jetzt beitreten"-Button in Termin-Detailansicht +- [ ] Erinnerung mit Link in Push Notification + +--- + +## Phase 4 — Post-MVP Q3 2026 + +### Modul: Azubi Video-Feed (Kernstück Azubi-Modul) + +- [ ] TikTok-Style vertikaler Video-Feed pro Beruf +- [ ] Video-Upload für Mitgliedsbetriebe (Mux-Integration) +- [ ] Berufs-Tags und Filter +- [ ] Like / Speichern +- [ ] "Mehr erfahren" → Direktkontakt zum Betrieb + +### Modul: 1-Click-Bewerbung + +- [ ] Bewerber-Profil anlegen (Name, Schulabschluss, Interessen, Wohnort) +- [ ] "Bewerben" Button bei Lehrstellenanzeige +- [ ] Chat-Initiierung: Bewerber ↔ Betrieb (In-App Messaging) +- [ ] Benachrichtigung an Betrieb + +### Modul: Digitales Berichtsheft (Azubis) + +- [ ] Täglicher Eintrag: Text, Foto, Sprachnotiz +- [ ] Wochenansicht +- [ ] Betrieb kann Einträge bestätigen / kommentieren +- [ ] Export als PDF (für Prüfer) + +--- + +## Phase 5 — Post-MVP Q4 2026 + +### Modul: Prüfungsvorbereitung + +- [ ] Fragenkatalog pro Gewerk (manuell gepflegt) +- [ ] Tägliches Quiz (5 Fragen, Push-Reminder) +- [ ] Lernfortschritt-Tracking +- [ ] Schwächen-Analyse: "Diese Themen solltest du wiederholen" + +### White-Label für HWK + +- [ ] Eigene Domain pro Innung: `innung-elektro-stuttgart.de` +- [ ] Vollständige Logo/Farb-Anpassung +- [ ] HWK-Dashboard: Alle Innungen im Bezirk auf einen Blick +- [ ] HWK kann Nachrichten an alle Innungen senden + +### Verbands-API + +- [ ] REST API für externe Systeme (HWK-eigene Software) +- [ ] Webhook-Integration (neue Mitglieder, neue Stellen) +- [ ] Dokumentierte API (OpenAPI/Swagger) + +--- + +## Meilensteine & KPIs + +| Meilenstein | Datum | KPI | +|---|---|---| +| Supabase + Expo Setup | KW 10/2026 | Technisches Fundament bereit | +| Erster Pilot live | KW 15/2026 | 1 Innung aktiv | +| App Store Launch | KW 16/2026 | iOS + Android verfügbar | +| 5 Piloten aktiv | KW 20/2026 | WAU > 40%, NPS > 50 | +| Erster zahlender Kunde | KW 22/2026 | MRR > 0 € | +| 10 zahlende Innungen | KW 32/2026 | MRR > 1.500 € | +| Erste HWK-Partnerschaft | KW 40/2026 | Distributionskanal validiert | +| 50 Innungen | KW 10/2027 | MRR > 8.500 €, Profitabilität | +| 100 Innungen | KW 26/2027 | MRR > 18.000 €, Seed-Bereit | diff --git a/SmartMeter_PRD.md b/SmartMeter_PRD.md deleted file mode 100644 index fbebd6c..0000000 --- a/SmartMeter_PRD.md +++ /dev/null @@ -1,1262 +0,0 @@ -# PRD: SmartMeter-Lite App -## Product Requirements Document - MVP Version - -**Version:** 1.0 -**Datum:** Februar 2026 -**Status:** Final für Development -**Owner:** [PM Name] -**Stakeholder:** Stadtwerke, Endkunden, Support-Teams - ---- - -## 1. EXECUTIVE SUMMARY - -### Vision -Digitalisierung der Zählerablesung für deutsche Stadtwerke durch eine einfache, mobile App. Ziel: Manuelle Ablesungsprozesse automatisieren, Fehlerquote von 30-40% auf <5% reduzieren, und Support-Anfragen zu Abrechnungsfehlern um 70% senken. - -### Problem Statement -Stadtwerke basieren aktuell auf **manueller, fehlerhafter Zählerablesung**: -- 📊 **30-40% Fehlerquote** bei manuellen Eingaben -- 📞 **50+ Anrufe/Woche** zu Abrechnungskorrektionen -- 💰 **5-10 Millionen EUR/Jahr** Verarbeitungskosten -- 😞 **Customer Dissatisfaction:** 45% Unzufriedenheit mit Abrechnungsprozess - -### Solution -**SmartMeter-Lite:** Eine mobile App, die es Kunden erlaubt, ihren Stromzähler zu fotografieren. OCR-Technologie liest automatisch die Zahl aus, validiert sie, und sendet sie direkt an die Stadtwerk-Abrechnungssysteme. - -### Expected Outcomes (Year 1) -- ✅ **<5% Fehlerquote** (vs. 30-40% aktuell) -- ✅ **70% weniger Support-Anfragen** zu Abrechnungen -- ✅ **40% Cost Savings** im Ablese-Prozess -- ✅ **80% Kundenakzeptanz** nach 6 Monaten -- ✅ **+50 NPS** Verbesserung - -### Market Opportunity -- **TAM:** 900+ Stadtwerke in Deutschland -- **SAM:** Top 100 Stadtwerke (60% Markt) -- **SOM Year 1:** 10-15 Stadtwerke = **€800k - 1.2M ARR** -- **SOM Year 2:** 30-40 Stadtwerke = **€2.4M - 4.8M ARR** - -### Business Model -**B2B SaaS:** -- **Small Stadtwerke:** €1.000 - €3.000/Monat -- **Medium Stadtwerke:** €3.000 - €8.000/Monat -- **Large Stadtwerke:** €8.000 - €20.000/Monat -- **Per-Scan Pricing (optional):** €0.05 - €0.15 pro Ablesung - ---- - -## 2. USER PERSONAS - -### Persona 1: Anna Müller (B2C - Endkundin) -**Alter:** 42 -**Job:** IT-Projektmanagerin -**Tech-Affinity:** Hoch - -**Probleme:** -- Vergisst regelmäßig Zählerablesung (Deadline jeweils 15. des Monats) -- Hatte schon 2x Abrechnungskorrektionen (Stress, Telefonieren) -- Wünscht sich digitale Lösung - -**Needs:** -- ✅ Einfach Foto machen, fertig -- ✅ Bestätigung, dass Ablesung ankam -- ✅ Keine technischen Fehler -- ✅ Ablauf in <2 Minuten - -**Motivation für Nutzung:** -- Zeitersparnis (10 Min Telefonat vermeiden) -- Sicherheit (Beweis, dass korrekt abgelesen) -- Convenience (von zuhause, am Wochenende) - ---- - -### Persona 2: Klaus Schmidt (B2B - Stadtwerk IT-Manager) -**Alter:** 55 -**Job:** IT-Leiter bei großer Stadtwerk (100k+ Kunden) -**Tech-Affinity:** Mittel - -**Probleme:** -- Support-Team bekommt täglich 50-100 Anfragen zu Abrechnungen -- Manuelle Ablesungen führen zu Datenfehlern in SAP-System -- Keine Digitalisierung im Ablese-Prozess - -**Needs:** -- ✅ Integration mit SAP/Oracle Abrechnungssystem -- ✅ Admin-Dashboard zur Überwachung -- ✅ Fehlerbehandlung (was wenn OCR falsch liest?) -- ✅ Datenqualitäts-Reports -- ✅ DSGVO Compliance - -**Motivation für Nutzung:** -- ROI in <18 Monaten -- Weniger Support-Tickets -- Bessere Datenqualität -- Wettbewerbsfähigkeit - ---- - -### Persona 3: Hans Schneider (B2B - Kundenservice Manager) -**Alter:** 38 -**Job:** Head of Customer Service bei Medium Stadtwerk (50k Kunden) -**Tech-Affinity:** Mittel-niedrig - -**Probleme:** -- Team muss täglich 100+ falsche Ablesungen korrigieren -- Customer Satisfaction score: 3.2/5 (zu niedrig) -- Keine Automatisierung möglich mit aktuellen Prozessen - -**Needs:** -- ✅ Einfach zu bedienende Software (nur Clicks, kein Coding) -- ✅ Klare Reports (wie viele Ablesungen/Woche?) -- ✅ Training für Support-Team -- ✅ Schneller Kundenservice (FAQ, Video-Tutorials) - -**Motivation für Nutzung:** -- Team-Entlastung -- Bessere Customer Satisfaction -- Kostenersparnis (weniger Korrektionen) -- Moderne Arbeitsprozesse - ---- - -## 3. USE CASES - -### Use Case 1: Normale Ablesung (Happy Path) - -**Akteur:** Anna Müller (Endkundin) -**Trigger:** Abrechnungs-Deadline erreicht (15. des Monats) - -**Ablauf:** -``` -1. Anna öffnet SmartMeter App auf ihrem Smartphone -2. Sie wählt "Neue Ablesung" -3. App öffnet Kamera, zeigt "Frame Guide" (Zähler-Umriss) -4. Anna fotografiert ihren Stromzähler (sechs Ziffern sichtbar) -5. App zeigt OCR-Ergebnis: "128456" mit 96% Confidence -6. Anna bestätigt oder korrigiert die Zahl -7. App speichert die Ablesung, zeigt "✅ Erfolgreich gesendet" -8. Ablesung wird in Echzeit an Stadtwerk-Backend übertragen -9. Stadtwerk bestätigt Receipt per SMS/E-Mail -``` - -**Erwartetes Ergebnis:** -- ✅ Ablesung korrekt im Stadtwerk-System -- ✅ Anna erhält Bestätigung -- ✅ Keine manuelle Bearbeitung nötig -- ✅ Keine Support-Anfrage - ---- - -### Use Case 2: OCR-Fehler (Alternate Path) - -**Akteur:** Klaus Mueller (Endkunde mit älterem Zähler) -**Trigger:** Zähler ist dunkel, schlecht lesbar - -**Ablauf:** -``` -1. Klaus fotografiert seinen alten, schmuddeligen Zähler -2. OCR liest: "12345X" (X statt 6, 60% Confidence - LOW) -3. App zeigt Warning: "Unsicher. Bitte überprüfen oder neu fotografieren" -4. Klaus sieht das rote Warning-Symbol -5. Er fotografiert nochmal, besser fokussiert -6. Dieses Mal: "123456" mit 98% Confidence -7. Klaus bestätigt -8. App speichert, zeigt: "✅ Erfolgreich gesendet" -``` - -**Erwartetes Ergebnis:** -- ✅ Fehler werden NICHT ans Backend gesendet -- ✅ User wird informiert und kann korrigieren -- ✅ Keine falschen Daten im System - ---- - -### Use Case 3: Admin Dashboard (B2B) - -**Akteur:** Klaus Schmidt (Stadtwerk IT-Manager) -**Trigger:** Morgens zur Arbeit, checkt Status - -**Ablauf:** -``` -1. Klaus loggt sich ins Admin Dashboard ein -2. Er sieht Übersicht: - - 847 Ablesungen diese Woche - - 834 erfolgreich (98.5%) - - 13 fehlgeschlagen (1.5%) - mit Reasons - - Average Confidence Score: 96.2% -3. Er klickt auf "Failed Ablesungen" -4. Er sieht: 8 × "Low Quality Photo", 5 × "Invalid Format" -5. Er exported den Report als CSV für SAP -6. Er sieht Alert: "3 Customers haben >3 Fehlerversuche" -7. Er klickt auf die Kunden → sieht ihre Fehlerbilder -8. Er sendet Kunden eine Email: "Bitte wie folgt fotografieren..." -``` - -**Erwartetes Ergebnis:** -- ✅ Klaus sieht Qualitätsmetriken in Echtzeit -- ✅ Fehler werden identifiziert, bevor sie zu Problems werden -- ✅ Pro-aktive Kundenunterstützung möglich - ---- - -### Use Case 4: Integration mit SAP (B2B Backend) - -**Akteur:** SAP-System der Stadtwerk -**Trigger:** Ablesung wird in SmartMeter-App bestätigt - -**Ablauf:** -``` -1. User submitted Ablesung in App -2. SmartMeter Backend validates: - - Format korrekt? ✅ - - Plausibility Check? (Z.B. nicht 50% mehr als letzte Ablesung) - - Duplicate Check? (Wurde heute schon abgelesen?) -3. SmartMeter sendet REST API Call zu Stadtwerk SAP: - POST /api/readings - { - "customer_id": "SW12345", - "reading": 128456, - "timestamp": "2026-02-17T14:32:00Z", - "confidence": 0.96, - "photo_hash": "abc123def456" - } -4. SAP antwortet: {"status": "success", "reading_id": "RD987654"} -5. SmartMeter speichert Reading ID lokal -6. App zeigt Kunde: "✅ Ablesung erfolgreich übertragen" -7. SAP triggert automatische Rechnungsberechnung -8. Keine manuelle Bearbeitung nötig -``` - -**Erwartetes Ergebnis:** -- ✅ Daten sind in Echtzeit im SAP-System -- ✅ Rechnungsprozess startet sofort -- ✅ Keine Verzögerungen durch manuelle Prozesse - ---- - -## 4. FEATURES - MVP (PHASE 1) - -### 4.1 Mobile App Features (iOS + Android) - -#### Feature 1.1: Authentication & Onboarding -**Priority:** CRITICAL -**Effort:** M (Medium) - -``` -- Sign Up: Email/Passwort oder SMS OTP -- Login: Standard Email/Passwort -- "Kundendaten Import": Stadtwerk importiert Kundenlisten - → App kann automatisch Kunden-ID vorausfüllen -- 2FA (optional): SMS-Bestätigung -- Biometric: Fingerprint / Face ID support -- Session Management: Auto-logout nach 15 Min Inaktivität -``` - -**Success Criteria:** -- ✅ Sign-Up in <2 Minuten -- ✅ 95%+ erfolgreiche Logins -- ✅ <30 Sekunden Login-Zeit - ---- - -#### Feature 1.2: Camera & Photo Capture -**Priority:** CRITICAL -**Effort:** M-L - -``` -- Live Camera Preview mit Frame Guide - → Zeigt Umriss des Zählers als Overlay - → Hilft User, korrekt zu fotografieren - → "Zähler muss in diesem Rahmen sein" - -- Auto-Capture Option: - → App fotografiert automatisch, wenn Zähler erkannt - → Oder manueller Knopf "Foto machen" - -- Flash Control: - → Auto-Flash für dunkle Umgebungen - → Manual Flash Adjustment möglich - -- Photo Quality Check: - → Vor Upload: Ist Foto scharf genug? - → Ist Zähler vollständig sichtbar? - → Wenn nicht: "Bitte besseres Foto machen" - -- Multiple Captures: - → User kann 3-5 Fotos machen, beste wählen - → App zeigt auto-selected bestes Foto -``` - -**Success Criteria:** -- ✅ >95% Fotos sind verwertbar -- ✅ <5% müssen erneut fotografiert werden -- ✅ Average Photo Quality Score: >90/100 - ---- - -#### Feature 1.3: OCR & Digit Recognition -**Priority:** CRITICAL -**Effort:** L (Large) - -``` -TECHNOLOGY OPTION A: Google Vision API (Recommended) -- Best Accuracy (97%+) -- Schnell (500ms) -- Kostet ca. €0.01 pro Request -- Einfache Integration via REST API - -TECHNOLOGY OPTION B: Tesseract (Open Source) -- Kostenlos -- 85-90% Accuracy -- Langsamer (2-3s) -- Braucht Local Processing - -TECHNOLOGY OPTION C: TensorFlow Lite Model (Custom) -- Medium Accuracy (88-92%) -- Schnell (300ms) -- Offline möglich -- Braucht Training Data (100+ Meter Fotos) - -RECOMMENDATION: Option A (Google Vision) für MVP -Later: Option C für Kosteneinsparungen - -FEATURES: -- Automatic OCR nach Foto-Upload -- Confidence Score anzeigen (Z.B. "96% sicher") -- Zeige alternatives interpretations wenn <90% Confidence - Z.B.: "Könnte auch sein: 128455 (87%)" -- Digit-by-Digit Verification möglich -- Auto-correct häufige Fehler: - → "O" als "0" erkennen - → "l" als "1" erkennen -``` - -**Success Criteria:** -- ✅ >95% OCR Accuracy -- ✅ <1s OCR Response Time -- ✅ <0.5% False Positives - ---- - -#### Feature 1.4: Manual Verification & Correction -**Priority:** CRITICAL -**Effort:** S (Small) - -``` -- Nach OCR: Zeige große, klare Digits zum Verifizieren -- User kann nach oben/unten swipen um Digit zu ändern - Z.B.: "1" → swipen-oben → "2" → swipen-unten → "1" - ODER: Tippen auf jede Ziffer → Numpad poppen up - -- Confirmation Screen: - "Bitte bestätigen Sie die Ablesung:" - [Großes Display: 123456] - [Button: ✅ Bestätigt] [Button: ❌ Neu fotografieren] - -- Fehlertoleranz: - Wenn User versucht "999999" einzugeben: - → "Warnung: Dieses ist um 800% höher als letzte Ablesung" - → "Bitte überprüfen oder Foto neu machen" -``` - -**Success Criteria:** -- ✅ >99% der Ablesungen sind korrekt nach Verification -- ✅ <5% Ablesungen müssen korrigiert werden - ---- - -#### Feature 1.5: Submission & Confirmation -**Priority:** CRITICAL -**Effort:** M - -``` -- Upload Status: - Zeige Progress Bar während Upload - "Sende Ablesung... 45%" - -- Offline Support: - Wenn kein Internet: Queue die Ablesung lokal - "Wird bei nächster Verbindung hochgeladen" - -- Success Confirmation: - "✅ Ablesung erfolgreich eingereicht!" - "Bestätigungs-ID: RD987654" - "Nächste Ablesung fällig: 15. März 2026" - -- Notification: - Push Notification: "Ablesung akzeptiert" - Email: Ablesung + Bestätigungs-ID - SMS (optional): "Ablesung erhalten" - -- History: - Alle bisherigen Ablesungen anzeigen: - "15. Feb 2026: 128456 ✅" - "15. Jan 2026: 127812 ✅" - Mit Links zu PDFs/Fotos -``` - -**Success Criteria:** -- ✅ >99% Uptime während Submission -- ✅ <2s Submission Response Time -- ✅ >95% Confirmations kommen an - ---- - -#### Feature 1.6: User Dashboard -**Priority:** HIGH -**Effort:** M - -``` -- Home Screen: - "Aktuelle Ablesung: 128456 (15. Feb 2026)" - "Nächste Ablesung fällig: 15. März 2026" (5 Tage) - [Big Button: "Jetzt Ablesen"] - -- History Tab: - Liste aller Ablesungen: - "15. Feb 2026 - 128456 ✅" - "15. Jan 2026 - 127812 ✅" - Mit: Foto, Zeitstempel, Status - -- Alerts Tab: - "Warnung: Ablesung 3 Tage überfällig!" - "Info: Neue Version verfügbar" - -- Settings Tab: - - Notifications (push, email, SMS) - - Sprache (Deutsch, Englisch) - - Account Management (Profil, Passwort) - - About & Help - - Logout - -- Help & FAQ: - "Wie fotografiere ich richtig?" - → Video Tutorial (30s) - "Mein Foto wird nicht erkannt" - → Troubleshooting Guide - "Wann ist die nächste Ablesung fällig?" - → FAQ -``` - -**Success Criteria:** -- ✅ >80% Users nutzen App min. 1x/Monat -- ✅ <3 Taps um Ablesung zu machen -- ✅ NPS >50 - ---- - -### 4.2 Admin Dashboard Features (Web - Für Stadtwerke) - -#### Feature 2.1: Authentication & Authorization -**Priority:** CRITICAL -**Effort:** S - -``` -- Login: Email/Passwort (Standard) -- 2FA: Mandatory für Admin Accounts -- Role-Based Access Control: - - Super Admin: Full Access - - Manager: Reports, Alerts, antwort auf Fehler - - Analyst: Read-Only - - Support: Kundensuche, Fehlerbehandlung - -- Session Management: - Auto-logout nach 30 Min Inaktivität (Enterprise Standard) -``` - ---- - -#### Feature 2.2: Real-Time Dashboard -**Priority:** CRITICAL -**Effort:** L - -``` -MAIN DASHBOARD WIDGETS: - -1. Today's Metrics: - - "847 Ablesungen heute" - - "823 erfolgreich (97.2%)" - - "24 fehlgeschlagen (2.8%)" - - "96.1% Average Confidence" - -2. Trend Chart (7-Day): - - Liniendiagramm: Ablesungen pro Tag - - Durchschnittliche Erfolgsrate - - Average Confidence über Zeit - -3. Top Issues (This Week): - - "13 × Zähler nicht lesbar (Low light)" - - "8 × Ungültige Format" - - "7 × User Error (falsche Zahl eingegeben)" - -4. Recent Submissions: - Live Feed: - "14:32 - Kunde XYZ - 128456 ✅" - "14:28 - Kunde ABC - 127812 ✅" - "14:25 - Kunde DEF - Error (Low confidence 41%) ❌" - -5. Alerts & Notifications: - - "3 Customers haben >3 Fehlerversuche" - - "System Response Time >2s" (Performance Alert) - - "Neue App Version verfügbar" - -REFRESH RATE: Real-time (WebSocket connection) -``` - -**Success Criteria:** -- ✅ Dashboard loads in <2s -- ✅ Real-time updates <500ms delay -- ✅ 99.9% uptime - ---- - -#### Feature 2.3: Detailed Analytics & Reports -**Priority:** HIGH -**Effort:** M - -``` -REPORT TYPES: - -1. Daily Summary Report: - - Datum - - Total Submissions - - Erfolgsrate (%) - - Avg Confidence Score - - Errors by Category - - Cost Calculation (EUR saved vs. manual) - -2. Customer-Level Report: - - Filter by: Alter, Region, Stadtwerke - - Details: - * Anzahl Ablesungen - * Success Rate - * Average Confidence - * Last Reading (Date + Value) - - Download: CSV, PDF - -3. Error Analysis Report: - - Fehlertypen: - * Low Quality Photo (%) - * Invalid Format (%) - * OCR Failure (%) - * User Error (%) - - Time Series: Fehler über Zeit - -4. Performance Report: - - Response Time (average, min, max) - - Uptime (%) - - API Availability - - Subscription Usage - -5. Compliance Report (DSGVO): - - Data Processing Log - - Audit Trail - - User Activity Log - -EXPORT OPTIONS: CSV, PDF, Excel, Email -SCHEDULING: Daily, Weekly, Monthly Reports -``` - -**Success Criteria:** -- ✅ Reports generieren in <10s -- ✅ >90% Accuracy of reported numbers - ---- - -#### Feature 2.4: Customer Management -**Priority:** HIGH -**Effort:** M - -``` -- Customer Search: - Suche by: Name, Customer ID, Email, Telefon - -- Customer Details: - - Name, Adresse, Kontakt - - Current Reading + History - - Success Rate - - Errors (Foto + Reason) - - Contact History - -- Bulk Import: - Upload CSV: - customer_id, name, email, phone, address - → System importiert und sendet Invitation - -- Customer Deactivation: - Kunde kann sich abmelden - Admin kann deactivieren (Z.B. umgezogen) - -- Resend Invitation: - Falls Kunde App nicht installiert hat - → Admin kann Invitation Email/SMS erneut senden -``` - ---- - -#### Feature 2.5: Error Management & Troubleshooting -**Priority:** CRITICAL -**Effort:** M - -``` -- Failed Submissions Detailed View: - Click on Error → Zeige: - - Foto (Thumbnail + Full View) - - OCR Result + Confidence Score - - User's Correction (falls vorhanden) - - Error Category: [Low Quality] [Invalid] [OCR Error] - - Customer Contact Info - -- Automated Responses: - Admin kann automatische Messages schreiben: - "Lieber Kunde, Ihr Zähler war nicht lesbar" - "Bitte fotografieren Sie wie folgt:" - [Link zu Video Tutorial] - -- Manual Intervention: - Admin kann: - - Reading manuell akzeptieren (mit Notiz) - - Reading ablehnen + Kunde kontaktieren - - Foto im System ersetzten - -- Error Categories: - Auto-Tagging nach AI (später): - - "Low Light" (60% Confidence) - - "Angle Wrong" (Invalid Format) - - "Meter Dirty" (Low Quality) - - "User Typo" (Plausibility Check Failed) -``` - -**Success Criteria:** -- ✅ Errors werden in <1h erkannt und handelt -- ✅ Support kann Fehler in <2 Min beheben - ---- - -#### Feature 2.6: User Management & Permissions -**Priority:** HIGH -**Effort:** S - -``` -- Add/Remove/Edit Users: - - Email - - Role: [Super Admin] [Manager] [Analyst] [Support] - - Permissions by Role - - Activation/Deactivation - -- Audit Log: - Wer hat was wann gemacht: - "Admin XYZ hat User ABC gelöscht (17.02.2026 14:23)" - "Manager DEF hat Reading manuell akzeptiert (RD987654)" - -- Activity Report: - - Logins (Zeit, IP) - - Actions (What, When, Who) - - Data Export -``` - ---- - -#### Feature 2.7: Integration & API -**Priority:** CRITICAL -**Effort:** L - -``` -API INTEGRATION with Stadtwerk's SAP/ERP: - -1. REST API Endpoints: - POST /api/v1/readings - Submit reading - GET /api/v1/readings/{id} - Get reading details - GET /api/v1/customers/{id} - Get customer info - GET /api/v1/reports/daily - Daily report data - -2. Authentication: - OAuth 2.0 Token-based - API Keys for System-to-System - -3. Data Format: - { - "customer_id": "SW12345", - "reading": 128456, - "timestamp": "2026-02-17T14:32:00Z", - "confidence": 0.96, - "photo_hash": "abc123def456" - } - -4. Callback Webhooks: - Stadtwerk kann subscribe zu: - - new_reading_submitted - - reading_failed - - customer_error - - Wir senden: POST to /webhook/readings - -5. Rate Limiting: - - 10,000 requests/hour (default) - - Higher tiers: 50,000 /hour - -6. Documentation: - Full Swagger/OpenAPI docs - Code Examples (Python, Node.js, Java) -``` - ---- - -## 5. TECH STACK - MVP - -### 5.1 Mobile App (iOS + Android) - -``` -Framework: React Native / Flutter -Language: TypeScript / Dart -State Management: Redux Toolkit / Provider -API Client: Axios / http -Camera: react-native-camera / Camera2 -OCR Integration: Google Vision API SDK -Storage: AsyncStorage / Realm DB (local caching) -UI Library: React Native Paper / Material 3 -Push Notifications: Firebase Cloud Messaging -Testing: Jest + Detox (E2E) -CI/CD: GitHub Actions / EAS Build -``` - -### 5.2 Backend (API Server) - -``` -Language: Node.js + TypeScript (Recommended) -Framework: Express.js / Fastify -Database: PostgreSQL 13+ -Cache: Redis (Session Cache, Rate Limiting) -Storage: AWS S3 / Azure Blob (for photos) -Authentication: JWT + OAuth2 -API Gateway: Kong / AWS API Gateway -Message Queue: RabbitMQ (for async processing) -Logging: Winston / Pino -Monitoring: Prometheus + Grafana -Testing: Jest + Supertest -``` - -### 5.3 OCR Service - -``` -Primary: Google Vision API (REST-based) -Fallback: Tesseract.js (Web-based) -Alternative: TensorFlow Lite (Custom Model) - -OCR Confidence Threshold: -- >90%: Accept automatically -- 70-90%: Show to user for confirmation -- <70%: Reject + ask for new photo -``` - -### 5.4 Admin Dashboard - -``` -Frontend: React 18+ -Language: TypeScript -UI Library: Material-UI / TailwindCSS -Charts: Recharts / Chart.js -State Management: Redux Toolkit / TanStack Query -Testing: Jest + React Testing Library -Build: Vite / Create React App -Deployment: Vercel / Netlify -``` - -### 5.5 Infrastructure - -``` -Cloud Provider: AWS (or Azure/GCP) -Containerization: Docker -Orchestration: Kubernetes (EKS) / or Lambda -Database Hosting: RDS PostgreSQL -File Storage: S3 -CDN: CloudFront -Monitoring: CloudWatch / DataDog -Security: WAF, SSL/TLS, VPC -``` - ---- - -## 6. DATA MODELS - -### 6.1 Customer - -```json -{ - "id": "uuid", - "customerNumber": "SW123456", - "email": "anna@example.com", - "phone": "+49123456789", - "firstName": "Anna", - "lastName": "Müller", - "address": "Beispielstr. 42, 69120 Heidelberg", - "postalCode": "69120", - "city": "Heidelberg", - "stadtwerkeId": "uuid", - "createdAt": "2026-01-15T10:30:00Z", - "updatedAt": "2026-02-17T14:22:00Z", - "status": "active" | "inactive" | "deleted" -} -``` - -### 6.2 Meter - -```json -{ - "id": "uuid", - "customerId": "uuid", - "meterNumber": "MTR987654", - "meterType": "electricity" | "gas" | "water", - "manufacturer": "Siemens", - "installDate": "2020-06-01", - "location": "Wohnzimmer", - "readingInterval": "monthly" | "quarterly", - "nextReadingDue": "2026-03-15", - "currentReading": 128456, - "lastReading": 127812, - "lastReadingDate": "2026-02-15T14:32:00Z", - "createdAt": "2020-06-01T00:00:00Z" -} -``` - -### 6.3 Reading (Ablesung) - -```json -{ - "id": "uuid", - "readingNumber": "RD987654", - "customerId": "uuid", - "meterId": "uuid", - "submittedValue": 128456, - "ocrResult": "128456", - "ocrConfidence": 0.96, - "manualCorrection": null, - "photoUrl": "s3://bucket/photos/RD987654.jpg", - "photoHash": "abc123def456", - "status": "success" | "pending_review" | "rejected" | "manual_approved", - "validationStatus": "valid" | "invalid" | "plausibility_warning", - "validationErrors": [], - "previousReading": 127812, - "previousReadingDate": "2026-02-15T00:00:00Z", - "submittedAt": "2026-02-17T14:32:00Z", - "processedAt": "2026-02-17T14:32:05Z", - "sentToSAPAt": null, - "sapReadingId": null, - "staffNotes": null -} -``` - -### 6.4 Error Log - -```json -{ - "id": "uuid", - "readingId": "uuid", - "customerId": "uuid", - "errorType": "low_confidence" | "invalid_format" | "plausibility_check" | "system_error", - "errorMessage": "OCR Confidence 41% below threshold 70%", - "severity": "info" | "warning" | "error", - "resolution": "ask_for_new_photo" | "manual_review" | "accepted_with_warning", - "resolvedAt": "2026-02-17T14:35:00Z", - "createdAt": "2026-02-17T14:32:10Z" -} -``` - ---- - -## 7. API SPECIFICATIONS - -### 7.1 Mobile App → Backend - -#### Endpoint: POST /api/v1/readings/submit - -**Request:** -```json -{ - "customerId": "uuid", - "meterId": "uuid", - "photoUrl": "data:image/jpeg;base64,...", - "submittedValue": 128456, - "latitude": 49.1234, - "longitude": 8.5678, - "appVersion": "1.0.5", - "timestamp": "2026-02-17T14:32:00Z" -} -``` - -**Response (Success):** -```json -{ - "status": "success", - "readingId": "RD987654", - "message": "Ablesung erfolgreich eingereicht", - "nextReadingDue": "2026-03-15", - "confirmation": { - "email": true, - "sms": true - } -} -``` - -**Response (Error):** -```json -{ - "status": "error", - "readingId": "RD987654", - "message": "OCR Confidence zu niedrig (41%)", - "suggestion": "Bitte neu fotografieren", - "suggestions": [ - { - "value": 123456, - "confidence": 0.67 - }, - { - "value": 128456, - "confidence": 0.41 - } - ] -} -``` - -#### Endpoint: GET /api/v1/readings/history - -**Request:** -```json -{ - "customerId": "uuid", - "limit": 10, - "offset": 0 -} -``` - -**Response:** -```json -{ - "readings": [ - { - "id": "RD987654", - "value": 128456, - "date": "2026-02-15", - "status": "success", - "photoUrl": "https://..." - } - ], - "total": 24, - "hasMore": true -} -``` - -### 7.2 Backend → Stadtwerk SAP - -#### Endpoint: POST /api/v1/readings/sync-to-sap - -**Internal Queue Job:** -```json -{ - "readingId": "uuid", - "customerId": "SW123456", - "meterNumber": "MTR987654", - "readingValue": 128456, - "readingDate": "2026-02-15", - "ocrConfidence": 0.96, - "source": "smartmeter_app" -} -``` - -**SAP Response:** -```json -{ - "status": "success", - "sapReadingId": "SAP-RD-2026-0987654", - "invoiceGenerated": true, - "invoiceNumber": "INV-2026-123456" -} -``` - ---- - -## 8. SECURITY & COMPLIANCE - -### 8.1 DSGVO (GDPR) Compliance - -``` -✅ Privacy by Design: - - Minimize data collection - - Only collect: Name, Email, Phone, Address - - NO unnecessary tracking - -✅ Data Retention: - - Photos: Delete after 90 days - - Readings: Keep 7 years (legal requirement) - - Logs: Delete after 30 days - -✅ User Rights: - - Right to Export: Full data download as PDF/CSV - - Right to Delete: GDPR-compliant deletion workflow - - Right to Rectification: Edit own data - -✅ Consent Management: - - Explicit opt-in for marketing emails - - Easy opt-out button - - Consent logging in DB - -✅ Third-Party Processors: - - Google Vision API: DPA signed - - AWS: DPA signed - - List all Subprocessors on website -``` - -### 8.2 Data Security - -``` -✅ Encryption: - - TLS 1.3 for all data in transit - - AES-256 for data at rest (S3) - - Database encryption enabled - -✅ Authentication: - - Passwords: bcrypt (12 rounds) - - Sessions: JWT with 24h expiry - - Admin: Require 2FA (TOTP) - - Biometric: Support Touch/Face ID - -✅ API Security: - - Rate Limiting: 1000 req/min per IP - - CORS: Whitelist origin domains - - Input Validation: Sanitize all inputs - - SQL Injection Prevention: Use Parameterized Queries - -✅ Photo Security: - - Photos stored in S3 with ACL - - Signed URLs expire after 24h - - Photos never logged to any logs - - Hash comparison for integrity -``` - -### 8.3 Penetration Testing & Audits - -``` -- Security Audit: Monthly (Internal) -- Penetration Testing: Quarterly (External) -- Bug Bounty Program: Available -- Vulnerability Disclosure: responsible-disclosure@smartmeter.app -``` - ---- - -## 9. SUCCESS METRICS & KPIs - -### 9.1 Product Metrics - -| Metrik | Target (6M) | Target (12M) | Measurement | -|--------|------------|-------------|-------------| -| **App Install Rate** | 30% of users | 60% of users | App Store Analytics | -| **Monthly Active Users (MAU)** | 40% of customers | 70% of customers | App Backend Logs | -| **Successful Readings/Month** | 95%+ success rate | 97%+ success rate | Dashboard KPI | -| **Average Time to Submit** | <3 min | <2 min | User Session Logs | -| **OCR Accuracy** | 95%+ | 97%+ | Test Dataset | -| **App Crash Rate** | <0.1% | <0.05% | Crash Analytics | -| **NPS Score** | >40 | >50 | Monthly Survey | - -### 9.2 Business Metrics - -| Metrik | Target (12M) | Measurement | -|--------|------------|-------------| -| **Customers Acquired** | 10-15 Stadtwerke | Sales Pipeline | -| **Annual Recurring Revenue (ARR)** | €800k - €1.2M | Finance | -| **Customer Retention Rate** | >90% | Churn Analysis | -| **Customer Satisfaction (CSAT)** | >80% | Survey | -| **Cost per User** | <€2 | Cost Analytics | - -### 9.3 Operational Metrics - -| Metrik | Target | Measurement | -|--------|--------|-------------| -| **System Uptime** | 99.9% | Monitoring (Datadog) | -| **Average Response Time** | <500ms | APM Tools | -| **OCR Processing Time** | <1s | Backend Logs | -| **API Error Rate** | <0.1% | API Monitoring | -| **Database Query Time** | <100ms | Query Logs | - ---- - -## 10. TIMELINE & MILESTONES - -### Phase 1: Foundation (Week 1-2) -- [ ] Team Setup & Onboarding -- [ ] Development Environment Setup -- [ ] Database & API Schema Design -- [ ] UI/UX Design Finalization (Figma) - -### Phase 2: MVP Development (Week 3-8) - -**Sprint 1-2 (Week 3-4): Backend Foundation** -- [ ] Project Setup (Node.js, Express, PostgreSQL) -- [ ] Authentication API (Sign Up, Login, 2FA) -- [ ] Database Migrations -- [ ] CI/CD Pipeline Setup - -**Sprint 2-3 (Week 5-6): Mobile App** -- [ ] React Native Project Setup -- [ ] Camera Integration -- [ ] Photo Upload Flow -- [ ] Basic UI Implementation - -**Sprint 3-4 (Week 7-8): OCR Integration** -- [ ] Google Vision API Integration -- [ ] OCR Pipeline (Photo → Digits) -- [ ] Confidence Scoring -- [ ] Error Handling - -**Sprint 4 (Week 8): Submission & Dashboard** -- [ ] Submission Workflow -- [ ] Confirmation Emails/SMS -- [ ] Basic Admin Dashboard -- [ ] Reading History - -### Phase 3: Testing & Optimization (Week 9-10) -- [ ] Unit Tests (Backend + Frontend) -- [ ] Integration Tests -- [ ] E2E Tests -- [ ] Performance Optimization - -### Phase 4: Pre-Launch (Week 11-12) -- [ ] Beta Testing (5-10 Kunden) -- [ ] Feedback Collection -- [ ] Bug Fixes -- [ ] Production Deployment - -### Phase 5: Launch & Support (Week 13+) -- [ ] Official Launch -- [ ] Support & Monitoring -- [ ] Customer Onboarding -- [ ] Iteration & Improvements - ---- - -## 11. RISKS & MITIGATION - -| Risiko | Wahrscheinlichkeit | Impact | Mitigation | -|--------|------------------|--------|-----------| -| **OCR Accuracy niedrig** | Medium | Hoch | Testing mit 100+ Meter-Fotos, Google Vision ist 97%+ | -| **SAP Integration komplex** | Medium | Hoch | Early Integration Testing, Dedicated Integration Engineer | -| **Mobile Adoption schwach** | Low | Mittel | Good UX Design, Video Tutorials, SMS Reminders | -| **Performance Issues** | Low | Mittel | Load Testing, Caching Strategy, Database Indexing | -| **Security Vulnerabilities** | Low | Hoch | Penetration Testing, Code Reviews, Security Audits | -| **Compliance Issues (DSGVO)** | Low | Hoch | Legal Review Early, Privacy-by-Design, Audit Trail | - ---- - -## 12. ROLLOUT STRATEGY - -### Phase A: Beta Phase (Week 13-16) -- **Customers:** 3-5 Small Stadtwerke -- **Users:** 500-1000 Endkunden -- **Goal:** Validate product-market-fit, gather feedback -- **Success Criteria:** - - NPS >40 - - OCR Success Rate >95% - - <1 Critical Bug - -### Phase B: Soft Launch (Week 17-20) -- **Customers:** 10-15 Small-to-Medium Stadtwerke -- **Users:** 5.000-10.000 Endkunden -- **Goal:** Prove business model, improve onboarding -- **Success Criteria:** - - NPS >45 - - Monthly Churn <5% - - Customer Satisfaction >75% - -### Phase C: General Availability (Month 6+) -- **Customers:** 20-30 Stadtwerke (Mix small/large) -- **Users:** 50.000+ Endkunden -- **Goal:** Scale to profitability -- **Success Criteria:** - - NPS >50 - - Monthly Churn <3% - - ARR >€1M - ---- - -## 13. RESOURCE REQUIREMENTS (MVP) - -### Team Size: 7-9 Personen (6 Monate) - -| Role | Seniority | FTE | Responsibilities | -|------|-----------|-----|------------------| -| Product Manager | Mid | 1.0 | PRD, Roadmap, Prioritization | -| Tech Lead / CTO | Senior | 1.0 | Architecture, Tech Decisions, Code Quality | -| Backend Lead | Senior | 1.0 | API Design, Database, Integration | -| Backend Developer | Mid | 1.0 | Backend Feature Development | -| React Native Developer | Mid | 1.0 | Mobile App Development | -| Frontend Developer | Junior | 1.0 | Dashboard Frontend | -| DevOps / Infrastructure | Mid | 0.5 | CI/CD, Deployment, Monitoring | -| QA / Tester | Mid | 0.5 | Testing, Bug Reports | -| **Total** | | **7.5** | | - -### Budget (6 Monate MVP) - -| Category | Cost | -|----------|------| -| **Salaries (7.5 FTE × €8k/month avg)** | €360.000 | -| **Infrastructure (AWS, Google API)** | €15.000 | -| **Tools (IDE, Figma, Jira, Slack)** | €8.000 | -| **Contingency (10%)** | €38.300 | -| **Total** | **€421.300** | - -*Rounded to **€420-450k*** für MVP-Entwicklung - ---- - -## 14. SUCCESS DEFINITION - -### Minimum Viable Product (MVP) Success -- ✅ App funktioniert auf iOS + Android -- ✅ OCR Accuracy >95% -- ✅ 3+ Stadtwerke haben erfolgreich abgelesen (100+ Readings) -- ✅ System uptime: 99.5% -- ✅ NPS >40 in Beta -- ✅ Zero critical bugs -- ✅ DSGVO-compliant - -### Go-to-Market Success -- ✅ 10 Customers in Year 1 -- ✅ 500+ Readings/Day durchschnittlich -- ✅ €800k - €1.2M ARR -- ✅ <5% Churn rate -- ✅ >40 NPS Score - ---- - -## 15. APPENDIX: GLOSSARY - -| Term | Definition | -|------|-----------| -| **OCR** | Optical Character Recognition - automatische Ziffernerkennung aus Fotos | -| **ARR** | Annual Recurring Revenue - jährliche wiederkehrende Einnahmen | -| **ACV** | Average Contract Value - durchschnittlicher Vertragswert | -| **MVP** | Minimum Viable Product - kleinste funktionsfähige Version | -| **NPS** | Net Promoter Score - Maß für Kundenloyal (0-100) | -| **DSGVO** | Datenschutz-Grundverordnung (GDPR) | -| **SAP** | ERP-System für Finanzbuchführung & Abrechnungen | -| **SaaS** | Software as a Service - Cloud-basiertes Softwaremodell | -| **Confidence Score** | Genauigkeit der OCR-Erkennung (0-100%) | - ---- - -## 16. APPROVAL & SIGN-OFF - -| Role | Name | Signature | Date | -|------|------|-----------|------| -| Product Manager | [Name] | __________ | ________ | -| Engineering Lead | [Name] | __________ | ________ | -| Business Lead | [Name] | __________ | ________ | -| Stakeholder | [Name] | __________ | ________ | - ---- - -**Document Version:** 1.0 -**Last Updated:** Februar 2026 -**Next Review:** April 2026 -**Status:** READY FOR DEVELOPMENT diff --git a/USER_STORIES.md b/USER_STORIES.md new file mode 100644 index 0000000..606011b --- /dev/null +++ b/USER_STORIES.md @@ -0,0 +1,107 @@ +# InnungsApp — User Stories + +> **Format:** Als [Rolle] möchte ich [Aktion], damit [Nutzen]. +> **Status:** MVP = im ersten Release | Post-MVP = spätere Version + +--- + +## Rolle: Innungsgeschäftsführer (Admin) + +### Onboarding & Setup +- [ ] Als Admin möchte ich die Innung in 15 Minuten einrichten (Name, Logo, Sparten, Kontaktdaten), damit wir schnell starten können. **[MVP]** +- [ ] Als Admin möchte ich Mitglieder per CSV-Import massenweise anlegen, damit ich nicht jeden einzeln eingeben muss. **[MVP]** +- [ ] Als Admin möchte ich Einladungs-E-Mails an alle Mitglieder mit einem Klick versenden, damit sie ihre Accounts aktivieren. **[MVP]** +- [ ] Als Admin möchte ich sehen, wer die Einladung angenommen hat und wer nicht, damit ich nachfassen kann. **[MVP]** + +### Mitgliederverwaltung +- [ ] Als Admin möchte ich ein neues Mitglied anlegen (Name, Betrieb, Sparte, E-Mail, Telefon), damit es in der App erscheint. **[MVP]** +- [ ] Als Admin möchte ich ein Mitglied auf "ausgetreten" setzen, damit es keinen Zugriff mehr hat. **[MVP]** +- [ ] Als Admin möchte ich die Mitgliederliste nach Sparte, Ort und Status filtern, damit ich gezielt suchen kann. **[MVP]** +- [ ] Als Admin möchte ich die gesamte Mitgliederliste als CSV exportieren, damit ich sie für andere Zwecke nutzen kann. **[Post-MVP]** +- [ ] Als Admin möchte ich ein Notizfeld pro Mitglied haben, damit ich interne Informationen festhalten kann. **[MVP]** + +### Kommunikation +- [ ] Als Admin möchte ich einen Beitrag mit Text, Kategorie und optionalem PDF-Anhang erstellen, damit Mitglieder informiert werden. **[MVP]** +- [ ] Als Admin möchte ich einen Beitrag zeitgesteuert veröffentlichen (z.B. morgen um 8 Uhr), damit ich Mitteilungen vorbereiten kann. **[MVP]** +- [ ] Als Admin möchte ich nach der Veröffentlichung sehen, wie viele Mitglieder den Beitrag gelesen haben, damit ich die Reichweite kenne. **[MVP]** +- [ ] Als Admin möchte ich eine Push-Notification an alle Mitglieder senden, wenn ein wichtiger Beitrag erscheint. **[MVP]** +- [ ] Als Admin möchte ich einen Beitrag als "Wichtig" anpinnen, damit er oben im Feed erscheint. **[MVP]** + +### Terminverwaltung +- [ ] Als Admin möchte ich Termine anlegen (Titel, Datum, Uhrzeit, Ort, Typ), damit Mitglieder informiert sind. **[MVP]** +- [ ] Als Admin möchte ich die Teilnehmerliste eines Termins einsehen und als CSV exportieren, damit ich planen kann. **[MVP]** +- [ ] Als Admin möchte ich für Termine eine maximale Teilnehmerzahl setzen, damit ich die Kapazität steuere. **[Post-MVP]** + +### Lehrstellenverwaltung +- [ ] Als Admin möchte ich alle Lehrstellenangebote meiner Mitgliedsbetriebe einsehen und moderieren, damit keine ungeeigneten Inhalte erscheinen. **[MVP]** +- [ ] Als Admin möchte ich Stellen im Namen von Betrieben anlegen, die das nicht selbst können, damit alle vertreten sind. **[MVP]** + +### Analytics +- [ ] Als Admin möchte ich auf dem Dashboard sehen: Mitgliederanzahl, aktive Nutzer diese Woche, ungelesene Beiträge, kommende Termine. **[MVP]** +- [ ] Als Admin möchte ich einen Monatsbericht (PDF) über Aktivität und Nutzung erhalten, damit ich dem Vorstand berichten kann. **[Post-MVP]** + +--- + +## Rolle: Innungsmitglied (Betrieb) + +### Erste Nutzung +- [ ] Als Mitglied möchte ich mich via Magic Link (E-Mail-Link) einloggen, ohne ein Passwort erstellen zu müssen, damit der Einstieg einfach ist. **[MVP]** +- [ ] Als Mitglied möchte ich beim ersten Login sehen, was die App kann, damit ich sie sofort sinnvoll nutzen kann. **[MVP]** + +### Mitgliederverzeichnis +- [ ] Als Mitglied möchte ich alle anderen Betriebe meiner Innung sehen, damit ich mich vernetzen kann. **[MVP]** +- [ ] Als Mitglied möchte ich nach Betrieb, Name, Sparte oder Ort suchen, damit ich schnell finde, was ich suche. **[MVP]** +- [ ] Als Mitglied möchte ich einen anderen Betrieb direkt anrufen (Tap-to-Call), damit ich keine Nummer abtippen muss. **[MVP]** +- [ ] Als Mitglied möchte ich mein eigenes Profil (Kontaktdaten, Website) bearbeiten, damit meine Daten aktuell sind. **[Post-MVP]** + +### News & Mitteilungen +- [ ] Als Mitglied möchte ich alle Mitteilungen der Innung in einer übersichtlichen Liste sehen, damit ich nichts verpasse. **[MVP]** +- [ ] Als Mitglied möchte ich Push-Benachrichtigungen bei wichtigen Mitteilungen erhalten, damit ich sofort informiert bin. **[MVP]** +- [ ] Als Mitglied möchte ich PDF-Anhänge direkt in der App öffnen, damit ich keine E-Mail suchen muss. **[MVP]** +- [ ] Als Mitglied möchte ich einstellen können, welche Kategorien mir Push-Benachrichtigungen senden, damit ich nicht überflutet werde. **[Post-MVP]** + +### Termine +- [ ] Als Mitglied möchte ich alle kommenden Termine sehen, damit ich planen kann. **[MVP]** +- [ ] Als Mitglied möchte ich mich für einen Termin an-/abmelden, damit der Admin die Planung kennt. **[MVP]** +- [ ] Als Mitglied möchte ich einen Termin in meinen Kalender exportieren (iCal/Google), damit er in meinem Kalender erscheint. **[MVP]** +- [ ] Als Mitglied möchte ich 24h vor einem Termin, für den ich angemeldet bin, eine Erinnerung erhalten. **[MVP]** + +### Lehrlingsbörse +- [ ] Als Mitglied (Ausbildungsbetrieb) möchte ich meine Ausbildungsstellen selbst einstellen und verwalten, damit ich Bewerber finde. **[MVP]** +- [ ] Als Mitglied möchte ich meine Stellen schnell aktivieren oder pausieren, wenn die Position besetzt ist. **[MVP]** +- [ ] Als Mitglied möchte ich sehen, wie viele Bewerber meine Stelle kontaktiert haben. **[Post-MVP]** + +--- + +## Rolle: Azubi-Bewerber (Gen Z, öffentlich) + +- [ ] Als Bewerber möchte ich Ausbildungsstellen einer Innung ohne Login durchsuchen, damit ich keine Hürde habe. **[MVP]** +- [ ] Als Bewerber möchte ich nach Sparte, Ort und Ausbildungsstart filtern, damit ich relevante Stellen finde. **[MVP]** +- [ ] Als Bewerber möchte ich einen Betrieb direkt per Telefon oder E-Mail kontaktieren, ohne ein Formular auszufüllen. **[MVP]** +- [ ] Als Bewerber möchte ich sehen, was ein Azubi in diesem Beruf verdient (Vergütung nach Lehrjahr), damit ich einen Vergleich habe. **[MVP]** +- [ ] Als Bewerber möchte ich Videos von Azubis sehen, die ihren Berufsalltag zeigen, damit ich einen echten Eindruck bekomme. **[Post-MVP / Azubi-Modul]** +- [ ] Als Bewerber möchte ich mich mit einem Profil (ohne CV) bewerben ("Swipe to Apply"), damit die Hürde niedrig ist. **[Post-MVP / Azubi-Modul]** +- [ ] Als Bewerber möchte ich den Lohn-Rechner nutzen ("Was verdiene ich wirklich?"), damit ich informiert entscheide. **[Post-MVP / Azubi-Modul]** + +--- + +## Rolle: Azubi (in der Ausbildung) + +- [ ] Als Azubi möchte ich mein digitales Berichtsheft über die App führen (Fotos, Sprachnotizen), damit ich keinen Papierkram brauche. **[Post-MVP Q3]** +- [ ] Als Azubi möchte ich Prüfungsfragen für meinen Beruf als tägliches Quiz erhalten, damit ich mich vorbereite. **[Post-MVP Q3]** +- [ ] Als Azubi möchte ich Innungs-News und Termine sehen, damit ich auf dem Laufenden bleibe. **[Post-MVP]** +- [ ] Als Azubi möchte ich meinen Lernfortschritt verfolgen, damit ich weiß, wo ich stehe. **[Post-MVP Q4]** + +--- + +## Rolle: Obermeister (Vereinsvorsitzender) + +- [ ] Als Obermeister möchte ich Beiträge vor der Veröffentlichung freigeben, damit nur geprüfte Inhalte erscheinen. **[Post-MVP]** +- [ ] Als Obermeister möchte ich Statistiken (Nutzerzahlen, Aktivität) auf einem Dashboard sehen, damit ich den Digitalisierungsfortschritt sehe. **[Post-MVP]** + +--- + +## Rolle: HWK-Mitarbeiter (Post-MVP) + +- [ ] Als HWK-Mitarbeiter möchte ich eine Übersicht aller Innungen in meinem Kammerbezirk sehen, damit ich Informationen zentral verwalten kann. **[Post-MVP Q4]** +- [ ] Als HWK-Mitarbeiter möchte ich Beiträge an alle Innungen gleichzeitig senden, damit wichtige Informationen alle erreichen. **[Post-MVP Q4]** diff --git a/VALIDATION_PLAYBOOK.md b/VALIDATION_PLAYBOOK.md index 08bea4c..ad22f64 100644 --- a/VALIDATION_PLAYBOOK.md +++ b/VALIDATION_PLAYBOOK.md @@ -1,560 +1,250 @@ -# VALIDATION PLAYBOOK +# InnungsApp — Validation Playbook -**Ziel:** Schnell validieren, ob SmartMeter-App ein echtes Problem löst -**Dauer:** 2-3 Wochen -**Output:** GO/NO-GO Entscheidung mit Daten +> **Ziel:** Hypothesen vor großen Investitionen mit echten Nutzern validieren --- -## PHASE 0: Interviews mit Entscheidungsträgern +## 1. Kern-Hypothesen -### Zielgruppe +| # | Hypothese | Validierungsmethode | Zielwert | +|---|---|---|---| +| H1 | Innungen zahlen 99–199 €/Monat für eine bessere App | Pilot-Conversion | ≥ 60 % Pilot → Paid | +| H2 | Mitglieder loggen sich aktiv ein (kein "Geisterprojekt") | WAU-Rate | ≥ 40 % der eingeladenen Mitglieder | +| H3 | Push-Notifications erhöhen Leserate vs. E-Mail | A/B-Test (Piloten) | Push-Leserate ≥ 2x E-Mail | +| H4 | Azubis nutzen die Lehrlingsbörse ohne Login | Analytics | ≥ 50 % der Aufrufe ohne Auth | +| H5 | Betriebe stellen Stellen selbst ein (kein Admin-Overhead) | Feature-Nutzung | ≥ 70 % Stellen vom Betrieb selbst | +| H6 | HWK sind bereit, InnungsApp zu empfehlen | HWK-Gespräche | 1 LOI innerhalb 6 Monate | -``` -Pro Stadtwerk: 2-3 Personen -1. IT-Leiter (Technical, Integration-Fragen) -2. Kundenservice-Leiter oder Betriebsleiter (Use Case, ROI) -3. CFO/Geschäftsführer (Budget, Priority) - -Total Target: 10-15 Stadtwerke -= 20-45 Interviews -``` - -### Kontakt-Strategie - -**Tiered Approach:** - -``` -Tier 1 (Known): Bestehende Kontakte -- LinkedIn Outreach zu IT Directors -- Existierende Geschäftspartner -- Networking Events (VKU) - -Tier 2 (Warm): Via Referrals -- Ask friends/advisors for intros -- Chamber of Commerce -- Industry associations - -Tier 3 (Cold): Direct Outreach -- LinkedIn Messages -- Email to general contacts -- VKU member database - -Template Email: --- -Subject: 15-Min Interview: Smart Meter Lösung für Stadtwerke -Hallo [Name], +## 2. Phase 0: Pre-Product Validation (vor der ersten Zeile Code) -wir entwickeln eine mobile App zur automatisierten Zählerablesung -für Stadtwerke. [Your Company] hat Expertise in diesem Bereich und -wir möchten von dir lernen. +### Customer Discovery Interviews -Hätte du Zeit für ein 15-Min Call diese Woche? Gerne telefonisch -oder per Zoom. +**Ziel:** Verstehen ob das Problem real und schmerzhaft genug ist. + +**Zielgruppe:** 10 Innungsgeschäftsführer, 5 Obermeister, 5 Mitglieder + +**Interview-Struktur (30 Minuten):** + +``` +Teil 1: Kontext verstehen (10 Min.) +────────────────────────────────── +"Beschreiben Sie mir, wie ein typischer Montag für Sie aussieht." +"Wie verwalten Sie aktuell die Mitglieder Ihrer Innung?" +"Wie kommunizieren Sie mit Mitgliedern — welche Tools nutzen Sie?" +"Wie oft haben Sie Kontakt zu einzelnen Mitgliedern?" +"Erzählen Sie mir von einem konkreten Moment, wo die Kommunikation schiefgelaufen ist." + +Teil 2: Pain Points herausarbeiten (10 Min.) +──────────────────────────────────────────── +"Was kostet Sie die meiste Zeit bei der Innungsarbeit?" +"Wenn Sie eine Sache sofort verbessern könnten, was wäre das?" +"Wie viele Stunden pro Woche verbringen Sie mit Verwaltungsaufgaben?" +"Was passiert, wenn ein Mitglied Sie wegen etwas anruft, das es selbst nachschlagen könnte?" +"Haben Sie schon andere Tools probiert? Was hat nicht funktioniert?" + +Teil 3: Lösung sondieren (10 Min.) +─────────────────────────────────── +[Figma Prototype / Mockup zeigen] +"Wenn ich Ihnen eine App zeige, die X und Y macht — was würden Sie als erstes tippen?" +"Was fehlt hier, was Sie erwartet hätten?" +"Was würden Sie daran anders machen?" +"Wenn diese App heute verfügbar wäre — würden Sie sie testen wollen?" +"Was würden Sie für diese Lösung bezahlen?" +``` + +**Auswertung:** +- Probleme die 3+ Personen unaufgefordert nennen = validiert +- Zahlungsbereitschaft > 100 €/Monat bei 3+ Personen = validiert + +**Interview-Aufzeichnung:** Notion-Template mit Zitaten, Audio-Mitschnitt (mit Erlaubnis) -Danke! -[Your Name] --- + +## 3. Phase 1: MVP Pilot Validation (Monat 1–3) + +### Pilot-Setup + +| Parameter | Wert | +|---|---| +| Anzahl Pilotinnungen | 5 | +| Pilot-Dauer | 3 Monate | +| Preis | kostenlos | +| Erwartung an Innung | Aktive Nutzung + wöchentlicher Feedback-Call | +| Erwartung an uns | Schnelle Bugfixes (< 24h), persönlicher Support | + +### Aktivierungsmetriken (Woche 1 nach Go-Live) + +| KPI | Definition | Zielwert | Alarmsignal | +|---|---|---|---| +| Einladungsrate | Eingeladene Mitglieder / Gesamt-Mitglieder | ≥ 80 % | < 50 % | +| Aktivierungsrate | Eingeloggte Nutzer / Eingeladene | ≥ 60 % | < 30 % | +| Time to First Action | Zeit bis erster Aktion nach Login | < 2 Min. | > 5 Min. | +| Feature Discovery | Nutzer die ≥ 3 Features genutzt haben | ≥ 50 % | < 20 % | + +### Engagement-Metriken (Monat 1–3) + +| KPI | Definition | Zielwert | +|---|---|---| +| WAU Rate | Wöchentl. aktive Nutzer / Gesamt-Nutzer | ≥ 40 % | +| News Leserate | Gelesen / Empfangen pro Beitrag | ≥ 50 % | +| Termin-Anmeldequote | Angemeldete / Eingeladene pro Termin | ≥ 40 % | +| Lehrlingsbörse Views | Öffentliche Aufrufe der Stellenliste | > 0 Bewerberkontakte | +| NPS (Admin) | Net Promoter Score der Geschäftsführer | ≥ 50 | +| NPS (Mitglied) | Net Promoter Score der Mitglieder | ≥ 40 | +| Support-Tickets | Kritische Bugs gemeldet | < 2 pro Innung | + +### Wöchentlicher Check-In mit Pilot-Innungen + +**Format:** 20-Minuten-Video-Call, jede Woche + +``` +Agenda: +1. "Was hat gut funktioniert diese Woche?" (5 Min.) +2. "Was hat nicht funktioniert / gefehlt?" (5 Min.) +3. "Zeigen Sie mir, wie Sie X benutzt haben" (5 Min.) +4. "Nächste Woche freischalten wir Feature Y — was erwarten Sie?" (5 Min.) +``` + +**Dokumentation:** Call-Notizen in Notion → Feature-Feedback → Backlog-Update + +### NPS-Umfrage (nach 6 Wochen) + +**Zeitpunkt:** 6 Wochen nach Go-Live, via In-App-Banner + +**Fragen:** +1. "Wie wahrscheinlich ist es, dass Sie InnungsApp einer anderen Innung empfehlen?" (0–10) +2. "Was würden Sie sofort verbessern?" (Freitext) +3. "Welches Feature ist für Sie am wichtigsten?" (Auswahl + Ranking) + +--- + +## 4. Phase 2: Conversion Validation (Monat 3) + +### Pilot → Bezahlt Gespräch + +**Zeitpunkt:** 2 Wochen vor Pilot-Ende + +**Script:** +``` +"Wir sind jetzt 3 Monate dabei. Ich möchte offen mit Ihnen sprechen. + Was hat die App für Ihre Innung verändert? + [Zuhören, konkrete Beispiele erfragen] + + Basierend auf dem, was ich gesehen habe, glaube ich, dass + [konkrete Zahl: z.B. "60 % Ihrer Mitglieder sind wöchentlich aktiv"]. + + Wir werden die App nach dem Piloten für 149 €/Monat anbieten. + Was braucht es von unserer Seite, damit Sie dabei bleiben?" +``` + +**Conversion-Trigger:** +- Intern: WAU > 40 % UND Leserate > 50 % → hohe Conversion-Wahrscheinlichkeit +- Zeige dem Admin seine eigenen Metriken im Gespräch + +**Ziel:** ≥ 3 von 5 Piloten konvertieren + +### Preis-Sensitivität testen + +**Methode:** Van Westendorp Price Sensitivity Meter im Gespräch: + +``` +"Zu welchem Preis würden Sie sagen, die App ist..." +1. "...zu günstig, sodass Sie an der Qualität zweifeln würden?" [€] +2. "...günstig — ein gutes Preis-Leistungs-Verhältnis?" [€] +3. "...teuer, aber Sie würden es noch überlegen?" [€] +4. "...zu teuer — Sie würden es nicht kaufen?" [€] ``` --- -## Interview Guide +## 5. Phase 3: Kanal-Validation (Monat 4–6) -### PART A: Problem Discovery (5 Min) +### Hypothese: "Direktakquise funktioniert" -**Q1: Current State** -``` -"Wie funktioniert eure Zählerablesung heute?" +**Test:** +- 50 Kaltakquise-E-Mails an Innungen in BW +- Tracking: Öffnungsrate, Antwortrate, Demo-Rate, Pilot-Rate -Expected Answers (flag if they say): -- Manual reading by customer -- Reading by technician -- Automated meter (smart meter) -- Mix of the above +**Erfolgskriterium:** Pilot-Rate > 10 % (5 von 50) -Red Flag: If 100% automated already → No problem to solve -Green Flag: If manual + high error rate → Good fit -``` +### Hypothese: "LinkedIn-Outreach funktioniert besser als E-Mail" -**Q2: Problem Validation** -``` -"Wie viel Zeit/Kosten investiert ihr jährlich in Zählerablesung?" +**Test:** +- 20 E-Mail-Kaltakquise (Kontrollgruppe) +- 20 LinkedIn-Direktnachrichten (Testgruppe) +- Messen: Antwortrate, Demo-Rate -Deep Dive: -- "Wie viele Zählerstände werden abgelesen pro Jahr?" -- "Wer macht das - Mitarbeiter oder Kunden?" -- "Wie hoch ist die Fehlerquote?" (Ziel: >20% = pain point) -- "Was kostet euch jede manuelle Ablesung?" +**Erfolgskriterium:** Einer der Kanäle > 15 % Demo-Rate -Example Math: -- 100K Kunden × 1 reading/year = 100K readings -- 30% need manual follow-up = 30K manual readings -- @€2 per reading = €60K/year cost +### Hypothese: "Zielgruppe sucht aktiv nach Lösung (SEO-Potenzial)" -Red Flag: Low error rate (<5%) or low cost (<€20K) → not a pain point -Green Flag: >20% error rate or >€50K/year cost → worth solving -``` - -**Q3: Current Frustrations** -``` -"Welche sind eure Top 3 Probleme mit dem aktuellen Process?" - -Listen for: -- Customer disputes over readings -- Staff effort (time-consuming) -- Data quality issues -- Customer complaints (feedback) -- Billing inaccuracies - -Probe deeper on each: -- "How often does this happen?" -- "What's the impact?" (Cost? Customer satisfaction?) -- "Who feels the pain most?" (Support team? Finance? Customers?) -``` +**Test:** +- Google Search Console nach 3 Monaten Blog-Content +- Keywords: "Innungsverwaltung Software", "App für Innungen", "Mitgliederverwaltung Handwerk" +- Ziel: > 100 organische Besucher/Monat nach 3 Monaten --- -### PART B: Solution Fit (5 Min) +## 6. Kill Criteria -**Q4: Appetite for Change** -``` -"Würdet ihr eine Mobile App für die Zählerablesung einführen?" +**Wir stoppen das Projekt wenn:** -Expected Answers: -A) "Yes, if it solves [specific problem]" -B) "Maybe, but we need to think about it" -C) "No, not interested" -D) "We're already evaluating solutions" +| Kriterium | Wert | +|---|---| +| Aktivierungsrate nach 3 Monaten Pilot | < 20 % | +| Pilot → Paid Conversion | < 2 von 5 (40 %) | +| NPS Admin | < 20 | +| Zahlungsbereitschaft | < 99 €/Monat bei Mehrheit | +| Support-Aufwand | > 5h/Woche pro Innung (nicht skalierbar) | -Green Flag: Answer A or D -Red Flag: Answer C or B (lukewarm interest) - -Follow-up: -- "What would make this compelling for you?" -- "What would be blockers?" -- "Timeline - when would you need this?" -``` - -**Q5: Customer Adoption Likelihood** -``` -"Glaubst du, dass deine Kunden eine App nutzen würden -zur Zählerablesung?" - -Dig deeper: -- "What % of your customers would use it?" (Target: >20% = viable) -- "What incentives would help adoption?" - - Free (most customers don't care) - - Small discount (€1-2/year per reading) - - Instant feedback (meter consumption insights) -- "Would you push it to customers or wait for demand?" - -Red Flag: <10% adoption estimate -Green Flag: >20% adoption estimate -``` - -**Q6: Integration Feasibility** -``` -"Welche Systeme nutzt ihr für Kundenmanagement?" - -Record: -- Billing system (SAP, Oracle, Infor, etc.) -- CRM (Salesforce, etc.) -- Meter database (own, external, etc.) -- IT infrastructure (on-prem, cloud, hybrid) - -Follow-up: -- "How open is your IT for external integrations?" -- "Who would need to approve this?" -- "Do you have an API layer?" - -Red Flag: Very legacy, no API access, slow approval -Green Flag: Modern stack, willing to integrate -``` +**Pivots bei Kill-Criteria:** +- WAU niedrig, aber Lehrlingsbörse-Traffic hoch → Pivot zu reiner Azubi-Plattform +- Admins mögen es, Mitglieder nicht → Pivot zu reinem Admin-Tool (Web-only) +- Innungen zahlen nicht → HWK direkt als zahlender Kunde angehen --- -### PART C: Commercial Viability (3 Min) +## 7. Tracking Setup -**Q7: Budget & Pricing** -``` -"Wie viel würdet ihr für eine Lösung budgetieren?" +### Analytics Events (PostHog) -Open-ended first: -- Listen to their thinking -- Don't anchor them to your price - -Then probe: -- "Is that annual or one-time?" -- "Would you pay monthly/yearly/license?" -- "What's the ROI threshold?" (Typical: payback in 1-2 years) - -Red Flag: Budget <€20K/year or willing to pay only if risk-free -Green Flag: Budget >€50K/year, willing to invest for ROI +```typescript +// Alle kritischen User Actions tracken +posthog.capture('member_invited', { org_id, member_count: 1 }); +posthog.capture('member_activated', { org_id, time_since_invite_hours: 24 }); +posthog.capture('news_opened', { org_id, news_id, kategorie }); +posthog.capture('news_attachment_downloaded', { org_id, news_id }); +posthog.capture('termin_angemeldet', { org_id, termin_id, termin_typ }); +posthog.capture('ical_exported', { org_id }); +posthog.capture('stelle_created', { org_id }); +posthog.capture('stelle_viewed', { org_id, stelle_id, sparte, is_logged_in: false }); +posthog.capture('stelle_contact_tapped', { org_id, stelle_id, contact_method: 'call' }); ``` -**Q8: Decision Making Process** -``` -"Wie würde so eine Entscheidung ablaufen?" +### Funnels in PostHog -Map: -- Who needs to approve? (Budget owner, IT, Board?) -- Timeline? (Fast-track vs. normal process) -- RFP required? (Or can you do handshake deal?) -- Contract terms? (1-year, 3-year, multi-year discount?) +1. **Aktivierungs-Funnel:** Eingeladen → E-Mail geöffnet → Link geklickt → Login → Erste Aktion +2. **News-Funnel:** Push erhalten → App geöffnet → Beitrag gelesen → Anhang geöffnet +3. **Stellen-Funnel:** Stellenliste aufgerufen → Stelle geöffnet → Kontakt aufgenommen +4. **Admin-Funnel:** Login → Beitrag erstellt → Veröffentlicht → Push gesendet -Red Flag: Requires months-long RFP, many approvers, slow -Green Flag: Can decide quickly, fewer stakeholders -``` - -**Q9: Switching Costs** -``` -"Wenn die App nicht funktioniert, wie schnell könnt ihr -rückwärts gehen?" - -This matters because: -- High switching costs = stickier customer -- Easy exit = customer feels safer trying - -Answer: -- "We'd just stop recommending it to customers" -- "We'd need to ramp down over X months" -- etc. - -Green Flag: Easy to exit → customer feels safe to try -``` - ---- - -### PART D: Follow-Up / Qualification (2 Min) - -**Q10: Next Steps** -``` -"Wäre es interessant, wenn wir euch eine Demo/Beta -im nächsten Monat zeigen?" - -Clear YES: -- "Yes, I want to see this" -- "Yes, let's do a pilot" - -Soft YES: -- "Maybe, depends on what I see" -- "Let me talk to my team first" - -NO: -- "Not right now" -- "We're happy with our current approach" - -Green Flag: Clear YES → Schedule demo/pilot for them -Soft YES: Send materials, follow up in 2 weeks -NO: Thank them, add to "maybe later" list -``` - -**Q11: Introductions** -``` -"Kennst du andere Stadtwerke, die ähnliche Probleme haben?" - -Goal: Get warm referrals -- "Can you introduce me to [competitor]?" -- "Would you be willing to be a reference?" - -Green Flag: YES on both → builds your network, proof -``` - ---- - -## Data Collection Template - -Create a Spreadsheet with: +### Dashboard für Piloten (Wöchentlicher Report per E-Mail) ``` -| Stadtwerk | Size | Contact | Q1 Method | Q2 Cost/Error | Q3 Pain | Q4 Appetite | Q5 Adoption | Q6 Integration | Q7 Budget | Q8 Timeline | Score | Notes | -|-----------|------|---------|-----------|----------------|---------|-------------|------------|-----------------|-----------|-----------|-------|-------| -| Stadt A | 100K | John D. | Manual 50%| €60K, 30% err | High | Yes | 30% | SAP, open | €80K | 2 months | 9/10 | Hot lead | -| Stadt B | 50K | Jane S. | Manual 70%| €40K, 25% err | Medium | Maybe | 15% | Legacy, closed | €30K | 6 months | 5/10 | Cold | +Betreff: Ihre InnungsApp Wochenbericht — KW 12 + +Aktivität diese Woche: +✓ 45 von 78 Mitgliedern waren aktiv (58 %) +✓ 2 Beiträge veröffentlicht → Ø Leserate: 71 % +✓ 3 neue Terminanmeldungen +✓ 4 Aufrufe der Lehrlingsbörse (2 Kontaktanfragen) + +Vergleich zu letzter Woche: +↑ +12 % mehr aktive Nutzer +↑ +8 % höhere Leserate + +Ausstehend: +⚠ 14 Mitglieder haben sich noch nie eingeloggt → [Erinnerung senden] ``` - ---- - -## GO / NO-GO Decision Framework - -### Scoring Matrix - -Assign points (1-10) for each question: - -``` -Q1: Current Manual Process = ___ / 10 - (1 = fully automated, 10 = fully manual) - -Q2: Annual Cost/Pain = ___ / 10 - (1 = <€10K cost, 10 = >€100K cost) - -Q3: Frustration Level = ___ / 10 - (1 = not a priority, 10 = huge pain) - -Q4: Appetite for Change = ___ / 10 - (1 = no, 10 = ready to sign today) - -Q5: Customer Adoption = ___ / 10 - (1 = <5%, 10 = >50%) - -Q6: Integration Feasible = ___ / 10 - (1 = impossible, 10 = very easy) - -Q7: Budget Available = ___ / 10 - (1 = <€20K, 10 = >€100K) - -Q8: Fast Decision = ___ / 10 - (1 = >6 months, 10 = <1 month) - -TOTAL SCORE = Sum of all 8 / 8 × 10 = ___ / 10 -``` - -### Go/No-Go Thresholds - -``` -SCORE 8-10: HOT LEADS (Definitely pursue) -- Validate further with second/third meetings -- Structure a pilot/POC -- These are your first customers - -SCORE 6-7: WARM LEADS (Worth pursuing) -- Keep in pipeline -- Send materials, stay in touch -- Re-engage in 3 months - -SCORE 4-5: COOL LEADS (Maybe later) -- Add to "monitor" list -- Market conditions may change -- Re-approach in 6 months - -SCORE <4: COLD LEADS (Not a fit now) -- Don't waste time -- Maybe re-approach if product evolves -``` - -### Portfolio Requirements for GO Decision - -After 10-15 interviews, you need: - -``` -✅ GO Signal if: -- 5+ Hot Leads (score 8-10) with €50K+ budget each -- OR 10+ Warm Leads (score 6-7) that could grow into hot -- Average adoption estimate: >20% -- Average budget: >€50K/year -- Market size (sum of budgets): >€500K - -❌ NO-GO Signal if: -- <3 Hot Leads -- Average score <5 -- Average adoption <10% -- Market size <€300K -- Pattern of "we'll wait and see" -``` - ---- - -## Competitive Positioning - -During interviews, also ask: - -``` -"Are you evaluating any other solutions?" - -Typical answers: -A) "Yes, we're in RFP with SAP/Oracle" -B) "No, but considering some options" -C) "Not actively, but open to ideas" -D) "We tried something similar, didn't work" - -Analysis: -- A: You're late, but potentially better/cheaper/faster -- B: You're in conversation, good timing -- C: You're educating the market, need strong proof -- D: Understand what failed, position differently - -Use competitive insights to position your MVP: -- Faster to market vs. SAP -- Cheaper than Oracle (€50K vs. €200K+) -- Mobile-first (better UX) -- Customizable (specific to Stadtwerke) -``` - ---- - -## Timeline & Execution - -### Week 1: Prep & Recruiting -``` -Mon-Tue: -- Create interview guide (this doc) -- Build data collection spreadsheet -- Create email template - -Wed-Fri: -- Start outreach (LinkedIn, email, phone) -- Target: 10-15 interviews scheduled - -Tools: -- Calendly for scheduling -- Zoom for remote calls -- Google Sheets for data -``` - -### Week 2-3: Conduct Interviews -``` -Goal: 10-15 interviews (2 per day) -Prep for each: -- Research company (size, industry focus) -- Prepare notes -- Test audio/video - -During: -- Record (with permission) or take notes -- Be friendly, genuine, listening-focused -- Don't pitch hard (listen more than talk) - -After: -- Score each interview -- Add to spreadsheet -- Send thank you note + case study PDF - -Time per interview: 20-30 min (including travel/setup) -Total time: ~10 hours for 15 interviews -``` - -### Week 4: Analysis & Decision -``` -Mon-Tue: -- Score all interviews -- Aggregate data in spreadsheet -- Create summary report - -Wed: -- Team discussion -- GO/NO-GO vote - -Thu-Fri: -- If GO: Contact top Hot Leads about pilot -- If NO-GO: Pivot to different pain point or market -``` - ---- - -## Sample Report Template - -After Week 3, create: - -``` -# VALIDATION REPORT: SmartMeter-Lite App -Date: [Date] -Conducted by: [Name] - -## Executive Summary -- 12 Interviews conducted -- 7 Hot Leads (58%), 3 Warm Leads (25%), 2 Cold (17%) -- Average budget: €65K/year -- Market opportunity: €780K in year 1 -- **Recommendation: GO** ✅ - -## Key Findings -1. Manual meter reading is REAL pain - - Avg cost: €50K/year per Stadtwerk - - Avg error rate: 28% - - Top frustration: Customer disputes - -2. Market appetite is strong - - 58% very interested (Hot) - - 25% interested (Warm) - - Would pay avg €65K/year - -3. Integration is manageable - - 75% have API-accessible systems - - 60% can integrate within 3-6 months - - Legacy systems are minority - -4. Customer adoption is solid - - Avg expected adoption: 25% - - Range: 10-40% - - Key: Make it optional (don't force) - -## Top Hot Leads -1. Stadtwerke München (100K households, €120K budget, Ready Now) -2. Stadtwerke Köln (80K households, €100K budget, 2-month timeline) -3. Stadtwerke Hamburg (120K households, €150K budget, 3-month timeline) - -## Risk Factors -- SAP/Oracle competition (but they're slow) -- DSGVO compliance needed (doable) -- Integration complexity (manageable) - -## Next Steps -1. Schedule pilots with top 3 Hot Leads -2. Get signed LOI (Letters of Intent) -3. Begin development in Week 5 -4. Deliver MVP in 12 weeks -``` - ---- - -## Key Metrics to Track - -After validation, you have: - -``` -√ Market Size: €X (sum of budgets from interviews) -√ Win Rate: Y% (Hot Leads / Total) -√ Sales Cycle: Z months (from interviews) -√ Product-Market Fit Score: __ / 10 -√ Competitive Landscape: [Summary] -√ Go-to-Market Strategy: [Clear approach] -``` - -These become your baseline KPIs. - ---- - -## What NOT to Do - -❌ **Don't pitch too hard** -- Interviews are for listening, not selling -- If they're interested, they'll ask for more - -❌ **Don't overcommit** -- "We can integrate with anything" - No, be honest -- "We can do custom features" - Not in MVP - -❌ **Don't ask leading questions** -- "You have problems with meter reading, right?" (Yes) -- Better: "Walk me through your process" (more honest) - -❌ **Don't ignore red flags** -- "Maybe next year" = Not a hot lead -- Lukewarm interest is not enough - -❌ **Don't over-engineer based on feedback** -- "We'd want X, Y, Z features" -- Don't add them to MVP - they add time/cost -- Just build #1 really well - ---- - -## Success Looks Like - -✅ You have 5+ Hot Leads wanting to pilot -✅ You have 3+ Letters of Intent (LOI) -✅ You understand the real problem deeply -✅ You have clear competitive positioning -✅ You know your Unit Economics (€15-30K CAC, €80-120K ACV) -✅ You're confident in 20%+ adoption rates -✅ You can articulate WHY Stadtwerke need this - -If you have all of this, you're ready to build. - ---- - -**Document Status:** Ready to execute -**Time to Complete:** 3-4 weeks -**Output:** GO/NO-GO + 5+ pilot customers (if GO) diff --git a/detailed_use_cases.md b/detailed_use_cases.md deleted file mode 100644 index ce22c21..0000000 --- a/detailed_use_cases.md +++ /dev/null @@ -1,458 +0,0 @@ -# DETAILLIERTE USE CASES UND SZENARIEN - -## SCHMERZEN AUS DER PRAXIS - -### 1. ZÄHLERABLESUNG - Kundenbeispiel - -**Persona: Anna Mueller, 45 Jahre, Hamburg** - -**Szenario - PROBLEM:** -- Anna erhält am 3. Januar ein Schreiben: "Bitte Zählerstand mitteilen bis 15. Januar" -- Sie macht ein Foto ihres Meters, schreibt aber versehentlich 245821 statt 248521 -- 3 Wochen später: Stadtwerke Hamburg schickt ihr eine Korrekturrechnung: -450 EUR -- Sie ist verwirrt: "Wieso so viel Rückzahlung?" → Anruf Kundenservice -- Wartezeit: 35 Minuten -- Mitarbeiter: "Das ist wahrscheinlich eine Fehlablesung gewesen, wir müssen nachrecherchieren" -- Auflösung: 10 Tage später Bestätigung -- **Zeitaufwand für Anna:** 2h (Anrufen, Mailen, Nachdenken) -- **Kosten für Stadtwerke:** 50 EUR (Bearbeitungszeit) + Verwaltungsaufwand - -**Lösung - SmartMeter-Lite:** -``` -Tag 1: Anna nimmt Foto des Meters -→ App erkennt automatisch: 248521 -→ Verifikation: "Stimmt das?" → Ja/Nein -→ Bestätigung an Stadtwerke - -Benefit für Anna: -- Schnell (30 Sekunden) -- Sicher (OCR prüft auf Fehler) -- Transparent (Sofortige Bestätigung) - -Benefit für Stadtwerke: -- 95% weniger Fehler -- 80% weniger Serviceanfragen -- Automatische Verarbeitung -``` - ---- - -### 2. ABSCHLAGSRECHNUNG - Kundenbeispiel - -**Persona: Klaus Schmidt, 67 Jahre, München** - -**Szenario - PROBLEM:** -``` -Abschlagsrechnung Januar 2024: 189 EUR/Monat -Klaus denkt: "Das ist ja viel mehr als letztes Jahr (143 EUR)" - -Er versucht, die Rechnung zu verstehen: -- Arbeitspreis: 0,4827 EUR/kWh (was ist normal?) -- Grundgebühr: 12,45 EUR/Monat (wozu?) -- Netzentgelt: 8,37 EUR/Monat (was ist das?) -- Konzessionsabgabe: 2,19 EUR/Monat -- Energiesteuer: 5,00 EUR/Monat -- MwSt: 21.1 EUR - -Ergebnis: Klaus versteht nichts! - -Nächster Schritt: Telefonanruf Stadtwerke München -Wartezeit: 22 Minuten -Kundenservicemitarbeiter erklärt eine Stunde lang alle Gebühren -Klaus' Missverständnis: "Aber wieso wird es teurer, wenn ich weniger verbrauche?" -Antwort: "Wegen der gestiegenen Strompreise, die haben sich verdoppelt" -Klaus: "Warum teilt ihr mir das nicht vorher mit?" - -Resultat: Klaus ist verärgert, beschwert sich per Mail -(nie beantwortet) -``` - -**Lösung - AbschlagAssistant:** -``` -Schritt 1: Klaus loggt sich ein -Schritt 2: "Mein Abschlag ist zu hoch" → Klick -Schritt 3: System zeigt interaktive Erklärung: - -VISUELLES DASHBOARD: -┌─────────────────────────────────────┐ -│ Ihre Abschlagsrechnung erklärt │ -├─────────────────────────────────────┤ -│ Stromverbrauch: 45 kWh × 0,4827 = 21,72 EUR -│ Grundgebühr (Monatlich): 12,45 EUR -│ Netzentgelt: 8,37 EUR -│ Steuern & Abgaben: 18,19 EUR -│ ───────────────────────────────────── -│ TOTAL ABSCHLAG: 189,00 EUR/Monat -└─────────────────────────────────────┘ - -VERGLEICH ZUM VORJAHR: -Dezember 2023: 143 EUR -Dezember 2024: 189 EUR (+32%) - -WARUM? -- Strompreis +18% (2023→2024) -- Dein Verbrauch war gleichbleibend -- Gas-Anteile: +15% Kosten - -MÖGLICHE MASSNAHMEN: -- Abschlag reduzieren auf 165 EUR? (→ Nachzahlung im März) -- Abschlag halten? (→ Rückzahlung zu erwarten) -- Sparmassnahmen? (→ Tipps siehe unten) - -[ABSCHLAG ÄNDERN BUTTON] -``` - -**Benefits für Klaus:** -- Versteht jetzt warum die Rechnung höher ist -- Kann selbst entscheiden, wie sein Abschlag aussieht -- Keine Warteschlange, keine Missverständnisse - -**Benefits für Stadtwerke München:** -- 50% weniger Anrufe zu Abschlag -- Klaus ist jetzt zufriedener (NPS +20) -- Weniger Beschwerdebriefe - ---- - -### 3. ENTSTÖRUNG (Stromausfall) - Kundenbeispiel - -**Persona: Familie Bergmann, 3 Kinder, Berlin** - -**Szenario - PROBLEM:** -``` -Mittwoch 14:30 Uhr: Plötzlich ist der Strom weg! - -Familie Bergmann: -- Kinder können keine Hausaufgaben machen -- Mutter macht sich Sorgen um den Gefrierschrank (Essen) -- Vater ruft Berliner Wasserbetriebe an - -HOTLINE: -Wartezeit: 15 Minuten -Die Ansage sagt: "Aktuelle Wartezeit: 25 Minuten" - -Nach 25 Minuten: -Kundenservicemitarbeiter: "Ja, wir haben einen Ausfall in Ihrem Gebiet" -Familie: "Wann ist der behoben?" -Mitarbeiter: "Ich weiß es nicht, wahrscheinlich in 2-3 Stunden" -Familie: "Was kann ich tun?" -Mitarbeiter: "Nichts, warten Sie" - -Resultat: -- Lebensmittel verderben -- Kinder sind frustriert -- Familie wartet 4 Stunden ohne Updates -- Techniker kommt um 18:45, behebt um 19:00 -- Familie hat Strom um 19:15 wieder (fast 5 Stunden ohne Update) -``` - -**Lösung - OutageAlert Pro:** - -``` -TIMELINE: -14:30 Uhr - Stromausfall - ↓ -14:32 - OutageAlert erkennt Ausfall automatisch - ↓ -14:33 - Familie Bergmann erhält SMS: - "⚠️ Stromausfall in Ihrem Gebiet - Bezirk Mitte, Prenzlauer Berg - Ursache: Schaden an Leitung - ETA: 17:30 Uhr - Live-Status: [LINK]" - ↓ -14:35 - Familie öffnet App/Website - LIVE MAP zeigt: - - Rote Zone = Betroffenes Gebiet - - Grüne Zone = Funktionierend - - Status: 156 Haushalte betroffen - - Techniker auf dem Weg (ETA: 15:15) - ↓ -15:10 - SMS Update: "Techniker vor Ort, arbeitet an der Behebung" - App aktualisiert: Status = "In Bearbeitung" - ETA neu: 16:30 Uhr - ↓ -16:25 - SMS: "Problem behoben, Stromzuführung wird hergestellt" - App: Status = "Wiederherstellung läuft" - ↓ -16:35 - Strom ist wieder da! - SMS: "Ihr Strom ist wieder da. Berichtet ist ok?" - [LINK zu Feedback-Formular] - -RESULTAT: -- Familie weiß immer Bescheid -- Keine frustrierenden Anrufe -- Transparenz = Vertrauen -- Weniger Ängstlichkeit/Besorgnis - -BENEFIT METRIKEN: -- Hotline-Anrufe: -65% -- Zufriedenheit bei Ausfällen: +75% -- Vertrauen in Stadtwerk: +50% -``` - ---- - -### 4. KUNDENSERVICE - Kundenbeispiel - -**Persona: Sabine Weber, 52 Jahre, Köln** - -**Szenario - PROBLEM:** - -``` -Montag 09:00 - Sabine hat eine Frage zu ihrer Rechnung -Sie versucht verschiedene Kanäle: - -VERSUCH 1: Telefon -Hotline: "Alle Mitarbeiter sind beschäftigt. Wartezeit: 32 Minuten" -Sabine wartet 32 Minuten, wird dann durchgestellt -Support: "Hallo, worum geht es?" -Sabine erklärt ihr Problem (2 Minuten) -Support: "Das ist eine gute Frage, ich muss das checken" -Support recherchiert (5 Minuten) -Support: "Ich bin mir nicht sicher. Lassen Sie mich das weiterleiten" -Sabine muss aufgelegt und wird später angerufen -Resultat: Mittwoch 14:00 Rückruf, aber Sabine ist nicht erreichbar - -VERSUCH 2: E-Mail -Sabine schreibt eine E-Mail Freitag 19:00 -Montagmorgen 09:00 Antwort: "Vielen Dank für Ihre Frage. Wir kümmern uns darum." -Donnerstagabend: Inhaltliche Antwort kommt: "Ihre Gebühren wurden korrekt berechnet" -Sabine: "Aber warum wurde ich nicht gefragt??" - -RESULTAT: -- 6 Tage Wartezeit -- Keine zufriedenstellende Antwort -- Fühlt sich ignoriert -- Schreiben 1-Stern-Bewertung online - -NET PROMOTER SCORE: -50 (sehr unzufrieden) -``` - -**Lösung - Kundenservice 360:** - -``` -TIMELINE: - -Montag 09:00 - Sabine öffnet Website -Sie sieht einen Chat-Button "Fragen? Wir helfen!" - -Montag 09:05 - Sabine chattet: -"Warum ist meine Rechnung diesen Monat 45 EUR teurer?" - -Bot versteht die Frage und antwortet SOFORT (< 3 Sekunden): -"Hallo Sabine! 👋 - -Ihre Rechnung ist teurer wegen: -1. Strompreiserhöhung (ab Januar +18%) -2. Abschlag erhöht (angepasst an höheren Verbrauch) - -Weitere Infos? → [LINK zu Erklär-Video] - -Hilft das weiter? -- Ja, danke! -- Nein, ich habe mehr Fragen -- Möchte mit Mitarbeiter sprechen" - -Sabine: "Nein, ich habe mehr Fragen" - -Bot: "Gerne! Welche?" - -Sabine: "Kann ich meinen Abschlag senken?" - -Bot: "Ja! Sie können über unser Portal den Abschlag ändern. -Falls Sie nicht sicher sind, hier ist eine Anleitung: [VIDEO] - -Oder möchten Sie einen echten Mitarbeiter sprechen? -(Wartezeit: 2 Minuten)" - -Sabine: "Ja, bitte mit Mitarbeiter" - -Bot: "Sehr gerne. Ein Mitarbeiter nimmt sich Ihrer an. -Hier ist eine Ticketnummer für Ihre Nachverfolgung: #456789" - -WARTESCHLANGE: -[Ticket-Info wird an Mitarbeiter übertragen] -- Kundenname: Sabine Weber -- Chathistorie: (Vollständig sichtbar) -- Thema: Abschlag zu hoch -- Situation: Verstanden, braucht Beratung - -Mitarbeiter: "Hallo Sabine, ich bin Marco. Ich habe unseren Chat gelesen. -Lass mich dir schnell zeigen, wie du dich einen optimalen Abschlag berechnest..." - -RESULTAT: -- Sabine bekommt innerhalb von 2 Minuten erste Antwort (Bot) -- Bei komplizierten Fragen: Max. 2 Minuten Wartezeit -- Mitarbeiter hat vollständigen Kontext -- Ticket wird automatisch verfolgt -- NPS: +80 (sehr zufrieden) - -BONUS - Automatische Follow-Up: -Dienstag 10:00 - E-Mail an Sabine: -"Danke für das Gespräch gestern! -Wir haben deinen Abschlag auf 165 EUR gesenkt. -Neue Rechnung: [PDF] - -Rückmeldung zur Lösung: -- Geholfen? [JA] [NEIN] [NEUTRAL] -- Zufrieden mit Service? [⭐⭐⭐⭐⭐]" - -Sabine: [JA] + [⭐⭐⭐⭐⭐] -``` - ---- - -### 5. ABRECHNUNG & RECHNUNGSVERSTÄNDNIS - Kundenbeispiel - -**Persona: Hans Mueller, 68 Jahre, Düsseldorf** - -**Szenario - PROBLEM:** - -``` -Hans erhält seine Jahresabrechnung. -Rückerstattung: 312 EUR - -Hans ist verwirrt: -"Wieso geben mir die Stadtwerke Geld zurück?" - -Die Rechnung (1 Seite, klein gedruckt): -- Verbrauch: 4.203 kWh -- Arbeitspreis 0,4827 EUR/kWh = 2.030 EUR -- Grundgebühr: 149,40 EUR -- Netzentgelt: 100,44 EUR -- Konzessionsabgabe: 26,28 EUR -- Energiesteuer: 60,00 EUR -- MwSt: 209,01 EUR -- Abschlagszahlungen: 2.667,00 EUR (12 × 222,25 EUR) -- DIFFERENZ: -312 EUR (Guthaben) - -Hans: "Ok, also habe ich zu viel bezahlt. Aber WARUM? -Mein Verbrauch ist normal, die Preise auch..." - -Hans schaut auf die Rechnung: Keine Erklärung. -Hans ruft Düsseldorf Stadtwerke an. -Wartezeit: 18 Minuten -Support: "Ihre Abschlagsrechnungen waren zu hoch geschätzt" -Hans: "Aber wie hätte ich das wissen können? Ihr hättet mir doch sagen können!" -Support: "Ja, aber das ist schwierig automatisch abzurechnen" -Hans: "Das ist euer Job, oder?" -Supportmitarbeiter: *unbeholfen* "Ja, entschuldigen Sie" - -RESULTAT: -- Hans ist verärgert -- Er vertraut den Stadtwerken nicht mehr -- Nächstes Jahr wird er selbst kontrollieren wollen -- 1-Stern-Bewertung online -``` - -**Lösung - RechnungsAnalyzer+:** - -``` -Hans erhält SMS am Tag der Rechnungstellung: -"Ihre Jahresabrechnung ist online. Sie erhalten 312 EUR Guthaben. -Hier ist die Erklärung: [LINK]" - -Hans klickt den Link: - -RECHNUNG ERKLÄRT -═════════════════════════════════════════════════════ - -IHRE VERBRAUCHSENTWICKLUNG -┌────────────────────────────────┐ -│ 2023: 4.203 kWh (Baseline) │ -│ 2024: 4.187 kWh (-16 kWh) │ -│ Veränderung: -0.4% │ -└────────────────────────────────┘ - -KOSTENAUFSCHLÜSSELUNG -┌────────────────────────────────┐ -│ Arbeitspreis: 2.030 EUR │ -│ Netzentgelt: 100 EUR │ -│ Grundgebühr: 149 EUR │ -│ Steuern/Abgaben: 252 EUR │ -│ ───────────────────────────────── -│ GESAMTKOSTEN: 2.531 EUR │ -│ IHRE ZAHLUNG: 2.667 EUR │ -│ ───────────────────────────────── -│ GUTHABEN: 312 EUR │ -└────────────────────────────────┘ - -WARUM GUTHABEN? -Du hast im Schnitt 222,25 EUR pro Monat abgeschlagen. -Deine tatsächlichen Kosten waren nur 210,92 EUR/Monat. -Differenz: 11,33 EUR × 12 Monate = 136 EUR -+ Einsparungen durch weniger Verbrauch = 176 EUR -= Gesamt Guthaben: 312 EUR ✓ - -AKTION: -[Guthaben auszahlen (ca. 5-7 Tage)] -[In nächsten Abschlag verrechnen] -[Abschlag anpassen (neu: 210 EUR/Monat)] -[Als Spende an lokale Umweltprojekte] - -VERGLEICH ZUM VORJAHR -2023 Guthaben: 89 EUR -2024 Guthaben: 312 EUR (+250%) - -Das ist höher als normal. Wir haben es überprüft: -→ Dein Verbrauch ist gleich -→ Aber Strom war günstiger diesen Sommer -→ Du hast richtig gespart! 🎉 - -WOLLEN SIE IHREN ABSCHLAG ÄNDERN? -Empfohlen: 195 EUR/Monat (statt 222,25 EUR) -[JA, ÄNDERN] -``` - -**Benefits für Hans:** -- Er versteht jetzt warum das Guthaben -- Er sieht, dass er Energie spart -- Transparenz schafft Vertrauen -- Er wird sogar zufriedener mit den Stadtwerken! -- NPS: +60 (vorher -20) - -**Benefit für Düsseldorf Stadtwerke:** -- 200+ Serviceanfragen pro Monat zu Rückerstattungen → 80% gespart -- Hans wird Fan der Stadtwerke (Word-of-Mouth) -- Weniger Reklamationen (-40%) - ---- - -## ZUSAMMENFASSUNG: EMOTIONALE IMPACT - -| Use Case | Vorher | Nachher | -|----------|--------|---------| -| **Zählerablesung** | 😤 Fehlerhafte Ablesungen, Frustration | 😊 Sicher, schnell, transparent | -| **Abschlag** | 😠 Verwirrung, Unverständnis | 😌 Durchschaubar, kontrollierbar | -| **Entstörung** | 😨 Angst, Ungewissheit | 😊 Informiert, vertrauensvoll | -| **Support** | 😤 Lange Wartezeiten, frustriert | 😄 Schnelle Hilfe, verstanden | -| **Abrechnung** | 😕 Komplex, Misstrauen | 😌 Klar, transparent, zufrieden | - -**Durchschnittlicher NPS-Lift:** +70 Punkte -**Durchschnittliche Kundenzufriedenheit:** +45% - ---- - -## MESSBARE BUSINESS OUTCOMES - -### Für Stadtwerke - -| KPI | Baseline | Mit Lösung | Impact | -|-----|----------|-----------|--------| -| Hotline Anrufe/Monat | 2.500 | 800 | -68% | -| Avg. Response Time | 45 min | 2 min | -95% | -| Abrechnungsbeschwerde | 280 | 45 | -84% | -| Churn Rate (monatlich) | 2.8% | 2.1% | -25% | -| NPS | 28 | 65 | +37 Punkte | -| Support Kostenersparnis | - | 450K EUR/Jahr | - | - -### Für Endkunden - -| Vorteil | Quantitativ | -|--------|------------| -| Zeit gespart (jährlich) | 4-6 Stunden | -| Besseres Verständnis | 85% vs. 35% | -| Zufriedenheit | +45% | -| Vertrauen in Stadtwerk | +60% | -| Energiekostenersparnis | 8-12% (durch bessere Einsicht) | diff --git a/implementation_roadmap.md b/implementation_roadmap.md deleted file mode 100644 index fd0c144..0000000 --- a/implementation_roadmap.md +++ /dev/null @@ -1,552 +0,0 @@ -# IMPLEMENTIERUNGS-ROADMAP: Deutsche Stadtwerke Software-Lösungen - -## EXECUTIVE SUMMARY - -Diese Roadmap beschreibt die Umsetzung von 5 hochprioritt Softwarelösungen für deutsche Stadtwerke, um ihre größten Pain Points zu adressieren. Die Gesamtmarktmöglichkeit wird auf **10-25 Millionen EUR** in den nächsten 3 Jahren geschätzt. - ---- - -## I. PROJEKT-TIMELINE (Gesamtdauer: 6 Monate) - -### PHASE 1: DISCOVERY & VALIDATION (Woche 1-3) - -#### 1.1 Stakeholder-Interviews -**Ziel:** Requirements und Pain Points validieren - -**Zu befragende Stakeholder:** -- Stadtwerk-Manager (Kundenservice, IT, Geschäftsführung) - 10 Interviews -- Endkunden (verschiedene Demografie) - 20 Interviews -- Support-Mitarbeiter (um echte Schmerzen zu verstehen) - 8 Interviews - -**Interview-Guide Beispiele:** - -``` -Für Stadtwerk-Manager: -1. Welche sind Ihre Top 3 Kundenservice-Probleme? -2. Wie viele Anrufe/E-Mails pro Tag zu Zählerablesung? -3. Was kostet Sie die manuelle Zählerablesung pro Jahr? -4. Haben Sie ein bestehendes Ticketing-System? -5. Welche technischen Systeme sind im Einsatz? (SAP, Oracle, etc.) - -Für Endkunden: -1. Was ist Ihr größtes Problem mit Ihrer Stadtwerk? -2. Wie oft rufen Sie an oder mailen wegen Abrechnung? -3. Verstehen Sie Ihre Rechnung vollständig? -4. Würden Sie eine App nutzen für Zählerablesung? (Was kostet's?) -``` - -**Deliverable:** Research-Report mit Top 10 Anforderungen - -#### 1.2 Marktforschung -- Konkurrenzanalyse (ähnliche Lösungen, Preise, Features) -- Benchmarking gegen europäische Stadtwerke (Wien, Zürich, Amsterdam) -- Regulatory Landscape (DSGVO, BSI-Anforderungen) - -**Deliverable:** Competitive Intelligence Report - -#### 1.3 Prototyping -- Low-Fidelity Wireframes für Top 3 Pain Points -- Interactive Prototypes (Figma) -- User Testing Sessions (5-10 Kunden) - -**Deliverable:** Design-System & Prototype Library - -**Budget Phase 1:** 25.000 - 35.000 EUR - ---- - -### PHASE 2: MVP-ENTWICKLUNG PRIORITÄT 1 (Woche 4-9) - -#### 2.1 Projekt: SmartMeter-Lite App (Pain Point #1) - -**Sprint 0-1 (Woche 4-5): Setup & Architektur** -- [ ] Development Environment Setup -- [ ] CI/CD Pipeline (GitHub Actions / GitLab CI) -- [ ] Database Schema Design (PostgreSQL) -- [ ] API Specification (OpenAPI/Swagger) -- [ ] Security Architecture Review (OWASP Top 10) - -**Tech-Stack Decision:** -``` -Frontend: -- React Native (iOS + Android) -- or Flutter (Alternative) -- State Management: Redux / MobX -- UI Library: React Native Paper / Material Design - -Backend: -- Node.js + Express / Fastify -- or Python + FastAPI -- Authentication: JWT + OAuth2 -- Database: PostgreSQL 13+ -- Caching: Redis - -ML/OCR: -- TensorFlow Lite (Mobile) -- or Tesseract (Open Source) -- Cloud Option: Google Vision API / Azure Computer Vision -``` - -**Sprint 1-2 (Woche 5-6): OCR-Integration** -- [ ] OCR Model Selection & Testing - ``` - Task: Test 3 OCR Optionen - 1. Google Vision API ($$, best accuracy) - 2. Tesseract (Free, 80% accuracy) - 3. AWS Textract ($, good balance) - - Evaluation: Accuracy, Latency, Cost - ``` -- [ ] Training Data Collection (100+ Meter Bilder) -- [ ] OCR Pipeline Development -- [ ] Error Handling & User Feedback Loop - -**Sprint 2-3 (Woche 6-7): Backend Development** -- [ ] User Authentication API -- [ ] Meter Reading CRUD API -- [ ] Consumption Analytics API -- [ ] Notification Service (Push, SMS, Email) -- [ ] Database Migrations & Backups - -**Sprint 3-4 (Woche 7-8): Mobile App Development** -- [ ] Auth Screen (Login, Registration, Password Reset) -- [ ] Camera Integration & Photo Upload -- [ ] Dashboard with Consumption Charts -- [ ] History & Reporting -- [ ] Settings & Notifications -- [ ] Testing (Unit + Integration + E2E) - -**Sprint 4 (Woche 8-9): Integration & Testing** -- [ ] Backend Integration Tests -- [ ] API Gateway & Rate Limiting -- [ ] Performance Testing -- [ ] Security Testing (Penetration Test) -- [ ] User Acceptance Testing (UAT) mit 10-20 Beta Usern - -**Deliverable:** -- Produktionsreife iOS + Android App -- REST API mit Dokumentation -- Dashboard für Admin/Stadtwerk -- Beta User Feedback & Metrics - -**Team & Budget Phase 2:** -- 1 Frontend Lead -- 2 React Native Entwickler -- 1 Backend Lead -- 1 Python Developer (ML/OCR) -- 1 QA Engineer -- Budget: 60.000 - 100.000 EUR - ---- - -### PHASE 2B: MVP-ENTWICKLUNG PRIORITÄT 2 (Parallel, Woche 4-9) - -#### 2.2 Projekt: AbschlagAssistant Web-Tool (Pain Point #2) - -**Sprint 0-1 (Woche 4-5): Requirements & Design** -- [ ] Tariff Data Model Design -- [ ] Calculation Rules Definition -- [ ] UI/UX Design (Figma) -- [ ] API Specification - -**Sprint 1-2 (Woche 5-6): Backend Development** -- [ ] Rule Engine Implementation (Drools / Easy Rules) -- [ ] Tariff Database (PostgreSQL) -- [ ] Calculation Engine (Node.js) -- [ ] Scenario Simulation API - -**Sprint 2-3 (Woche 6-7): Frontend Development** -- [ ] Abschlag-Simulator Interface -- [ ] Transparency Dashboard -- [ ] What-If Scenarios -- [ ] Historical Comparisons - -**Sprint 3-4 (Woche 8-9): Integration & Launch** -- [ ] Backend Integration -- [ ] Testing & Optimization -- [ ] UAT mit Stadtwerken - -**Deliverable:** -- Web-based Abschlag-Simulator -- Admin Dashboard -- Integration Documentation - -**Team & Budget Phase 2B:** -- 1 Fullstack Developer -- 1 Rule Engine Specialist -- 1 QA Engineer -- Budget: 40.000 - 60.000 EUR - -**Total Phase 2 Budget:** 100.000 - 160.000 EUR - ---- - -### PHASE 3: SCALE & PHASE 2 LÖSUNGEN (Woche 10-16) - -#### 3.1 Projekt: OutageAlert Pro (Pain Point #3) - -**Timeline: 10-14 Wochen** - -**Architektur:** -``` -Frontend: -- Website (React) -- Mobile App (React Native) -- Real-time Updates (WebSocket) - -Backend: -- Node.js / Go -- Real-time Server (Socket.io / SignalR) -- Mapping Service (Mapbox) -- SCADA Integration Layer - -Database: -- PostgreSQL (Primary) -- Redis (Real-time Cache) -- InfluxDB (Metrics) - -Integrations: -- Twilio (SMS/WhatsApp) -- Firebase Cloud Messaging -- SCADA Systems (Modbus, IEC 60870-5-104) -``` - -**Key Features:** -1. Live Outage Map -2. Automated Notifications (SMS, Push, Email) -3. Technician Tracking & ETA -4. Incident Reporting System -5. Analytics & Predictive Maintenance - -**Development Steps:** -- Week 1-2: System Integration & SCADA Connection -- Week 3-4: Real-time Infrastructure (WebSocket, Caching) -- Week 5-6: Frontend (Website + App) -- Week 7-8: Notification Service -- Week 9-10: Technician App & Tracking -- Week 11-12: Analytics & Machine Learning (Outage Prediction) -- Week 13-14: Testing & Deployment - -**Team:** 2 Backend, 2 Frontend, 1 DevOps, 1 QA - -**Budget: 120.000 - 180.000 EUR** - -#### 3.2 Projekt: Kundenservice 360 (Pain Point #4) - -**Timeline: 12-16 Wochen** - -**Architecture:** -``` -Chatbot & NLP: -- Rasa / OpenAI GPT -- Intent Recognition -- Entity Extraction -- Multi-Language Support - -Support Ticketing: -- Custom Built oder Zendesk Integration -- Workflow Automation (Zapier) -- Knowledge Base Management - -Integration Connectors: -- Website Chat -- WhatsApp Business API -- Email (Gmail, Office 365) -- SMS (Twilio) -- Phone (Asterisk / FreePBX) - -Analytics: -- Customer Satisfaction (CSAT) -- First Response Time -- Resolution Time -- Agent Performance Metrics -``` - -**Development Steps:** -- Week 1-2: Chatbot Training Data Collection -- Week 3-5: Chatbot Development & Training -- Week 6-7: Ticketing System -- Week 8-9: Multi-Channel Integrations -- Week 10-11: Knowledge Base & Analytics -- Week 12-14: Agent Tools & Dashboard -- Week 15-16: Testing & Deployment - -**Team:** 2 ML Engineers (Chatbot), 2 Backend, 2 Frontend, 1 QA - -**Budget: 150.000 - 220.000 EUR** - -#### 3.3 Projekt: RechnungsAnalyzer+ (Pain Point #5) - -**Timeline: 10-14 Wochen** - -**Architecture:** -``` -Frontend: -- React Dashboard -- Mobile App -- PDF Viewer - -Backend: -- OCR Service (Tesseract / Azure) -- Bill Parser -- Payment Gateway Integration -- Analytics Engine - -Integrations: -- Payment Providers (Stripe, Adyen, Paypal) -- Email Integration -- PDF Processing (pdfkit) -- Accounting Systems (SAP, Oracle) -``` - -**Features:** -1. Digital Bill Archive with OCR Indexing -2. Visual Bill Explanation -3. Consumption Trend Analysis -4. Flexible Payment Options -5. Automated Payment Plans -6. Anomaly Detection -7. Export Tools (PDF, CSV) -8. Dispute Management - -**Development Steps:** -- Week 1-2: Bill Parsing & OCR Integration -- Week 3-5: Dashboard Development -- Week 6-7: Analytics Engine -- Week 8-9: Payment Integration -- Week 10-11: Archive & Export Tools -- Week 12-13: Mobile App -- Week 14: Testing & Deployment - -**Team:** 2 Backend, 2 Frontend, 1 Data Scientist, 1 QA - -**Budget: 140.000 - 200.000 EUR** - -**Total Phase 3 Budget: 410.000 - 600.000 EUR** - ---- - -## II. ORGANISATION & TEAM - -### Empfohlene Größe Entwicklungsteam - -**Für MVP (Phase 1-2): 8-10 Personen** -- 1 Product Manager / Scrum Master -- 1 UX/UI Designer -- 2 Full-Stack / Frontend Developer -- 2 Backend Developer -- 1 ML/AI Specialist (OCR) -- 1 DevOps / Infrastructure -- 1 QA Engineer -- 1 Product Owner - -**Für Scale (Phase 3): 15-18 Personen** -- +3 Backend Developer -- +2 Frontend Developer -- +1 Senior Architect -- +1 Security Engineer -- +1 Solutions Engineer (für B2B Sales Support) - -### Organisationsmodell: Agile/Scrum - -**Sprint Duration:** 1 Woche (für schnelle Iteration) - -**Ceremonies:** -- Daily Standup: 15 min (9:00 AM) -- Sprint Planning: 2h (Montags) -- Backlog Refinement: 1h (Mi) -- Sprint Review/Demo: 1.5h (Freitags) -- Retrospective: 1h (Freitags) - ---- - -## III. TECH STACK EMPFEHLUNG - -### Frontend -``` -Web: -- React 18+ / Vue 3 -- TypeScript -- TailwindCSS / Material-UI -- State: Redux Toolkit / Pinia -- Testing: Jest + React Testing Library - -Mobile: -- React Native / Flutter -- TypeScript -- Navigation: React Navigation / GetX -- State: Redux / Provider -``` - -### Backend -``` -Language: Node.js + TypeScript / Python -Framework: Express / Fastify (Node) oder FastAPI (Python) -Authentication: JWT + OAuth2 (Google, Microsoft) -Database: PostgreSQL 13+ -Caching: Redis -Message Queue: RabbitMQ / Kafka -API Documentation: Swagger/OpenAPI -``` - -### Infrastructure -``` -Cloud: AWS / Azure / GCP -Containerization: Docker -Orchestration: Kubernetes (EKS/AKS/GKE) -CI/CD: GitHub Actions / GitLab CI -Monitoring: DataDog / New Relic / Prometheus -Logging: ELK Stack / Cloudwatch -``` - -### Security -``` -- OWASP Top 10 Compliance -- Encryption: TLS 1.3, AES-256 at rest -- Authentication: 2FA / MFA -- API Rate Limiting & DDoS Protection -- Penetration Testing (quarterly) -- Bug Bounty Program -- DSGVO Compliance (Privacy by Design) -``` - ---- - -## IV. GO-TO-MARKET STRATEGIE - -### Phase 1: Direct Sales an Stadtwerke - -**Target Profile:** -- Stadtwerke mit 100.000+ Kundenbasis -- Annual Revenue > 100 Mio EUR -- Bereits digitalisierungsorientiert - -**Top 20 Target Accounts:** -1. Stadtwerke München -2. Stadtwerke Berlin -3. Stadtwerke Köln -4. Stadtwerke Hamburg -5. Stadtwerke Stuttgart -6. Stadtwerke Düsseldorf -7. Stadtwerke Frankfurt -8. Stadtwerke Dortmund -9. Stadtwerke Essen -10. Stadtwerke Leipzig -... (weitere 10) - -**Sales Strategie:** -- **Inbound:** Content Marketing, Thought Leadership, Webinars -- **Outbound:** Executive Outreach (VP IT, VP Customer Service) -- **Partnership:** Zusammenarbeit mit Verbänden (VKU - Verband Kommunaler Unternehmen) - -**Sales Cycle:** 60-90 Tage (für komplexere Integrationen) -**Deal Size:** 50.000 - 300.000 EUR (ACV) - -### Phase 2: Partnership mit Integratoren - -- SAP/Oracle Implementation Partner -- Telekommunikations-Provider (Deutsche Telekom, Vodafone) - -### Phase 3: B2C/Direct-to-Consumer - -- App Store Optimization (ASO) -- Organic Social Media -- Influencer Partnerships (Energiespartipps) - ---- - -## V. REVENUE PROJECTIONS - -### Szenario A: Conservative (30% Market Penetration) - -**Year 1 (6 Monate Post-Launch):** -- Pain Point #1 (SmartMeter): 5 Stadtwerke × 80K = 400K EUR -- Pain Point #2 (Abschlag): 8 Stadtwerke × 60K = 480K EUR -- **Total Y1:** 880K EUR (+ recurring: 50K/month baseline) - -**Year 2:** -- Installed Base: 30 Stadtwerke -- Average Contract Value: 120K EUR/year -- **Total Y2:** 3.6M EUR - -**Year 3:** -- Installed Base: 60 Stadtwerke -- **Total Y3:** 7.2M EUR - -### Szenario B: Aggressive (50% Market Penetration) - -**Year 1:** 2.0M EUR -**Year 2:** 8.0M EUR -**Year 3:** 15.0M EUR - -### Szenario C: B2C Additional Revenue - -**B2C Premium Feature (optional):** -- 500K early adopters × 2 EUR/month = 12M EUR annual run-rate (Year 3) - ---- - -## VI. RISIKEN & MITIGATION - -### Risiko #1: Lange Sales Cycles -**Mitigation:** Freemium-Modell für Endkunden, Proof-of-Concepts mit schnellen ROI-Demonstrationen - -### Risiko #2: Integration mit Legacy Systemen -**Mitigation:** Dediziertes Integration Team, API-Wrapper für alte Systeme, Fallback-Szenarien - -### Risiko #3: Regulatorische/Compliance Anforderungen -**Mitigation:** Early DSGVO/BSI-Audits, Legal Review, Compliance Budget +20% - -### Risiko #4: Technische Schulden -**Mitigation:** Agile Development mit regelmäßigen Refactorings, Code Reviews, Tech Debt Tracking - -### Risiko #5: Konkurrenz durch interne IT der Stadtwerke -**Mitigation:** Partnerschaften, weiße Label Lösungen, beste Practices aus vielen Stadtwerken - ---- - -## VII. SUCCESS METRICS - -### Business Metrics -- **ARR (Annual Recurring Revenue):** Ziel: 5M EUR Ende Year 2 -- **Churn Rate:** < 5% pro Jahr -- **NRR (Net Revenue Retention):** > 120% -- **CAC (Customer Acquisition Cost):** < 40K EUR -- **LTV:CAC Ratio:** > 3:1 - -### Product Metrics -- **User Adoption:** > 40% der Endkunden nutzen App innerhalb 6 Monate -- **DAU/MAU:** > 30% MAU sind DAU -- **NPS (Net Promoter Score):** > 50 -- **Feature Usage:** Top Features genutzt von > 80% Users - -### Operational Metrics -- **System Uptime:** > 99.9% -- **Average Response Time:** < 200ms (API) -- **Support Response Time:** < 2h (B2B), < 30min (Incident) -- **Bug Escape Rate:** < 5% (kritisch Bugs in Production) - ---- - -## VIII. BUDGET SUMMARY - -| Phase | Dauer | Budget | -|-------|-------|--------| -| Phase 1: Discovery | 3 Wo. | 25K - 35K | -| Phase 2: MVP Development | 6 Wo. | 100K - 160K | -| Phase 3: Scale | 6 Wo. | 410K - 600K | -| Marketing & Sales (Year 1) | - | 50K - 100K | -| **Total MVP-to-Launch** | **15 Wo.** | **585K - 895K EUR** | - -**Mit Overhead (HR, Admin, Facility):** ~700K - 1.1M EUR für erste 15 Wochen - ---- - -## IX. NEXT IMMEDIATE STEPS (Diese Woche) - -- [ ] Executive Sponsor identifizieren -- [ ] Founding Team zusammenstellen (Leiter Tech, Product, Sales) -- [ ] Investor Meeting vorbereiten (wenn VC-Finanzierung geplant) -- [ ] Erste 3 Stadtwerke für Interviews kontaktieren -- [ ] Development Environment einrichten -- [ ] Tool Selection (Design, Development, Collaboration) diff --git a/innungsapp/.env.example b/innungsapp/.env.example new file mode 100644 index 0000000..07ce7e4 --- /dev/null +++ b/innungsapp/.env.example @@ -0,0 +1,36 @@ +# ============================================= +# DATABASE +# ============================================= +DATABASE_URL="postgresql://postgres:password@localhost:5432/innungsapp" + +# ============================================= +# BETTER-AUTH +# ============================================= +BETTER_AUTH_SECRET="change-me-to-a-random-32-char-string" +BETTER_AUTH_URL="http://localhost:3000" + +# ============================================= +# EMAIL (SMTP for magic links & invitations) +# ============================================= +EMAIL_FROM="noreply@innungsapp.de" +SMTP_HOST="smtp.example.com" +SMTP_PORT="587" +SMTP_SECURE="false" +SMTP_USER="" +SMTP_PASS="" + +# ============================================= +# ADMIN APP (Next.js) +# ============================================= +NEXT_PUBLIC_APP_URL="http://localhost:3000" + +# ============================================= +# MOBILE APP (Expo) +# ============================================= +EXPO_PUBLIC_API_URL="http://localhost:3000" + +# ============================================= +# FILE UPLOADS +# ============================================= +UPLOAD_DIR="./uploads" +UPLOAD_MAX_SIZE_MB="10" diff --git a/innungsapp/.gitignore b/innungsapp/.gitignore new file mode 100644 index 0000000..d6a9c78 --- /dev/null +++ b/innungsapp/.gitignore @@ -0,0 +1,39 @@ +# Dependencies +node_modules +.pnp +.pnp.js + +# Build outputs +.next +dist +build +out + +# Turbo +.turbo + +# Environment +.env +.env.local +.env.production +.env.staging + +# Uploads (local file storage) +apps/admin/uploads/ + +# Prisma +packages/shared/prisma/migrations/ + +# Expo +apps/mobile/.expo +apps/mobile/android +apps/mobile/ios + +# OS +.DS_Store +Thumbs.db + +# Editor +.vscode +.idea +*.swp diff --git a/innungsapp/apps/admin/app/api/auth/[...all]/route.ts b/innungsapp/apps/admin/app/api/auth/[...all]/route.ts new file mode 100644 index 0000000..76286db --- /dev/null +++ b/innungsapp/apps/admin/app/api/auth/[...all]/route.ts @@ -0,0 +1,4 @@ +import { auth } from '@/lib/auth' +import { toNextJsHandler } from 'better-auth/next-js' + +export const { POST, GET } = toNextJsHandler(auth) diff --git a/innungsapp/apps/admin/app/api/trpc/[trpc]/route.ts b/innungsapp/apps/admin/app/api/trpc/[trpc]/route.ts new file mode 100644 index 0000000..0493812 --- /dev/null +++ b/innungsapp/apps/admin/app/api/trpc/[trpc]/route.ts @@ -0,0 +1,23 @@ +import { fetchRequestHandler } from '@trpc/server/adapters/fetch' +import { appRouter } from '@/server/routers' +import { createContext } from '@/server/context' +import { type NextRequest } from 'next/server' + +const handler = (req: NextRequest) => + fetchRequestHandler({ + endpoint: '/api/trpc', + req, + router: appRouter, + createContext: () => createContext({ req, resHeaders: new Headers(), info: {} as never }), + onError: + process.env.NODE_ENV === 'development' + ? ({ path, error }) => { + console.error( + `[tRPC] Error on ${path ?? ''}:`, + error + ) + } + : undefined, + }) + +export { handler as GET, handler as POST } diff --git a/innungsapp/apps/admin/app/api/upload/route.ts b/innungsapp/apps/admin/app/api/upload/route.ts new file mode 100644 index 0000000..7e4f5d5 --- /dev/null +++ b/innungsapp/apps/admin/app/api/upload/route.ts @@ -0,0 +1,54 @@ +import { NextRequest, NextResponse } from 'next/server' +import { writeFile, mkdir } from 'fs/promises' +import path from 'path' +import { randomUUID } from 'crypto' +import { auth } from '@/lib/auth' + +const UPLOAD_DIR = process.env.UPLOAD_DIR ?? './uploads' +const MAX_SIZE_BYTES = Number(process.env.UPLOAD_MAX_SIZE_MB ?? 10) * 1024 * 1024 + +export async function POST(req: NextRequest) { + // Auth check + const session = await auth.api.getSession({ headers: req.headers }) + if (!session?.user) { + return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) + } + + const formData = await req.formData() + const file = formData.get('file') as File | null + + if (!file) { + return NextResponse.json({ error: 'No file provided' }, { status: 400 }) + } + + if (file.size > MAX_SIZE_BYTES) { + return NextResponse.json({ error: 'File too large' }, { status: 413 }) + } + + // Only allow safe file types + const allowedTypes = [ + 'application/pdf', + 'image/png', + 'image/jpeg', + 'image/webp', + 'image/gif', + ] + if (!allowedTypes.includes(file.type)) { + return NextResponse.json({ error: 'File type not allowed' }, { status: 415 }) + } + + const ext = path.extname(file.name) + const fileName = `${randomUUID()}${ext}` + const uploadPath = path.join(process.cwd(), UPLOAD_DIR) + + await mkdir(uploadPath, { recursive: true }) + const buffer = Buffer.from(await file.arrayBuffer()) + await writeFile(path.join(uploadPath, fileName), buffer) + + return NextResponse.json({ + storagePath: fileName, + name: file.name, + sizeBytes: file.size, + url: `/uploads/${fileName}`, + }) +} diff --git a/innungsapp/apps/admin/app/api/uploads/[...path]/route.ts b/innungsapp/apps/admin/app/api/uploads/[...path]/route.ts new file mode 100644 index 0000000..3fdaf0d --- /dev/null +++ b/innungsapp/apps/admin/app/api/uploads/[...path]/route.ts @@ -0,0 +1,41 @@ +import { NextRequest, NextResponse } from 'next/server' +import { readFile } from 'fs/promises' +import path from 'path' + +const UPLOAD_DIR = process.env.UPLOAD_DIR ?? './uploads' + +export async function GET( + req: NextRequest, + { params }: { params: { path: string[] } } +) { + try { + const filePath = path.join(process.cwd(), UPLOAD_DIR, ...params.path) + + // Security: prevent path traversal + const resolved = path.resolve(filePath) + const uploadDir = path.resolve(path.join(process.cwd(), UPLOAD_DIR)) + if (!resolved.startsWith(uploadDir)) { + return new NextResponse('Forbidden', { status: 403 }) + } + + const file = await readFile(resolved) + const ext = path.extname(resolved).toLowerCase() + const mimeTypes: Record = { + '.pdf': 'application/pdf', + '.png': 'image/png', + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.gif': 'image/gif', + '.webp': 'image/webp', + } + + return new NextResponse(file, { + headers: { + 'Content-Type': mimeTypes[ext] ?? 'application/octet-stream', + 'Cache-Control': 'public, max-age=86400', + }, + }) + } catch { + return new NextResponse('Not Found', { status: 404 }) + } +} diff --git a/innungsapp/apps/admin/app/dashboard/einstellungen/page.tsx b/innungsapp/apps/admin/app/dashboard/einstellungen/page.tsx new file mode 100644 index 0000000..1fa5608 --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/einstellungen/page.tsx @@ -0,0 +1,115 @@ +'use client' + +import { trpc } from '@/lib/trpc-client' +import { useState } from 'react' + +export default function EinstellungenPage() { + const { data: org, isLoading } = trpc.organizations.me.useQuery() + const updateMutation = trpc.organizations.update.useMutation() + const avvMutation = trpc.organizations.acceptAvv.useMutation() + + const [name, setName] = useState('') + const [contactEmail, setContactEmail] = useState('') + + if (isLoading) return
Wird geladen...
+ if (!org) return null + + return ( +
+

Einstellungen

+ + {/* Org Settings */} +
+

Innung

+
+ + setName(e.target.value)} + className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500" + /> +
+
+ + setContactEmail(e.target.value)} + className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500" + /> +
+ + {updateMutation.isSuccess && ( +

Einstellungen gespeichert ✓

+ )} +
+ + {/* AVV */} +
+

Auftragsverarbeitungsvertrag (AVV)

+

+ Der AVV regelt die Verarbeitung personenbezogener Daten im Auftrag Ihrer Innung + durch InnungsApp GmbH gemäß Art. 28 DSGVO. +

+ + 📄 AVV als PDF herunterladen + + {org.avvAccepted ? ( +
+

+ ✓ AVV akzeptiert am {org.avvAcceptedAt?.toLocaleDateString('de-DE')} +

+
+ ) : ( +
+

+ ⚠️ Der AVV muss vor dem Go-Live akzeptiert werden. +

+ + +
+ )} +
+ + {/* Plan Info */} +
+

Plan

+ + {org.plan} + +

+ Für Upgrades oder Fragen zum Plan: kontakt@innungsapp.de +

+
+
+ ) +} diff --git a/innungsapp/apps/admin/app/dashboard/layout.tsx b/innungsapp/apps/admin/app/dashboard/layout.tsx new file mode 100644 index 0000000..eff6229 --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/layout.tsx @@ -0,0 +1,18 @@ +import { Sidebar } from '@/components/layout/Sidebar' +import { Header } from '@/components/layout/Header' + +export default function DashboardLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( +
+ +
+
+
{children}
+
+
+ ) +} diff --git a/innungsapp/apps/admin/app/dashboard/mitglieder/neu/page.tsx b/innungsapp/apps/admin/app/dashboard/mitglieder/neu/page.tsx new file mode 100644 index 0000000..6d7b10f --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/mitglieder/neu/page.tsx @@ -0,0 +1,187 @@ +'use client' + +import { useState } from 'react' +import { useRouter } from 'next/navigation' +import { trpc } from '@/lib/trpc-client' +import Link from 'next/link' +import { SPARTEN } from '@innungsapp/shared' + +export default function MitgliedNeuPage() { + const router = useRouter() + const [sendInvite, setSendInvite] = useState(true) + const [form, setForm] = useState({ + name: '', + betrieb: '', + sparte: 'Elektrotechnik', + ort: '', + telefon: '', + email: '', + status: 'aktiv' as const, + istAusbildungsbetrieb: false, + seit: new Date().getFullYear(), + }) + + const createMutation = trpc.members.create.useMutation({ + onSuccess: () => router.push('/dashboard/mitglieder'), + }) + const inviteMutation = trpc.members.invite.useMutation({ + onSuccess: () => router.push('/dashboard/mitglieder'), + }) + + const isPending = createMutation.isPending || inviteMutation.isPending + const error = createMutation.error ?? inviteMutation.error + + function handleSubmit(e: React.FormEvent) { + e.preventDefault() + if (sendInvite) { + inviteMutation.mutate(form) + } else { + createMutation.mutate(form) + } + } + + return ( +
+
+ + ← Zurück + +

Mitglied anlegen

+
+ +
+
+
+ + setForm({ ...form, name: e.target.value })} + className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500" + /> +
+
+ + setForm({ ...form, betrieb: e.target.value })} + className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500" + /> +
+
+ + +
+
+ + setForm({ ...form, ort: e.target.value })} + className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500" + /> +
+
+ + setForm({ ...form, email: e.target.value })} + className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500" + /> +
+
+ + setForm({ ...form, telefon: e.target.value })} + className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500" + /> +
+
+ + setForm({ ...form, seit: Number(e.target.value) })} + min="1900" + max="2100" + className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500" + /> +
+
+ + +
+
+ +
+
+ +
+ +

+ Das Mitglied erhält eine E-Mail mit einem Login-Link. +

+
+ + {error && ( +

+ {error.message} +

+ )} + +
+ + + Abbrechen + +
+
+
+ ) +} diff --git a/innungsapp/apps/admin/app/dashboard/mitglieder/page.tsx b/innungsapp/apps/admin/app/dashboard/mitglieder/page.tsx new file mode 100644 index 0000000..f7f850c --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/mitglieder/page.tsx @@ -0,0 +1,150 @@ +import { prisma } from '@innungsapp/shared' +import { auth } from '@/lib/auth' +import { headers } from 'next/headers' +import { redirect } from 'next/navigation' +import Link from 'next/link' +import { MEMBER_STATUS_LABELS } from '@innungsapp/shared' +import { format } from 'date-fns' +import { de } from 'date-fns/locale' + +const STATUS_COLORS = { + aktiv: 'bg-green-100 text-green-700', + ruhend: 'bg-yellow-100 text-yellow-700', + ausgetreten: 'bg-red-100 text-red-700', +} + +export default async function MitgliederPage({ + searchParams, +}: { + searchParams: { q?: string; status?: string } +}) { + const session = await auth.api.getSession({ headers: await headers() }) + if (!session?.user) redirect('/login') + + const userRole = await prisma.userRole.findFirst({ + where: { userId: session.user.id }, + }) + if (!userRole || userRole.role !== 'admin') redirect('/dashboard') + + const search = searchParams.q ?? '' + const statusFilter = searchParams.status + + const members = await prisma.member.findMany({ + where: { + orgId: userRole.orgId, + ...(statusFilter && { status: statusFilter as never }), + ...(search && { + OR: [ + { name: { contains: search, mode: 'insensitive' } }, + { betrieb: { contains: search, mode: 'insensitive' } }, + { ort: { contains: search, mode: 'insensitive' } }, + ], + }), + }, + orderBy: { name: 'asc' }, + }) + + return ( +
+
+
+

Mitglieder

+

{members.length} Einträge

+
+ + + Mitglied anlegen + +
+ + {/* Filters */} +
+
+ + + +
+
+ + {/* Table */} +
+ + + + + + + + + + + + + + {members.map((m) => ( + + + + + + + + + + ))} + +
Name / BetriebSparteOrtMitglied seitStatusEingeladen
+
+

{m.name}

+

{m.betrieb}

+
+
{m.sparte}{m.ort}{m.seit ?? '—'} + + {MEMBER_STATUS_LABELS[m.status]} + + + {m.userId ? ( + ✓ Aktiv + ) : ( + Nicht eingeladen + )} + + + Bearbeiten + +
+ {members.length === 0 && ( +
+ Keine Mitglieder gefunden +
+ )} +
+
+ ) +} diff --git a/innungsapp/apps/admin/app/dashboard/news/neu/page.tsx b/innungsapp/apps/admin/app/dashboard/news/neu/page.tsx new file mode 100644 index 0000000..6e538da --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/news/neu/page.tsx @@ -0,0 +1,158 @@ +'use client' + +import { useState } from 'react' +import { useRouter } from 'next/navigation' +import { trpc } from '@/lib/trpc-client' +import Link from 'next/link' +import dynamic from 'next/dynamic' + +const MDEditor = dynamic(() => import('@uiw/react-md-editor'), { ssr: false }) + +const KATEGORIEN = [ + { value: 'Wichtig', label: 'Wichtig' }, + { value: 'Pruefung', label: 'Prüfung' }, + { value: 'Foerderung', label: 'Förderung' }, + { value: 'Veranstaltung', label: 'Veranstaltung' }, + { value: 'Allgemein', label: 'Allgemein' }, +] + +export default function NewsNeuPage() { + const router = useRouter() + const [title, setTitle] = useState('') + const [body, setBody] = useState('## Inhalt\n\nHier können Sie Ihren Beitrag verfassen.') + const [kategorie, setKategorie] = useState('Allgemein') + const [uploading, setUploading] = useState(false) + const [attachments, setAttachments] = useState< + Array<{ name: string; storagePath: string; sizeBytes: number; url: string }> + >([]) + + const createMutation = trpc.news.create.useMutation({ + onSuccess: () => router.push('/dashboard/news'), + }) + + function handleSubmit(publishNow: boolean) { + if (!title.trim() || !body.trim()) return + createMutation.mutate({ + title, + body, + kategorie: kategorie as never, + publishedAt: publishNow ? new Date().toISOString() : null, + }) + } + + async function handleFileUpload(e: React.ChangeEvent) { + const file = e.target.files?.[0] + if (!file) return + setUploading(true) + const formData = new FormData() + formData.append('file', file) + try { + const res = await fetch('/api/upload', { method: 'POST', body: formData }) + const data = await res.json() + setAttachments((prev) => [...prev, data]) + } catch { + alert('Upload fehlgeschlagen') + } finally { + setUploading(false) + } + } + + return ( +
+
+ + ← Zurück + +

Beitrag erstellen

+
+ +
+
+
+ + setTitle(e.target.value)} + placeholder="Aussagekräftiger Titel..." + className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500" + /> +
+
+ + +
+
+ +
+ +
+ setBody(v ?? '')} + height={400} + preview="live" + /> +
+
+ + {/* Attachments */} +
+ + + {attachments.length > 0 && ( +
    + {attachments.map((a, i) => ( +
  • + 📄 + {a.name} + ({Math.round(a.sizeBytes / 1024)} KB) +
  • + ))} +
+ )} +
+ + {createMutation.error && ( +

+ {createMutation.error.message} +

+ )} + +
+ + +
+
+
+ ) +} diff --git a/innungsapp/apps/admin/app/dashboard/news/page.tsx b/innungsapp/apps/admin/app/dashboard/news/page.tsx new file mode 100644 index 0000000..e17dea0 --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/news/page.tsx @@ -0,0 +1,123 @@ +import { prisma } from '@innungsapp/shared' +import { auth } from '@/lib/auth' +import { headers } from 'next/headers' +import { redirect } from 'next/navigation' +import Link from 'next/link' +import { NEWS_KATEGORIE_LABELS } from '@innungsapp/shared' +import { format } from 'date-fns' +import { de } from 'date-fns/locale' + +const KATEGORIE_COLORS: Record = { + Wichtig: 'bg-red-100 text-red-700', + Pruefung: 'bg-blue-100 text-blue-700', + Foerderung: 'bg-green-100 text-green-700', + Veranstaltung: 'bg-purple-100 text-purple-700', + Allgemein: 'bg-gray-100 text-gray-700', +} + +export default async function NewsPage() { + const session = await auth.api.getSession({ headers: await headers() }) + if (!session?.user) redirect('/login') + const userRole = await prisma.userRole.findFirst({ + where: { userId: session.user.id, role: 'admin' }, + }) + if (!userRole) redirect('/dashboard') + + const news = await prisma.news.findMany({ + where: { orgId: userRole.orgId }, + include: { author: { select: { name: true } } }, + orderBy: [{ publishedAt: 'desc' }, { createdAt: 'desc' }], + }) + + const published = news.filter((n) => n.publishedAt) + const drafts = news.filter((n) => !n.publishedAt) + + return ( +
+
+
+

News

+

{published.length} publiziert · {drafts.length} Entwürfe

+
+ + + Beitrag erstellen + +
+ + {drafts.length > 0 && ( +
+

+ Entwürfe +

+
+ + + {drafts.map((n) => ( + + + + + + ))} + +
+

{n.title}

+

Erstellt {format(n.createdAt, 'dd. MMM yyyy', { locale: de })}

+
+ + {NEWS_KATEGORIE_LABELS[n.kategorie]} + + + + Bearbeiten + +
+
+
+ )} + +
+

+ Publiziert +

+
+ + + + + + + + + + + + {published.map((n) => ( + + + + + + + + ))} + +
TitelKategorieAutorDatum
{n.title} + + {NEWS_KATEGORIE_LABELS[n.kategorie]} + + {n.author?.name ?? '—'} + {n.publishedAt ? format(n.publishedAt, 'dd.MM.yyyy', { locale: de }) : '—'} + + + Bearbeiten + +
+
+
+
+ ) +} diff --git a/innungsapp/apps/admin/app/dashboard/page.tsx b/innungsapp/apps/admin/app/dashboard/page.tsx new file mode 100644 index 0000000..07c1d9f --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/page.tsx @@ -0,0 +1,125 @@ +import { prisma } from '@innungsapp/shared' +import { auth } from '@/lib/auth' +import { headers } from 'next/headers' +import { redirect } from 'next/navigation' +import { StatsCards } from '@/components/stats/StatsCards' +import Link from 'next/link' +import { format } from 'date-fns' +import { de } from 'date-fns/locale' +import { NEWS_KATEGORIE_LABELS, TERMIN_TYP_LABELS } from '@innungsapp/shared' + +export default async function DashboardPage() { + const session = await auth.api.getSession({ headers: await headers() }) + if (!session?.user) redirect('/login') + + const userRole = await prisma.userRole.findFirst({ + where: { userId: session.user.id }, + include: { org: true }, + }) + if (!userRole) redirect('/login') + + const orgId = userRole.orgId + const now = new Date() + const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000) + + const [activeMembers, newsThisWeek, upcomingTermine, activeStellen, recentNews, nextTermine] = + await Promise.all([ + prisma.member.count({ where: { orgId, status: 'aktiv' } }), + prisma.news.count({ where: { orgId, publishedAt: { gte: weekAgo, not: null } } }), + prisma.termin.count({ where: { orgId, datum: { gte: now } } }), + prisma.stelle.count({ where: { orgId, aktiv: true } }), + prisma.news.findMany({ + where: { orgId, publishedAt: { not: null } }, + orderBy: { publishedAt: 'desc' }, + take: 5, + include: { author: { select: { name: true } } }, + }), + prisma.termin.findMany({ + where: { orgId, datum: { gte: now } }, + orderBy: { datum: 'asc' }, + take: 3, + }), + ]) + + return ( +
+
+

Übersicht

+

{userRole.org.name}

+
+ + + +
+ {/* Recent News */} +
+
+

Neueste Beiträge

+ + Alle anzeigen + +
+
+ {recentNews.map((n) => ( +
+
+

{n.title}

+

+ {n.publishedAt + ? format(n.publishedAt, 'dd. MMM yyyy', { locale: de }) + : 'Entwurf'}{' '} + · {n.author?.name ?? 'Unbekannt'} +

+
+ + {NEWS_KATEGORIE_LABELS[n.kategorie]} + +
+ ))} +
+
+ + {/* Upcoming Termine */} +
+
+

Nächste Termine

+ + Alle anzeigen + +
+
+ {nextTermine.length === 0 && ( +

Keine bevorstehenden Termine

+ )} + {nextTermine.map((t) => ( +
+
+

+ {format(t.datum, 'dd', { locale: de })} +

+

+ {format(t.datum, 'MMM', { locale: de })} +

+
+
+

{t.titel}

+

{t.ort ?? 'Kein Ort angegeben'}

+
+ + {TERMIN_TYP_LABELS[t.typ]} + +
+ ))} +
+
+
+
+ ) +} diff --git a/innungsapp/apps/admin/app/dashboard/stellen/DeactivateButton.tsx b/innungsapp/apps/admin/app/dashboard/stellen/DeactivateButton.tsx new file mode 100644 index 0000000..709a344 --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/stellen/DeactivateButton.tsx @@ -0,0 +1,21 @@ +'use client' + +import { trpc } from '@/lib/trpc-client' +import { useRouter } from 'next/navigation' + +export function DeactivateButton({ id }: { id: string }) { + const router = useRouter() + const mutation = trpc.stellen.deactivate.useMutation({ + onSuccess: () => router.refresh(), + }) + + return ( + + ) +} diff --git a/innungsapp/apps/admin/app/dashboard/stellen/page.tsx b/innungsapp/apps/admin/app/dashboard/stellen/page.tsx new file mode 100644 index 0000000..b1092d3 --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/stellen/page.tsx @@ -0,0 +1,78 @@ +import { prisma } from '@innungsapp/shared' +import { auth } from '@/lib/auth' +import { headers } from 'next/headers' +import { redirect } from 'next/navigation' +import { format } from 'date-fns' +import { de } from 'date-fns/locale' +import { DeactivateButton } from './DeactivateButton' + +export default async function StellenPage() { + const session = await auth.api.getSession({ headers: await headers() }) + if (!session?.user) redirect('/login') + const userRole = await prisma.userRole.findFirst({ + where: { userId: session.user.id, role: 'admin' }, + }) + if (!userRole) redirect('/dashboard') + + const stellen = await prisma.stelle.findMany({ + where: { orgId: userRole.orgId }, + include: { member: { select: { name: true, betrieb: true } } }, + orderBy: [{ aktiv: 'desc' }, { createdAt: 'desc' }], + }) + + return ( +
+
+

Lehrlingsbörse

+

+ {stellen.filter((s) => s.aktiv).length} aktive Angebote +

+
+ +
+ + + + + + + + + + + + + + + {stellen.map((s) => ( + + + + + + + + + + + ))} + +
BetriebSparteStellenLehrjahrVergütungEingestelltStatus
+

{s.member.betrieb}

+

{s.member.name}

+
{s.sparte}{s.stellenAnz}{s.lehrjahr ?? '—'}{s.verguetung ?? '—'}{format(s.createdAt, 'dd.MM.yyyy', { locale: de })} + + {s.aktiv ? 'Aktiv' : 'Inaktiv'} + + + {s.aktiv && } +
+ {stellen.length === 0 && ( +
Noch keine Stellenangebote
+ )} +
+
+ ) +} diff --git a/innungsapp/apps/admin/app/dashboard/termine/neu/page.tsx b/innungsapp/apps/admin/app/dashboard/termine/neu/page.tsx new file mode 100644 index 0000000..7ab9abc --- /dev/null +++ b/innungsapp/apps/admin/app/dashboard/termine/neu/page.tsx @@ -0,0 +1,144 @@ +'use client' + +import { useState } from 'react' +import { useRouter } from 'next/navigation' +import { trpc } from '@/lib/trpc-client' +import Link from 'next/link' + +const TYPEN = [ + { value: 'Pruefung', label: 'Prüfung' }, + { value: 'Versammlung', label: 'Versammlung' }, + { value: 'Kurs', label: 'Kurs' }, + { value: 'Event', label: 'Event' }, + { value: 'Sonstiges', label: 'Sonstiges' }, +] + +export default function TerminNeuPage() { + const router = useRouter() + const [form, setForm] = useState({ + titel: '', + datum: '', + uhrzeit: '', + endeDatum: '', + endeUhrzeit: '', + ort: '', + adresse: '', + typ: 'Versammlung', + beschreibung: '', + maxTeilnehmer: '', + }) + + const createMutation = trpc.termine.create.useMutation({ + onSuccess: () => router.push('/dashboard/termine'), + }) + + function handleSubmit(e: React.FormEvent) { + e.preventDefault() + createMutation.mutate({ + titel: form.titel, + datum: form.datum, + uhrzeit: form.uhrzeit || undefined, + endeDatum: form.endeDatum || undefined, + endeUhrzeit: form.endeUhrzeit || undefined, + ort: form.ort || undefined, + adresse: form.adresse || undefined, + typ: form.typ as never, + beschreibung: form.beschreibung || undefined, + maxTeilnehmer: form.maxTeilnehmer ? Number(form.maxTeilnehmer) : undefined, + }) + } + + const F = (field: string) => (e: React.ChangeEvent) => + setForm({ ...form, [field]: e.target.value }) + + const inputClass = + 'w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500' + + return ( +
+
+ + ← Zurück + +

Termin anlegen

+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +