mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-26 11:54:38 +02:00
refactor: restructure
monorepo with apps/ and services/ directories
This commit is contained in:
parent
25824ed0ac
commit
ff80aeec1f
4062 changed files with 2592 additions and 1278 deletions
391
apps/maerchenzauber/docs/MCP_SERVER_SETUP.md
Normal file
391
apps/maerchenzauber/docs/MCP_SERVER_SETUP.md
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
# MCP Server Setup für Märchenzauber
|
||||
|
||||
## Übersicht
|
||||
|
||||
Dieses Dokument beschreibt die Einrichtung eines **Model Context Protocol (MCP) Servers** für die Supabase-Datenbank von Märchenzauber. Mit MCP kann Claude Code direkt mit der Supabase-Datenbank interagieren, Queries ausführen, Tabellen analysieren und Migrationen durchführen.
|
||||
|
||||
## Was ist MCP?
|
||||
|
||||
**Model Context Protocol (MCP)** ist ein Standard, der es Large Language Models (LLMs) wie Claude ermöglicht, mit externen Tools, Datenbanken und APIs zu kommunizieren. MCP erweitert die Fähigkeiten von Claude Code durch:
|
||||
|
||||
- Direkte Datenbankabfragen
|
||||
- Tabellenverwaltung und -analyse
|
||||
- Automatisierte Migrationen
|
||||
- Zugriff auf Konfigurationen
|
||||
- Natürlichsprachige Datenbankinteraktionen
|
||||
|
||||
## Supabase MCP Server Features
|
||||
|
||||
Der offizielle Supabase MCP Server bietet über 20 Tools in verschiedenen Kategorien:
|
||||
|
||||
### Verfügbare Tool-Gruppen
|
||||
|
||||
- **Account**: Account-Management
|
||||
- **Knowledge Base**: Dokumentation und Wissen
|
||||
- **Database**: Tabellen, Queries, Schema-Management
|
||||
- **Debugging**: Logs und Fehleranalyse
|
||||
- **Development**: Entwicklungstools
|
||||
- **Edge Functions**: Serverless Functions
|
||||
- **Branching**: Database Branching
|
||||
- **Storage**: Dateiverwaltung
|
||||
|
||||
### Hauptfunktionen
|
||||
|
||||
- `execute_sql`: SQL-Queries ausführen (SELECT, INSERT, UPDATE, DELETE)
|
||||
- `apply_migration`: Schema-Änderungen und Migrationen anwenden
|
||||
- Tabellenanalyse und -erstellung
|
||||
- Automatische DDL-Generierung
|
||||
|
||||
## Setup-Anleitung
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
1. **Claude Code** installiert und eingerichtet
|
||||
2. **Supabase Account** mit aktivem Projekt
|
||||
3. **Supabase Projekt-Referenz** (projekt_ref aus der Supabase URL)
|
||||
|
||||
### Schritt 1: Sicherheitsüberlegungen
|
||||
|
||||
**WICHTIG:** Bevor du MCP einrichtest, beachte folgende Sicherheitshinweise:
|
||||
|
||||
#### ⚠️ Sicherheitswarnungen
|
||||
|
||||
- **Niemals mit Produktion verbinden**: Nutze MCP nur für Development-Projekte
|
||||
- **Prompt Injection**: AI-Assistenten können durch manipulierte Eingaben zu ungewollten Queries verleitet werden
|
||||
- **Developer-Permissions**: Der MCP Server arbeitet mit deinen Entwickler-Rechten
|
||||
- **Kein End-User-Tool**: MCP ist nur für interne Entwicklung gedacht
|
||||
|
||||
#### ✅ Best Practices
|
||||
|
||||
1. **Read-Only Mode**: Nutze den Read-Only Modus für maximale Sicherheit
|
||||
2. **Projekt-Scoping**: Beschränke den Server auf ein spezifisches Projekt
|
||||
3. **Database Branching**: Nutze Supabase Branches für sichere Tests
|
||||
4. **Manual Approval**: Aktiviere manuelle Bestätigung für Tool-Aufrufe
|
||||
5. **Feature-Einschränkung**: Aktiviere nur benötigte Tool-Gruppen
|
||||
|
||||
### Schritt 2: MCP Server konfigurieren
|
||||
|
||||
Der Supabase MCP Server ist als **Remote HTTP Server** verfügbar und benötigt keine lokale Installation.
|
||||
|
||||
#### Option A: Mit Claude Code CLI (Empfohlen)
|
||||
|
||||
```bash
|
||||
# MCP Server hinzufügen (Read-Only für Märchenzauber Production)
|
||||
claude mcp add --transport http supabase-maerchenzauber "https://mcp.supabase.com/mcp?read_only=true&project_ref=dyywxrmonxoiojsjmymc"
|
||||
|
||||
# Alle MCP Server auflisten
|
||||
claude mcp list
|
||||
|
||||
# Server entfernen (falls nötig)
|
||||
claude mcp remove supabase-maerchenzauber
|
||||
```
|
||||
|
||||
#### Option B: Manuelle Konfiguration
|
||||
|
||||
Erstelle oder bearbeite die MCP-Konfigurationsdatei:
|
||||
|
||||
**Für lokales Scope** (nur für dich in diesem Projekt):
|
||||
```bash
|
||||
# .mcp.json im Projekt-Root erstellen
|
||||
```
|
||||
|
||||
**Für User Scope** (global für alle deine Projekte):
|
||||
```bash
|
||||
# ~/.config/claude/mcp.json
|
||||
```
|
||||
|
||||
**Konfiguration (JSON):**
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"supabase-maerchenzauber": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.supabase.com/mcp?read_only=true&project_ref=dyywxrmonxoiojsjmymc"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Schritt 3: Konfigurationsoptionen
|
||||
|
||||
#### URL-Parameter
|
||||
|
||||
Du kannst die MCP Server URL mit folgenden Query-Parametern anpassen:
|
||||
|
||||
```bash
|
||||
https://mcp.supabase.com/mcp?read_only=true&project_ref=<projekt-ref>&features=database,debugging
|
||||
```
|
||||
|
||||
**Verfügbare Parameter:**
|
||||
|
||||
- `read_only=true` - Nur Lesezugriff (empfohlen!)
|
||||
- `project_ref=<ref>` - Beschränke auf spezifisches Projekt
|
||||
- `features=<gruppe1>,<gruppe2>` - Aktiviere nur bestimmte Tool-Gruppen
|
||||
|
||||
**Beispiele:**
|
||||
|
||||
```bash
|
||||
# Read-Only mit nur Database-Tools
|
||||
https://mcp.supabase.com/mcp?read_only=true&project_ref=dyywxrmonxoiojsjmymc&features=database
|
||||
|
||||
# Voller Zugriff auf Development-Datenbank
|
||||
https://mcp.supabase.com/mcp?project_ref=<dev-projekt-ref>
|
||||
|
||||
# Nur Debugging und Knowledge Base
|
||||
https://mcp.supabase.com/mcp?read_only=true&project_ref=dyywxrmonxoiojsjmymc&features=debugging,knowledgebase
|
||||
```
|
||||
|
||||
### Schritt 4: Authentifizierung
|
||||
|
||||
Beim ersten Verwenden des MCP Servers wirst du automatisch aufgefordert, dich zu authentifizieren:
|
||||
|
||||
1. **Browser-Fenster öffnet sich** automatisch
|
||||
2. **Login bei Supabase** mit deinem Account
|
||||
3. **Organisation auswählen**, die das Projekt enthält
|
||||
4. **Zugriff gewähren** für den MCP Server
|
||||
|
||||
Die Authentifizierung erfolgt über OAuth 2.0 und ist sicher.
|
||||
|
||||
### Schritt 5: MCP Server verwenden
|
||||
|
||||
Nach der Einrichtung kannst du in Claude Code direkt mit der Datenbank interagieren:
|
||||
|
||||
#### Beispiel-Prompts
|
||||
|
||||
```
|
||||
"Zeige mir alle Tabellen in der Märchenzauber-Datenbank"
|
||||
|
||||
"Erstelle eine neue Spalte 'created_at' in der 'stories' Tabelle"
|
||||
|
||||
"Wie viele Charaktere haben wir insgesamt in der Datenbank?"
|
||||
|
||||
"Analysiere die Struktur der 'characters' Tabelle"
|
||||
|
||||
"Führe eine Migration aus, um die 'user_settings' Tabelle zu erweitern"
|
||||
```
|
||||
|
||||
#### MCP Resources verwenden
|
||||
|
||||
Du kannst auf Datenbank-Ressourcen mit `@` verweisen:
|
||||
|
||||
```
|
||||
"Analysiere @characters Tabelle und schlage Optimierungen vor"
|
||||
```
|
||||
|
||||
## Konfiguration für verschiedene Umgebungen
|
||||
|
||||
### Development Setup (empfohlen für Start)
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"supabase-dev": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.supabase.com/mcp?project_ref=dyywxrmonxoiojsjmymc&features=database,development"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Production Setup (nur Lesen)
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"supabase-prod": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.supabase.com/mcp?read_only=true&project_ref=dyywxrmonxoiojsjmymc&features=database"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Debugging Setup
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"supabase-debug": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.supabase.com/mcp?read_only=true&project_ref=dyywxrmonxoiojsjmymc&features=database,debugging"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Projekt-spezifische Informationen
|
||||
|
||||
### Märchenzauber Supabase Details
|
||||
|
||||
- **Projekt URL**: `https://dyywxrmonxoiojsjmymc.supabase.co`
|
||||
- **Projekt Ref**: `dyywxrmonxoiojsjmymc`
|
||||
- **Storage Bucket**: `maerchenzauber`
|
||||
|
||||
### Wichtige Tabellen
|
||||
|
||||
- `characters` - Benutzerdefinierte Charaktere
|
||||
- `stories` - Generierte Geschichten
|
||||
- `story_collections` - Story-Sammlungen
|
||||
- `user_settings` - Benutzereinstellungen
|
||||
- `public_stories` - Öffentlich geteilte Geschichten
|
||||
|
||||
### Empfohlene MCP-Konfiguration für Märchenzauber
|
||||
|
||||
```bash
|
||||
# Produktive Datenbank (Read-Only)
|
||||
claude mcp add --transport http supabase-prod "https://mcp.supabase.com/mcp?read_only=true&project_ref=dyywxrmonxoiojsjmymc&features=database,knowledgebase"
|
||||
|
||||
# Development/Testing (mit Schreibrechten)
|
||||
# ACHTUNG: Nur nutzen, wenn du eine Dev-Instanz hast!
|
||||
# claude mcp add --transport http supabase-dev "https://mcp.supabase.com/mcp?project_ref=<dev-ref>&features=database,development,debugging"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### MCP Server verbindet nicht
|
||||
|
||||
```bash
|
||||
# 1. Überprüfe ob MCP konfiguriert ist
|
||||
claude mcp list
|
||||
|
||||
# 2. Authentifizierung zurücksetzen
|
||||
# Lösche die Authentifizierungsdaten und starte neu
|
||||
|
||||
# 3. Überprüfe die Projekt-Referenz
|
||||
# Stelle sicher, dass dyywxrmonxoiojsjmymc korrekt ist
|
||||
```
|
||||
|
||||
### Queries schlagen fehl
|
||||
|
||||
- **Read-Only Mode**: Wenn `read_only=true` gesetzt ist, sind nur SELECT-Queries erlaubt
|
||||
- **Permissions**: Überprüfe, ob dein Supabase-Account die nötigen Rechte hat
|
||||
- **RLS Policies**: Row Level Security Policies können Queries blockieren
|
||||
|
||||
### Authentifizierung schlägt fehl
|
||||
|
||||
- Stelle sicher, dass du im richtigen Supabase-Account eingeloggt bist
|
||||
- Überprüfe, ob du Zugriff auf die Organisation hast, die das Projekt enthält
|
||||
- Versuche, dich erneut zu authentifizieren
|
||||
|
||||
## Erweiterte Konfiguration
|
||||
|
||||
### Umgebungsvariablen verwenden
|
||||
|
||||
Du kannst Umgebungsvariablen in der MCP-Konfiguration nutzen:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"supabase": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.supabase.com/mcp?read_only=true&project_ref=${SUPABASE_PROJECT_REF}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Mehrere Projekte
|
||||
|
||||
Du kannst mehrere Supabase-Projekte gleichzeitig konfigurieren:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"supabase-maerchenzauber-prod": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.supabase.com/mcp?read_only=true&project_ref=dyywxrmonxoiojsjmymc"
|
||||
},
|
||||
"supabase-maerchenzauber-dev": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.supabase.com/mcp?project_ref=<dev-ref>"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Team-Setup (Project Scope)
|
||||
|
||||
Für Team-weite Konfiguration, erstelle `.mcp.json` im Projekt-Root:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"supabase-maerchenzauber": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.supabase.com/mcp?read_only=true&project_ref=dyywxrmonxoiojsjmymc&features=database",
|
||||
"description": "Märchenzauber Production DB (Read-Only)"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Vorteile:**
|
||||
- Alle Teammitglieder nutzen die gleiche Konfiguration
|
||||
- Versionskontrolle über Git
|
||||
- Einheitliche Development-Experience
|
||||
|
||||
**Hinweis:** Jedes Teammitglied muss sich individuell authentifizieren.
|
||||
|
||||
## Nützliche Workflows
|
||||
|
||||
### 1. Datenbank-Schema analysieren
|
||||
|
||||
```
|
||||
Claude: "Analysiere alle Tabellen in der Datenbank und erstelle ein Schema-Diagramm"
|
||||
```
|
||||
|
||||
### 2. Migration erstellen
|
||||
|
||||
```
|
||||
Claude: "Erstelle eine Migration, um eine 'is_favorite' Spalte zur 'stories' Tabelle hinzuzufügen"
|
||||
```
|
||||
|
||||
### 3. Daten abfragen
|
||||
|
||||
```
|
||||
Claude: "Zeige mir die letzten 10 erstellten Stories mit ihren Autoren"
|
||||
```
|
||||
|
||||
### 4. Performance-Analyse
|
||||
|
||||
```
|
||||
Claude: "Analysiere die Performance der 'characters' Tabelle und schlage Indizes vor"
|
||||
```
|
||||
|
||||
## Sicherheits-Checkliste
|
||||
|
||||
Vor der Einrichtung von MCP:
|
||||
|
||||
- [ ] Nutze **niemals** Production-Daten für Experimente
|
||||
- [ ] Aktiviere **Read-Only Mode** für Production
|
||||
- [ ] Beschränke auf **spezifisches Projekt** mit `project_ref`
|
||||
- [ ] Aktiviere nur **benötigte Features**
|
||||
- [ ] Nutze **Database Branching** für sichere Tests
|
||||
- [ ] Teile **niemals MCP-Konfiguration** mit End-Usern
|
||||
- [ ] Überprüfe **regelmäßig die Zugriffe** im Supabase Dashboard
|
||||
|
||||
## Ressourcen
|
||||
|
||||
- [Supabase MCP Documentation](https://supabase.com/docs/guides/getting-started/mcp)
|
||||
- [Supabase MCP GitHub](https://github.com/supabase-community/supabase-mcp)
|
||||
- [Claude Code MCP Documentation](https://docs.claude.com/en/docs/claude-code/mcp.md)
|
||||
- [Model Context Protocol Spec](https://modelcontextprotocol.io/)
|
||||
|
||||
## Support
|
||||
|
||||
Bei Problemen:
|
||||
|
||||
1. **Supabase Discord**: Frage im #mcp Channel
|
||||
2. **GitHub Issues**: [supabase-community/supabase-mcp](https://github.com/supabase-community/supabase-mcp/issues)
|
||||
3. **Claude Code Issues**: [anthropics/claude-code](https://github.com/anthropics/claude-code/issues)
|
||||
|
||||
## Version
|
||||
|
||||
- **Dokument erstellt**: 2025-10-15
|
||||
- **Supabase MCP Server**: Pre-1.0 (Breaking Changes möglich)
|
||||
- **Claude Code**: Latest
|
||||
|
||||
## Changelog
|
||||
|
||||
- **2025-10-15**: Initiale Dokumentation erstellt
|
||||
1230
apps/maerchenzauber/docs/REPLICATE_IMAGE_MODELS_COMPREHENSIVE.md
Normal file
1230
apps/maerchenzauber/docs/REPLICATE_IMAGE_MODELS_COMPREHENSIVE.md
Normal file
File diff suppressed because it is too large
Load diff
10
apps/maerchenzauber/docs/ReplicateImageModels.md
Normal file
10
apps/maerchenzauber/docs/ReplicateImageModels.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
https://replicate.com/google/imagen-4-fast
|
||||
https://replicate.com/bytedance/seedream-4
|
||||
https://replicate.com/ideogram-ai/ideogram-v3-turbo
|
||||
https://replicate.com/qwen/qwen-image
|
||||
https://replicate.com/black-forest-labs/flux-schnell
|
||||
https://replicate.com/black-forest-labs/flux-1.1-pro
|
||||
https://replicate.com/stability-ai/stable-diffusion-3.5-large-turbo
|
||||
https://replicate.com/google/imagen-4
|
||||
https://replicate.com/stability-ai/stable-diffusion-3.5-medium
|
||||
https://replicate.com/google/nano-banana
|
||||
316
apps/maerchenzauber/docs/SYSTEM_CHARACTERS.md
Normal file
316
apps/maerchenzauber/docs/SYSTEM_CHARACTERS.md
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
# System Characters
|
||||
|
||||
System characters are special read-only characters visible to all users in the Storyteller app. They provide a curated set of characters that users can use to create stories without needing to create their own characters first.
|
||||
|
||||
## Overview
|
||||
|
||||
System characters differ from regular user characters in several key ways:
|
||||
|
||||
- **Shared Visibility**: All users can see and use system characters
|
||||
- **Read-Only**: Users cannot edit or delete system characters
|
||||
- **No Sharing**: Share and edit buttons are hidden in the UI
|
||||
- **Special User ID**: System characters belong to a special system user
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### System User ID
|
||||
|
||||
System characters use a special UUID to identify them:
|
||||
|
||||
```typescript
|
||||
const SYSTEM_USER_ID = '00000000-0000-0000-0000-000000000000';
|
||||
```
|
||||
|
||||
This UUID is used consistently across:
|
||||
- Database records (`user_id` field)
|
||||
- Backend validation logic
|
||||
- Frontend UI conditional rendering
|
||||
|
||||
### Database Structure
|
||||
|
||||
System characters are stored in the same `characters` table as user characters, with `user_id` set to the system UUID:
|
||||
|
||||
```sql
|
||||
INSERT INTO public.characters (
|
||||
id,
|
||||
user_id,
|
||||
name,
|
||||
user_description,
|
||||
character_description,
|
||||
character_description_prompt,
|
||||
image_url,
|
||||
is_animal,
|
||||
animal_type,
|
||||
archived,
|
||||
created_at,
|
||||
updated_at,
|
||||
is_published,
|
||||
sharing_preference,
|
||||
images_data
|
||||
) VALUES (
|
||||
'11111111-1111-1111-1111-111111111111', -- Unique character ID
|
||||
'00000000-0000-0000-0000-000000000000', -- System user ID
|
||||
'Finia',
|
||||
'Eine Mutter weibliche Füchsin...',
|
||||
'A wise mother fox with red-golden fur...',
|
||||
-- ... other fields
|
||||
);
|
||||
```
|
||||
|
||||
### Row Level Security (RLS)
|
||||
|
||||
The database uses RLS policies to allow all authenticated users to read system characters while protecting them from modification:
|
||||
|
||||
**Read Access Policy:**
|
||||
```sql
|
||||
CREATE POLICY "Users can view their own characters and system characters"
|
||||
ON public.characters
|
||||
FOR SELECT
|
||||
USING (
|
||||
user_id = current_setting('request.jwt.claims', true)::json->>'user_id'
|
||||
OR user_id = '00000000-0000-0000-0000-000000000000'
|
||||
);
|
||||
```
|
||||
|
||||
**Write Protection:**
|
||||
System characters are protected from updates and deletes by the existing ownership checks in the UPDATE and DELETE policies.
|
||||
|
||||
### Backend Validation
|
||||
|
||||
The backend validates access to characters in multiple places. Each validation point checks both ownership and system character status:
|
||||
|
||||
**Character Controller** (`backend/src/character/character.controller.ts`):
|
||||
|
||||
```typescript
|
||||
const SYSTEM_USER_ID = '00000000-0000-0000-0000-000000000000';
|
||||
const isSystemCharacter = character.user_id === SYSTEM_USER_ID;
|
||||
const isOwnCharacter = character.user_id === user.sub;
|
||||
|
||||
if (!isSystemCharacter && !isOwnCharacter) {
|
||||
return { error: 'Character not found or access denied' };
|
||||
}
|
||||
```
|
||||
|
||||
This pattern is applied in:
|
||||
- `getCharacterById()` - GET /character/:id
|
||||
- `updateCharacter()` - PUT /character/:id
|
||||
- `deleteCharacter()` - DELETE /character/:id
|
||||
|
||||
**Story Creation Service** (`backend/src/story/services/story-creation.service.ts`):
|
||||
|
||||
```typescript
|
||||
const SYSTEM_USER_ID = '00000000-0000-0000-0000-000000000000';
|
||||
const isSystemCharacter = character.user_id === SYSTEM_USER_ID;
|
||||
const isOwnCharacter = character.user_id === userId;
|
||||
|
||||
if (!isSystemCharacter && !isOwnCharacter) {
|
||||
throw new Error('Character not found or does not belong to user');
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend UI
|
||||
|
||||
The mobile app detects system characters and hides edit/share functionality:
|
||||
|
||||
**Character Detail Screen** (`mobile/app/character/[id].tsx`):
|
||||
|
||||
```typescript
|
||||
// Check if this is a system character (read-only)
|
||||
const SYSTEM_USER_ID = '00000000-0000-0000-0000-000000000000';
|
||||
const isSystemCharacter = character?.user_id === SYSTEM_USER_ID;
|
||||
|
||||
// Hide edit/share buttons for system characters
|
||||
{!isEditing && !isSystemCharacter && (
|
||||
<ScrollView>
|
||||
<ShareCharacterButton character={character} />
|
||||
<TouchableOpacity onPress={() => setIsEditing(!isEditing)}>
|
||||
<AntDesign name="edit" />
|
||||
<Text>Bearbeiten</Text>
|
||||
</TouchableOpacity>
|
||||
</ScrollView>
|
||||
)}
|
||||
```
|
||||
|
||||
## Adding New System Characters
|
||||
|
||||
To add a new system character to the platform:
|
||||
|
||||
### 1. Prepare Character Assets
|
||||
|
||||
Upload the character image to Supabase Storage in the system user's folder:
|
||||
|
||||
```
|
||||
bucket: user-uploads
|
||||
path: 00000000-0000-0000-0000-000000000000/characters/[filename]
|
||||
```
|
||||
|
||||
Example URL:
|
||||
```
|
||||
https://dyywxrmonxoiojsjmymc.supabase.co/storage/v1/object/public/user-uploads/00000000-0000-0000-0000-000000000000/characters/1762453771144-cmngxj-large.webp
|
||||
```
|
||||
|
||||
### 2. Create Database Migration
|
||||
|
||||
Create a migration to insert the character record:
|
||||
|
||||
```sql
|
||||
-- Add new system character
|
||||
INSERT INTO public.characters (
|
||||
id, -- Generate new UUID
|
||||
user_id, -- Always '00000000-0000-0000-0000-000000000000'
|
||||
name, -- Character name
|
||||
user_description, -- User-facing description (German)
|
||||
character_description, -- AI prompt description (English)
|
||||
character_description_prompt, -- Enhanced prompt for consistency
|
||||
image_url, -- Supabase Storage URL
|
||||
is_animal, -- true/false
|
||||
animal_type, -- Animal type if applicable
|
||||
archived, -- false
|
||||
created_at, -- NOW()
|
||||
updated_at, -- NOW()
|
||||
is_published, -- true
|
||||
sharing_preference, -- 'public'
|
||||
images_data -- JSON array of image variations
|
||||
) VALUES (
|
||||
gen_random_uuid(), -- Or specific UUID
|
||||
'00000000-0000-0000-0000-000000000000',
|
||||
'Character Name',
|
||||
'Deutsche Beschreibung...',
|
||||
'English AI description...',
|
||||
'Detailed prompt for image generation...',
|
||||
'https://...',
|
||||
true,
|
||||
'animal_type',
|
||||
false,
|
||||
NOW(),
|
||||
NOW(),
|
||||
true,
|
||||
'public',
|
||||
'[{"description": "...", "imageUrl": "..."}]'::jsonb
|
||||
) ON CONFLICT (id) DO UPDATE SET
|
||||
name = EXCLUDED.name,
|
||||
user_description = EXCLUDED.user_description,
|
||||
-- ... update other fields as needed
|
||||
;
|
||||
```
|
||||
|
||||
### 3. Apply Migration
|
||||
|
||||
Use Supabase MCP tools to apply the migration to both development and production databases:
|
||||
|
||||
```typescript
|
||||
// Example using MCP tools
|
||||
await mcp__supabase__apply_migration({
|
||||
project_id: "your-project-id",
|
||||
name: "add_[character_name]_system_character",
|
||||
query: "INSERT INTO ..."
|
||||
});
|
||||
```
|
||||
|
||||
## Current System Characters
|
||||
|
||||
### Finia - The Wise Fox
|
||||
|
||||
- **ID**: `11111111-1111-1111-1111-111111111111`
|
||||
- **Type**: Female Fox (Füchsin)
|
||||
- **Description**: A wise mother fox with red-golden fur and a caring nature
|
||||
- **Purpose**: Default character for first-time users to create stories immediately
|
||||
- **Languages**: German (user_description) and English (character_description)
|
||||
|
||||
**Image Location**:
|
||||
```
|
||||
https://dyywxrmonxoiojsjmymc.supabase.co/storage/v1/object/public/user-uploads/00000000-0000-0000-0000-000000000000/characters/1762453771144-cmngxj-large.webp
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Character Selection
|
||||
- Choose characters with broad appeal for diverse story types
|
||||
- Ensure high-quality, consistent character images
|
||||
- Provide both German and English descriptions
|
||||
- Make characters suitable for children's stories
|
||||
|
||||
### Naming Conventions
|
||||
- Use descriptive, memorable names
|
||||
- Consider cultural appropriateness
|
||||
- Ensure uniqueness from user-created characters
|
||||
|
||||
### Image Requirements
|
||||
- High resolution (recommended: 1024x1024 or higher)
|
||||
- Consistent art style across system characters
|
||||
- Child-appropriate content
|
||||
- Clear, recognizable character features
|
||||
|
||||
### Database Management
|
||||
- Always use migrations for changes
|
||||
- Test in development before production
|
||||
- Include rollback procedures in migrations
|
||||
- Document character purposes and target audiences
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Character Not Visible to Users
|
||||
|
||||
**Check RLS Policies:**
|
||||
```sql
|
||||
-- Verify the SELECT policy exists
|
||||
SELECT * FROM pg_policies
|
||||
WHERE tablename = 'characters'
|
||||
AND policyname LIKE '%system%';
|
||||
```
|
||||
|
||||
**Verify User ID:**
|
||||
```sql
|
||||
-- Ensure character has correct system user_id
|
||||
SELECT id, name, user_id
|
||||
FROM characters
|
||||
WHERE user_id = '00000000-0000-0000-0000-000000000000';
|
||||
```
|
||||
|
||||
### Backend Rejecting System Characters
|
||||
|
||||
Ensure all character validation logic includes system character checks:
|
||||
|
||||
```typescript
|
||||
const SYSTEM_USER_ID = '00000000-0000-0000-0000-000000000000';
|
||||
const isSystemCharacter = character.user_id === SYSTEM_USER_ID;
|
||||
const isOwnCharacter = character.user_id === user.sub;
|
||||
|
||||
if (!isSystemCharacter && !isOwnCharacter) {
|
||||
// Reject access
|
||||
}
|
||||
```
|
||||
|
||||
Check these files:
|
||||
- `backend/src/character/character.controller.ts` (GET, PUT, DELETE)
|
||||
- `backend/src/story/services/story-creation.service.ts` (character validation)
|
||||
|
||||
### Edit/Share Buttons Still Showing
|
||||
|
||||
Verify frontend detection logic in `mobile/app/character/[id].tsx`:
|
||||
|
||||
```typescript
|
||||
const SYSTEM_USER_ID = '00000000-0000-0000-0000-000000000000';
|
||||
const isSystemCharacter = character?.user_id === SYSTEM_USER_ID;
|
||||
```
|
||||
|
||||
Ensure the character object includes the `user_id` field from the API response.
|
||||
|
||||
## Related Files
|
||||
|
||||
### Backend
|
||||
- `backend/src/character/character.controller.ts` - Character CRUD endpoints
|
||||
- `backend/src/story/services/story-creation.service.ts` - Story creation validation
|
||||
- `backend/src/core/services/supabase-data.service.ts` - Database operations
|
||||
|
||||
### Frontend
|
||||
- `mobile/app/character/[id].tsx` - Character detail screen
|
||||
- `mobile/src/utils/dataService.ts` - Character data service (removed hardcoded logic)
|
||||
|
||||
### Database
|
||||
- Migration: `add_finnia_system_character_fixed`
|
||||
- Migration: `cleanup_conflicting_character_policies`
|
||||
|
||||
### Documentation
|
||||
- `CLAUDE.md` - Main project documentation
|
||||
- This file - System characters documentation
|
||||
211
apps/maerchenzauber/docs/ToDos.md
Normal file
211
apps/maerchenzauber/docs/ToDos.md
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
# Märchenzauber - ToDos & Dokumentation
|
||||
|
||||
## <¨ Bildmodell-Auswahl Feature (10.09.2025)
|
||||
|
||||
### Was wurde implementiert
|
||||
|
||||
#### Backend-Änderungen
|
||||
|
||||
1. **Datenbank-Schema**
|
||||
- Neue Tabelle `user_settings` mit Spalte `image_model` erstellt
|
||||
- RLS-Policies für sichere User-spezifische Einstellungen implementiert
|
||||
- Migration-Script: `apps/backend/migrations/001_create_user_settings_table.sql`
|
||||
|
||||
2. **Model-Konfiguration** (`apps/backend/src/core/models/image-models.ts`)
|
||||
- Drei Bildgenerierungsmodelle definiert:
|
||||
- **FLUX Schnell**: Schnelle Generierung (1-2 Sek, 1 Credit)
|
||||
- **FLUX Pro 1.1**: Premium-Qualität (10-15 Sek, 3 Credits)
|
||||
- **Stable Diffusion XL**: Standard-Qualität (5-10 Sek, 2 Credits)
|
||||
- Vollständige Replicate Model-IDs mit Versionen integriert
|
||||
|
||||
3. **Settings Service** (`apps/backend/src/core/services/settings.service.ts`)
|
||||
- `getUserImageModel(userId)`: Abrufen des User-spezifischen Modells
|
||||
- `setUserImageModel(userId, modelId)`: Setzen eines neuen Modells
|
||||
- `getAvailableImageModels()`: Liste aller verfügbaren Modelle
|
||||
- `getImageModelInfo(modelId)`: Detailinformationen zu einem Modell
|
||||
- Caching der User-Einstellungen für Performance
|
||||
|
||||
4. **Image Service Updates** (`apps/backend/src/core/services/image-supabase.service.ts`)
|
||||
- `generateImageWithReplicate()` nutzt jetzt User-spezifisches Modell
|
||||
- User-ID wird durch alle Bildgenerierungsfunktionen durchgereicht
|
||||
- Fallback auf Standard-Modell (SDXL) wenn keine User-Einstellung vorhanden
|
||||
|
||||
5. **Character Controller Updates** (`apps/backend/src/character/character.controller.ts`)
|
||||
- Alle `generateImage()` Aufrufe erweitert um User-ID Parameter
|
||||
- Drei Varianten aktualisiert: createCharacter, createCharacterFromImage, createCharacterSpecial
|
||||
|
||||
6. **Story Service Updates** (`apps/backend/src/story/services/story-creation.service.ts`)
|
||||
- `generateIllustrationForPage()` nutzt User-ID für Modellauswahl
|
||||
- Konsistente Modellnutzung für alle Illustrationen einer Story
|
||||
|
||||
7. **API Endpoints** (`apps/backend/src/settings/settings.controller.ts`)
|
||||
- `GET /settings/image-models`: Verfügbare Modelle mit Metadaten
|
||||
- `GET /settings/user/image-model`: Aktuelles User-Modell abrufen
|
||||
- `PUT /settings/user/image-model`: User-Modell ändern
|
||||
- DTO für Modell-Updates: `apps/backend/src/settings/dto/image-model.dto.ts`
|
||||
|
||||
#### Frontend-Änderungen
|
||||
|
||||
1. **Neue Settings-Seite** (`apps/mobile/app/(tabs)/(settings)/image-model.tsx`)
|
||||
- Übersichtliche Card-basierte Modellauswahl
|
||||
- Visual Feedback für ausgewähltes Modell
|
||||
- Badges für Geschwindigkeit und Credit-Kosten
|
||||
- Informative Beschreibungen für jedes Modell
|
||||
- Loading- und Saving-States
|
||||
- Error Handling mit User-Feedback
|
||||
|
||||
2. **Settings Integration** (`apps/mobile/app/settings.tsx`)
|
||||
- Neuer Button "Bildgenerierung" in den Haupteinstellungen
|
||||
- Navigation zur Modellauswahl-Seite
|
||||
|
||||
3. **UI Features**
|
||||
- Responsive Design für verschiedene Bildschirmgrößen
|
||||
- Farbcodierte Badges (Schnell/Premium/Standard)
|
||||
- Checkmark-Icon für ausgewähltes Modell
|
||||
- Info-Box mit Erklärung zur Modellauswahl
|
||||
|
||||
### =' Was muss noch gemacht werden
|
||||
|
||||
#### Sofort erforderlich (vor Go-Live)
|
||||
|
||||
1. **Datenbank-Migration ausführen** KRITISCH
|
||||
```bash
|
||||
# In Supabase Dashboard oder via psql:
|
||||
psql "postgresql://postgres.[project-id]:[password]@db.dyywxrmonxoiojsjmymc.supabase.co:5432/postgres"
|
||||
\i apps/backend/migrations/001_create_user_settings_table.sql
|
||||
```
|
||||
|
||||
2. **Backend neu starten**
|
||||
```bash
|
||||
cd apps/backend
|
||||
npm run dev # oder npm run start:prod für Produktion
|
||||
```
|
||||
|
||||
3. **Testing**
|
||||
- [ ] Modellauswahl in der App testen
|
||||
- [ ] Story-Generierung mit verschiedenen Modellen testen
|
||||
- [ ] Character-Erstellung mit verschiedenen Modellen testen
|
||||
- [ ] Persistenz der Einstellungen prüfen
|
||||
|
||||
#### Nächste Schritte (Nice-to-have)
|
||||
|
||||
1. **Performance & Monitoring**
|
||||
- [ ] Logging für Modell-Performance (Generierungszeiten)
|
||||
- [ ] Erfolgs-/Fehlerquoten pro Modell tracken
|
||||
- [ ] Analytics für Modell-Präferenzen der User
|
||||
|
||||
2. **User Experience**
|
||||
- [ ] Modell-Empfehlungen basierend auf Use-Case
|
||||
- [ ] Vorschau-Bilder für jedes Modell
|
||||
- [ ] A/B Testing für optimale Default-Einstellung
|
||||
|
||||
3. **Admin Features**
|
||||
- [ ] Admin-Dashboard für Modell-Statistiken
|
||||
- [ ] Modelle dynamisch aktivieren/deaktivieren
|
||||
- [ ] Credit-Preise anpassen per Admin-Interface
|
||||
|
||||
4. **Erweiterte Features**
|
||||
- [ ] Verschiedene Modelle für Characters vs. Stories
|
||||
- [ ] User-Feedback zur Bildqualität erfassen
|
||||
- [ ] Automatisches Fallback bei Modell-Ausfall
|
||||
- [ ] Batch-Generierung mit mehreren Modellen (für Vergleich)
|
||||
|
||||
### =Ê Technische Details
|
||||
|
||||
#### Modell-Spezifikationen
|
||||
|
||||
| Modell | Replicate ID | Geschwindigkeit | Credits | Use-Case |
|
||||
|--------|-------------|-----------------|---------|----------|
|
||||
| FLUX Schnell | `black-forest-labs/flux-schnell:5599ed30...` | 1-2s | 1 | Tests, Prototypen |
|
||||
| FLUX Pro 1.1 | `black-forest-labs/flux-1.1-pro:8f06b9d3...` | 10-15s | 3 | Finale Stories |
|
||||
| SDXL | `stability-ai/sdxl:39ed52f2...` | 5-10s | 2 | Standard |
|
||||
|
||||
#### Datenbank-Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE user_settings (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id TEXT NOT NULL UNIQUE,
|
||||
image_model TEXT DEFAULT 'sdxl' CHECK (image_model IN ('flux-schnell', 'flux-pro', 'sdxl')),
|
||||
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
### = Bekannte Issues & Fixes
|
||||
|
||||
1. **Import-Pfad-Fehler (GELÖST)**
|
||||
- Problem: `Colors` Import-Pfad war falsch
|
||||
- Lösung: Pfad von `../../../src/constants/Colors` zu `../../../constants/Colors` korrigiert
|
||||
|
||||
2. **TypeScript Strict Mode**
|
||||
- Linter hat `!` zu required properties hinzugefügt
|
||||
- DTOs nutzen jetzt strict mode compliance
|
||||
|
||||
### =Ý Testing Checklist
|
||||
|
||||
- [ ] **Backend API Tests**
|
||||
```bash
|
||||
# Modelle abrufen
|
||||
curl http://localhost:3002/settings/image-models -H "Authorization: Bearer TOKEN"
|
||||
|
||||
# User-Modell ändern
|
||||
curl -X PUT http://localhost:3002/settings/user/image-model \
|
||||
-H "Authorization: Bearer TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model": "flux-schnell"}'
|
||||
```
|
||||
|
||||
- [ ] **Frontend Tests**
|
||||
- Settings öffnen ’ Bildgenerierung
|
||||
- Modell auswählen und speichern
|
||||
- App neu starten und prüfen ob Auswahl persistiert
|
||||
- Neue Story/Character erstellen
|
||||
|
||||
- [ ] **Datenbank Tests**
|
||||
```sql
|
||||
-- User-Settings prüfen
|
||||
SELECT * FROM user_settings;
|
||||
|
||||
-- Modell-Verteilung
|
||||
SELECT image_model, COUNT(*) FROM user_settings GROUP BY image_model;
|
||||
```
|
||||
|
||||
### =Ú Dokumentation
|
||||
|
||||
- Vollständige Implementation-Dokumentation: `/IMAGE_MODEL_SELECTION_README.md`
|
||||
- API-Dokumentation in den jeweiligen Controller-Dateien
|
||||
- Frontend-Komponenten sind self-documenting mit TypeScript-Interfaces
|
||||
|
||||
### =€ Deployment Checklist
|
||||
|
||||
1. [ ] Datenbank-Migration ausführen
|
||||
2. [ ] Environment-Variable `MAERCHENZAUBER_REPLICATE_API_KEY` prüfen
|
||||
3. [ ] Backend deployen
|
||||
4. [ ] Mobile App builden und deployen
|
||||
5. [ ] Feature-Flag aktivieren (falls vorhanden)
|
||||
6. [ ] Monitoring aktivieren
|
||||
7. [ ] User-Kommunikation über neues Feature
|
||||
|
||||
---
|
||||
|
||||
## =Å Weitere TODOs (nicht related zu Bildmodell-Feature)
|
||||
|
||||
### High Priority
|
||||
- [ ] Story-Logbook vollständig implementieren
|
||||
- [ ] Character-Konsistenz in Stories verbessern
|
||||
- [ ] 10 Bilder pro Story generieren (aktuell nur 3)
|
||||
|
||||
### Medium Priority
|
||||
- [ ] Mana Core Credit-System Integration vervollständigen
|
||||
- [ ] Mehrsprachigkeit (DE/EN) konsistent umsetzen
|
||||
- [ ] Performance-Optimierungen für große Story-Collections
|
||||
|
||||
### Low Priority
|
||||
- [ ] Onboarding-Flow überarbeiten
|
||||
- [ ] Push-Notifications implementieren
|
||||
- [ ] Social-Sharing Features
|
||||
|
||||
---
|
||||
|
||||
*Letzte Aktualisierung: 10.09.2025 - Till Schneider*
|
||||
2690
apps/maerchenzauber/docs/VERBESSERUNGSVORSCHLAEGE.md
Normal file
2690
apps/maerchenzauber/docs/VERBESSERUNGSVORSCHLAEGE.md
Normal file
File diff suppressed because it is too large
Load diff
310
apps/maerchenzauber/docs/ci-npm-ssh-fix.md
Normal file
310
apps/maerchenzauber/docs/ci-npm-ssh-fix.md
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
# Summary: Fixing npm ci SSH Authentication in GitHub Actions
|
||||
|
||||
## 🔴 What We Tried (That Didn't Work)
|
||||
|
||||
### Attempt 1: Git Config URL Rewriting
|
||||
**What we did:**
|
||||
```yaml
|
||||
- name: Configure git for private packages
|
||||
run: |
|
||||
git config --global url."https://${GH_TOKEN}@github.com/".insteadOf "https://github.com/"
|
||||
git config --global url."https://${GH_TOKEN}@github.com/".insteadOf "ssh://git@github.com/"
|
||||
git config --global url."https://${GH_TOKEN}@github.com/".insteadOf "git@github.com:"
|
||||
```
|
||||
|
||||
**Why it failed:**
|
||||
- npm ci reads URLs directly from `package-lock.json`
|
||||
- npm's internal git client doesn't reliably honor git config `url.insteadOf` rules
|
||||
- npm fell back to SSH when it couldn't authenticate via HTTPS
|
||||
|
||||
### Attempt 2: Invalid .npmrc Configuration
|
||||
**What we did:**
|
||||
```
|
||||
# backend/.npmrc
|
||||
git-ssh-url = https://github.com/
|
||||
```
|
||||
|
||||
**Why it failed:**
|
||||
- `git-ssh-url` is not a valid npm configuration option
|
||||
- npm doesn't recognize this setting
|
||||
|
||||
### Attempt 3: Reordering Steps (Git Config Before Node Setup)
|
||||
**What we did:**
|
||||
- Moved git config step before `actions/setup-node`
|
||||
- Added npm cache clearing
|
||||
|
||||
**Why it failed:**
|
||||
- While this helped with caching issues, it didn't solve the root problem
|
||||
- npm ci still ignored git config and used lockfile URLs directly
|
||||
|
||||
### Attempt 4: persist-credentials: false
|
||||
**What we did:**
|
||||
```yaml
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
```
|
||||
|
||||
**Why it failed (partially):**
|
||||
- This fixed the token override issue (actions/checkout was setting default GITHUB_TOKEN)
|
||||
- But npm ci still couldn't authenticate because the lockfile URL had no token
|
||||
|
||||
### Attempt 5: Local Git Config Override
|
||||
**What we did:**
|
||||
```bash
|
||||
# Try to override global SSH rewrites with local HTTPS config
|
||||
cd project-root
|
||||
git config --local url."https://github.com/".insteadOf "git@github.com:"
|
||||
git config --local url."https://github.com/".insteadOf "ssh://git@github.com/"
|
||||
rm package-lock.json
|
||||
npm install
|
||||
```
|
||||
|
||||
**Why it failed:**
|
||||
- npm's internal git client doesn't consistently honor local git config during package resolution
|
||||
- Even with correct local config, npm still generated SSH URLs in `package-lock.json`
|
||||
- The git config order of precedence (local > global > system) doesn't reliably apply to npm's git subprocess
|
||||
- Testing with `git ls-remote` worked (used HTTPS), but `npm install` still wrote SSH URLs to lockfile
|
||||
- **Key insight**: npm may use a different git execution context that bypasses local config
|
||||
|
||||
---
|
||||
|
||||
## ✅ What Finally Worked
|
||||
|
||||
### The Root Cause
|
||||
**npm ci uses URLs from package-lock.json directly and ignores git config url.insteadOf**
|
||||
|
||||
Even though:
|
||||
- ✅ package.json had `git+https://github.com/...`
|
||||
- ✅ package-lock.json had `git+https://github.com/...` (no SSH)
|
||||
- ✅ git config was properly set
|
||||
|
||||
npm would run:
|
||||
```bash
|
||||
git ls-remote https://github.com/Memo-2023/mana-core-nestjs-package.git
|
||||
```
|
||||
|
||||
This failed with "Permission denied" because:
|
||||
1. The URL had no authentication token
|
||||
2. npm fell back to SSH (which wasn't configured)
|
||||
3. Git config rewrites were ignored by npm's git subprocess
|
||||
|
||||
### The Solution: Runtime Token Injection
|
||||
|
||||
**Step 1: Prevent Token Override**
|
||||
```yaml
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false # Don't let default GITHUB_TOKEN interfere
|
||||
```
|
||||
|
||||
**Step 2a: If lockfile has HTTPS URLs - Verify and Inject Token**
|
||||
```yaml
|
||||
- name: Verify no SSH URLs in lockfile
|
||||
run: |
|
||||
if grep -q "git@github.com\|ssh://git@github.com" package-lock.json; then
|
||||
echo "❌ ERROR: SSH URLs found in package-lock.json"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ No SSH URLs found in package-lock.json"
|
||||
|
||||
- name: Inject token into package-lock.json
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
|
||||
run: |
|
||||
sed -i "s|https://github.com/Memo-2023/|https://${GH_TOKEN}@github.com/Memo-2023/|g" package-lock.json
|
||||
```
|
||||
|
||||
**Step 2b: If lockfile has SSH URLs - Patch to HTTPS with Token**
|
||||
```yaml
|
||||
- name: Patch SSH URLs to HTTPS with token
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
|
||||
run: |
|
||||
if grep -q "git+ssh://git@github.com" package-lock.json; then
|
||||
echo "⚠️ SSH URLs found - patching to HTTPS with token..."
|
||||
sed -i "s|git+ssh://git@github.com/Memo-2023/|git+https://${GH_TOKEN}@github.com/Memo-2023/|g" package-lock.json
|
||||
echo "✓ Lockfile patched successfully"
|
||||
else
|
||||
echo "⚠️ No SSH URLs found - patching HTTPS URLs with token..."
|
||||
sed -i "s|https://github.com/Memo-2023/|https://${GH_TOKEN}@github.com/Memo-2023/|g" package-lock.json
|
||||
echo "✓ Token injected successfully"
|
||||
fi
|
||||
```
|
||||
|
||||
> **Note**: Use Step 2a if you can generate HTTPS lockfiles locally. Use Step 2b if your local git config always generates SSH URLs (accepts either format).
|
||||
|
||||
**Step 4: Run npm ci**
|
||||
```yaml
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
```
|
||||
|
||||
### Why This Works
|
||||
|
||||
1. **Direct URL Authentication**: Token is embedded in the URL that npm ci reads
|
||||
2. **No Reliance on Git Config**: Doesn't depend on git config which npm ignores
|
||||
3. **Just-in-Time**: Token is injected at runtime, never committed to repo
|
||||
4. **Consistent Behavior**: Works across npm v7, v8, v9+ and all CI environments
|
||||
|
||||
### The Execution Order (Critical)
|
||||
```
|
||||
1. Checkout (persist-credentials: false)
|
||||
2. Configure git (defense in depth, may help in edge cases)
|
||||
3. Verify no SSH URLs (fail fast if lockfile is corrupted)
|
||||
4. Setup Node.js (restore npm cache)
|
||||
5. Inject token into package-lock.json ← THE KEY STEP
|
||||
6. npm ci (now has authenticated URL from lockfile)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Key Learnings
|
||||
|
||||
| Issue | What We Learned |
|
||||
|-------|----------------|
|
||||
| Git config ignored | npm ci reads package-lock.json directly, bypasses git config |
|
||||
| persist-credentials | Default checkout token can override custom PAT config |
|
||||
| npm v7+ behavior | Modern npm converts HTTPS to SSH for private repos if auth fails |
|
||||
| Token placement | Must inject token into lockfile URL, not just configure git |
|
||||
| sed is reliable | Runtime patching with sed is more reliable than git rewrites |
|
||||
| Local git config fails | npm's git subprocess doesn't honor local config consistently - even `git ls-remote` works but `npm install` still writes SSH |
|
||||
| Don't fight it locally | Stop trying to generate HTTPS lockfiles locally - accept SSH and patch in CI |
|
||||
|
||||
## 🎯 The One-Liner That Fixed It
|
||||
|
||||
**For HTTPS lockfiles:**
|
||||
```bash
|
||||
sed -i "s|https://github.com/Memo-2023/|https://${GH_TOKEN}@github.com/Memo-2023/|g" package-lock.json
|
||||
```
|
||||
|
||||
**For SSH lockfiles (if your local git config generates SSH URLs):**
|
||||
```bash
|
||||
sed -i "s|git+ssh://git@github.com/Memo-2023/|git+https://${GH_TOKEN}@github.com/Memo-2023/|g" package-lock.json
|
||||
```
|
||||
|
||||
These commands ensure npm gets an authenticated HTTPS URL, preventing the SSH fallback entirely.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Complete Working Workflow
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Configure git for private packages
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
|
||||
run: |
|
||||
git config --global url."https://${GH_TOKEN}@github.com/".insteadOf ssh://git@github.com/
|
||||
git config --global url."https://${GH_TOKEN}@github.com/".insteadOf git@github.com:
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'backend/package-lock.json'
|
||||
|
||||
- name: Patch package-lock.json with authenticated URLs
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
|
||||
run: |
|
||||
cd backend
|
||||
# Handle both SSH and HTTPS URLs
|
||||
if grep -q "git+ssh://git@github.com" package-lock.json; then
|
||||
echo "⚠️ SSH URLs found - patching to HTTPS with token..."
|
||||
sed -i "s|git+ssh://git@github.com/Memo-2023/|git+https://${GH_TOKEN}@github.com/Memo-2023/|g" package-lock.json
|
||||
echo "✓ Lockfile patched successfully"
|
||||
else
|
||||
echo "⚠️ HTTPS URLs found - injecting token..."
|
||||
sed -i "s|https://github.com/Memo-2023/|https://${GH_TOKEN}@github.com/Memo-2023/|g" package-lock.json
|
||||
echo "✓ Token injected successfully"
|
||||
fi
|
||||
|
||||
- name: Clear npm cache (if needed)
|
||||
run: npm cache clean --force || true
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd backend
|
||||
npm ci --loglevel verbose
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Required GitHub Secrets
|
||||
|
||||
Make sure you have set up in your repository:
|
||||
|
||||
- `GH_PERSONAL_TOKEN`: Personal Access Token with repo access
|
||||
- Scope: `repo` (Full control of private repositories)
|
||||
- Used for: Accessing private npm git dependencies
|
||||
|
||||
---
|
||||
|
||||
## 🎓 References
|
||||
|
||||
- [npm/cli Issue #2610](https://github.com/npm/cli/issues/2610) - NPM v7 uses SSH instead of explicit HTTPS
|
||||
- [GitHub Community Discussion #25936](https://github.com/orgs/community/discussions/25936) - Installing private GitHub repos via npm in GitHub Actions
|
||||
- [Stack Overflow: npm ignores git+https setting](https://stackoverflow.com/questions/69725809/npm-ignores-githttps-setting-and-uses-gitssh-in-package-lock-json)
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🆕 Update: Handling SSH URLs in Lockfile (2025-09-30)
|
||||
|
||||
If your local git config **always** generates SSH URLs in `package-lock.json` (despite attempts to fix it locally), you have two options:
|
||||
|
||||
### Option 1: Accept SSH and Patch in CI (Recommended)
|
||||
1. **Stop fighting with local git config** - it's unreliable
|
||||
2. **Commit the lockfile with SSH URLs** as-is
|
||||
3. **Use the flexible sed command** in CI that handles both SSH and HTTPS:
|
||||
|
||||
```yaml
|
||||
- name: Patch package-lock.json with authenticated URLs
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
|
||||
run: |
|
||||
cd backend
|
||||
if grep -q "git+ssh://git@github.com" package-lock.json; then
|
||||
sed -i "s|git+ssh://git@github.com/Memo-2023/|git+https://${GH_TOKEN}@github.com/Memo-2023/|g" package-lock.json
|
||||
else
|
||||
sed -i "s|https://github.com/Memo-2023/|https://${GH_TOKEN}@github.com/Memo-2023/|g" package-lock.json
|
||||
fi
|
||||
```
|
||||
|
||||
### Option 2: Force HTTPS Locally (Fragile)
|
||||
If you insist on HTTPS lockfiles, you must ensure NO global git config rewrites exist:
|
||||
|
||||
```bash
|
||||
# Check for problematic rewrites
|
||||
git config --global --get-regexp url
|
||||
|
||||
# Remove them
|
||||
git config --global --unset-all url."git@github.com:".insteadOf
|
||||
git config --global --unset-all url."ssh://git@github.com/".insteadOf
|
||||
|
||||
# Regenerate lockfile
|
||||
rm package-lock.json
|
||||
npm install
|
||||
```
|
||||
|
||||
**Warning**: This changes your global git config and may break other workflows where you prefer SSH.
|
||||
|
||||
---
|
||||
|
||||
**Date Fixed:** 2025-09-29
|
||||
**Commit:** `5cce473` - fix: inject PAT token into package-lock.json for npm ci
|
||||
|
||||
**Updated:** 2025-09-30 - Added SSH lockfile handling documentation
|
||||
343
apps/maerchenzauber/docs/expo-sdk-54-upgrade.md
Normal file
343
apps/maerchenzauber/docs/expo-sdk-54-upgrade.md
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
# Expo SDK 54 Upgrade Guide für Märchenzauber
|
||||
|
||||
## 📋 Übersicht
|
||||
|
||||
Dieses Dokument beschreibt das Upgrade von **Expo SDK 51** (aktuell) auf **Expo SDK 54** für das Märchenzauber Projekt.
|
||||
|
||||
### Aktuelle Version
|
||||
- **Expo SDK**: 51.0.28
|
||||
- **React Native**: 0.74.5
|
||||
- **React**: 18.2.0
|
||||
|
||||
### Zielversion
|
||||
- **Expo SDK**: 54.0.0
|
||||
- **React Native**: 0.81.0
|
||||
- **React**: 19.1.0
|
||||
|
||||
## 🚀 Neue Features in SDK 54
|
||||
|
||||
### 1. Performance-Verbesserungen
|
||||
- **Precompiled XCFrameworks für iOS**: Reduziert Clean-Build-Zeiten von ~120 auf ~10 Sekunden
|
||||
- **Schnellere Builds**: Besonders bei großen Projekten spürbar
|
||||
|
||||
### 2. Native UI-Features
|
||||
- **Native Tabs (Beta)**: Liquid Glass Tabs mit automatischem Scrolling
|
||||
- **iOS 26 Support**: Liquid Glass Icons und Views
|
||||
- **Verbesserte Modals**: Web-Modals verhalten sich jetzt wie iPad/iPhone Modals
|
||||
|
||||
### 3. Technische Updates
|
||||
- **React Native 0.81** mit React 19.1
|
||||
- **Android 16 Target**: Edge-to-Edge standardmäßig aktiviert
|
||||
- **New Architecture Migration**: SDK 55 wird nur noch New Architecture unterstützen
|
||||
|
||||
### 4. API-Verbesserungen
|
||||
- **File System API**: Neue objektorientierte API
|
||||
- **SQLite localStorage**: Drop-in Ersatz für Web localStorage
|
||||
- **Streaming Support**: TextDecoderStream/TextEncoderStream für AI-Integration
|
||||
|
||||
## ⚠️ Breaking Changes
|
||||
|
||||
### 1. Kritische Änderungen
|
||||
|
||||
#### expo-av Deprecation
|
||||
```diff
|
||||
- import { Audio, Video } from 'expo-av';
|
||||
+ import { Audio } from 'expo-audio';
|
||||
+ import { Video } from 'expo-video';
|
||||
```
|
||||
**Wichtig**: expo-av wird in SDK 55 entfernt!
|
||||
|
||||
#### File System API
|
||||
```diff
|
||||
- import { ... } from 'expo-file-system/next';
|
||||
+ import { ... } from 'expo-file-system';
|
||||
// Legacy API verfügbar unter:
|
||||
+ import { ... } from 'expo-file-system/legacy';
|
||||
```
|
||||
|
||||
#### Reanimated v4
|
||||
- Nur New Architecture Support
|
||||
- Für Legacy Architecture: Bei Reanimated v3 bleiben
|
||||
|
||||
### 2. Platform-spezifische Änderungen
|
||||
|
||||
#### iOS
|
||||
- **Xcode Requirement**: Xcode 16.1+ (empfohlen: Xcode 26)
|
||||
- **iOS Minimum**: iOS 15.1
|
||||
|
||||
#### Android
|
||||
- **Target SDK**: Android 16
|
||||
- **Edge-to-Edge**: Standardmäßig aktiviert (nicht deaktivierbar)
|
||||
|
||||
## 📝 Upgrade-Schritte
|
||||
|
||||
### Schritt 1: Backup erstellen
|
||||
```bash
|
||||
# Git-Status prüfen
|
||||
git status
|
||||
|
||||
# Alle Änderungen committen
|
||||
git add .
|
||||
git commit -m "chore: backup before SDK 54 upgrade"
|
||||
|
||||
# Neuen Branch erstellen
|
||||
git checkout -b upgrade/expo-sdk-54
|
||||
```
|
||||
|
||||
### Schritt 2: Dependencies aktualisieren
|
||||
|
||||
#### Mobile App (apps/mobile/package.json)
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"expo": "~54.0.0",
|
||||
"expo-application": "~6.0.0",
|
||||
"expo-blur": "~14.0.0",
|
||||
"expo-clipboard": "~8.0.0",
|
||||
"expo-constants": "~17.0.0",
|
||||
"expo-dev-client": "~5.0.0",
|
||||
"expo-device": "~7.0.0",
|
||||
"expo-file-system": "~18.0.0",
|
||||
"expo-font": "~13.0.0",
|
||||
"expo-image": "~2.0.0",
|
||||
"expo-image-picker": "~16.0.0",
|
||||
"expo-linear-gradient": "~14.0.0",
|
||||
"expo-linking": "~7.0.0",
|
||||
"expo-localization": "~16.0.0",
|
||||
"expo-router": "~4.0.0",
|
||||
"expo-secure-store": "~14.0.0",
|
||||
"expo-splash-screen": "~0.29.0",
|
||||
"expo-status-bar": "~2.0.0",
|
||||
"expo-system-ui": "~4.0.0",
|
||||
"expo-web-browser": "~14.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-native": "0.81.0",
|
||||
"react-native-gesture-handler": "~2.22.0",
|
||||
"react-native-reanimated": "~3.16.0",
|
||||
"react-native-safe-area-context": "4.14.0",
|
||||
"react-native-screens": "4.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "~19.1.0",
|
||||
"jest-expo": "~54.0.0",
|
||||
"typescript": "~5.7.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Schritt 3: Installation durchführen
|
||||
```bash
|
||||
# Cache löschen
|
||||
cd apps/mobile
|
||||
rm -rf node_modules
|
||||
npm cache clean --force
|
||||
|
||||
# Dependencies installieren
|
||||
npm install
|
||||
|
||||
# Expo Doctor ausführen
|
||||
npx expo-doctor
|
||||
```
|
||||
|
||||
### Schritt 4: Native Directories zurücksetzen (wenn vorhanden)
|
||||
```bash
|
||||
# Alte native Directories löschen
|
||||
rm -rf ios android
|
||||
|
||||
# Neu generieren (wenn benötigt)
|
||||
npx expo prebuild --clean
|
||||
```
|
||||
|
||||
### Schritt 5: Code-Anpassungen
|
||||
|
||||
#### 1. File System API migrieren
|
||||
```typescript
|
||||
// ALT (SDK 51)
|
||||
import * as FileSystem from 'expo-file-system';
|
||||
|
||||
// NEU (SDK 54) - Für moderne API
|
||||
import { File, Directory } from 'expo-file-system';
|
||||
|
||||
// Oder für Legacy-Kompatibilität
|
||||
import * as FileSystem from 'expo-file-system/legacy';
|
||||
```
|
||||
|
||||
#### 2. Router Updates (v3 → v4)
|
||||
```typescript
|
||||
// Prüfe expo-router Imports und Konfiguration
|
||||
// Router v4 hat verbesserte TypeScript-Unterstützung
|
||||
```
|
||||
|
||||
#### 3. Native Tabs (Optional - Beta)
|
||||
```typescript
|
||||
// Neue native Tabs verwenden (Beta)
|
||||
import { Tabs } from 'expo-router/unstable-native-tabs';
|
||||
|
||||
// Liquid Glass Effekte automatisch verfügbar
|
||||
```
|
||||
|
||||
### Schritt 6: Metro-Konfiguration prüfen
|
||||
```javascript
|
||||
// metro.config.js
|
||||
// Entferne veraltete Overrides
|
||||
// Prüfe monorepo-spezifische Konfiguration
|
||||
```
|
||||
|
||||
### Schritt 7: Tests durchführen
|
||||
```bash
|
||||
# Unit Tests
|
||||
npm test
|
||||
|
||||
# Type Checking
|
||||
npm run type-check
|
||||
|
||||
# Linting
|
||||
npm run lint
|
||||
|
||||
# iOS testen
|
||||
npm run ios
|
||||
|
||||
# Android testen
|
||||
npm run android
|
||||
```
|
||||
|
||||
## 🔧 Spezifische Anpassungen für Märchenzauber
|
||||
|
||||
### 1. Image Generation
|
||||
- Replicate Integration sollte weiterhin funktionieren
|
||||
- Prüfe expo-image v2.0 Breaking Changes
|
||||
|
||||
### 2. Supabase Integration
|
||||
- Keine direkten Änderungen erwartet
|
||||
- Auth-Flow testen
|
||||
|
||||
### 3. Character/Story Features
|
||||
- File System API für Caching anpassen
|
||||
- Image Picker API prüfen
|
||||
|
||||
### 4. Performance-Optimierungen nutzen
|
||||
- iOS Builds werden deutlich schneller
|
||||
- Android Edge-to-Edge für bessere UX
|
||||
|
||||
## 📱 Neue Features für Märchenzauber nutzen
|
||||
|
||||
### Native Tabs für Story-Navigation
|
||||
```typescript
|
||||
import { Tabs } from 'expo-router/unstable-native-tabs';
|
||||
|
||||
// Liquid Glass Effekte für magische Navigation
|
||||
<Tabs
|
||||
screenOptions={{
|
||||
tabBarStyle: {
|
||||
// Automatische Liquid Glass Effekte
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tabs.Screen name="stories" />
|
||||
<Tabs.Screen name="characters" />
|
||||
</Tabs>
|
||||
```
|
||||
|
||||
### iOS 26 Liquid Glass Icons
|
||||
```json
|
||||
// app.json
|
||||
{
|
||||
"expo": {
|
||||
"ios": {
|
||||
"icon": "./assets/app.icon" // Neue .icon Datei
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Verbesserte Modal-Präsentation
|
||||
```typescript
|
||||
// Web-Modals verhalten sich jetzt nativ
|
||||
<Modal
|
||||
presentationStyle="pageSheet" // Funktioniert jetzt auch im Web
|
||||
animationType="slide"
|
||||
>
|
||||
{/* Story-Optionen */}
|
||||
</Modal>
|
||||
```
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Problem: Build-Fehler nach Upgrade
|
||||
```bash
|
||||
# Cache komplett zurücksetzen
|
||||
npx expo start -c
|
||||
rm -rf .expo
|
||||
watchman watch-del-all
|
||||
```
|
||||
|
||||
### Problem: Reanimated Fehler
|
||||
```bash
|
||||
# Bei Legacy Architecture bleiben
|
||||
npm install react-native-reanimated@3.16.0
|
||||
```
|
||||
|
||||
### Problem: Metro-Fehler
|
||||
```javascript
|
||||
// metro.config.js anpassen
|
||||
// Entferne metro/src/... Imports
|
||||
// Ersetze durch metro/private/...
|
||||
```
|
||||
|
||||
### Problem: Type-Fehler mit React 19
|
||||
```bash
|
||||
# TypeScript-Definitionen aktualisieren
|
||||
npm install --save-dev @types/react@~19.1.0
|
||||
```
|
||||
|
||||
## ✅ Checkliste
|
||||
|
||||
- [ ] Backup/Branch erstellt
|
||||
- [ ] Dependencies aktualisiert
|
||||
- [ ] expo-doctor ohne Fehler
|
||||
- [ ] File System API migriert
|
||||
- [ ] Tests laufen durch
|
||||
- [ ] iOS Build funktioniert
|
||||
- [ ] Android Build funktioniert
|
||||
- [ ] Story-Generation getestet
|
||||
- [ ] Character-Creation getestet
|
||||
- [ ] Image-Generation funktioniert
|
||||
- [ ] Auth-Flow funktioniert
|
||||
- [ ] Credits/Mana-System funktioniert
|
||||
|
||||
## 📚 Ressourcen
|
||||
|
||||
- [Expo SDK 54 Changelog](https://expo.dev/changelog/sdk-54)
|
||||
- [Upgrade Guide](https://docs.expo.dev/workflow/upgrading-expo-sdk-walkthrough/)
|
||||
- [New Architecture Guide](https://docs.expo.dev/guides/new-architecture/)
|
||||
- [React Native 0.81 Release Notes](https://reactnative.dev/blog)
|
||||
- [Reanimated v4 Migration](https://docs.swmansion.com/react-native-reanimated/docs/guides/migration-from-v3)
|
||||
|
||||
## 🎯 Nächste Schritte nach Upgrade
|
||||
|
||||
1. **Performance-Tests**: Vergleiche Build-Zeiten vorher/nachher
|
||||
2. **Native Features**: Evaluiere Native Tabs für bessere UX
|
||||
3. **New Architecture**: Plane Migration für SDK 55 Kompatibilität
|
||||
4. **Edge-to-Edge**: Nutze Android 16 Features für immersive Stories
|
||||
5. **iOS 26 Features**: Implementiere Liquid Glass Effekte
|
||||
|
||||
## ⏱️ Geschätzter Zeitaufwand
|
||||
|
||||
- **Vorbereitung**: 30 Minuten
|
||||
- **Upgrade durchführen**: 1-2 Stunden
|
||||
- **Testing**: 2-3 Stunden
|
||||
- **Fehlerbehebung**: 1-2 Stunden (je nach Komplexität)
|
||||
- **Gesamt**: ~1 Arbeitstag
|
||||
|
||||
## 🚨 Wichtige Hinweise
|
||||
|
||||
1. **SDK 55 Vorbereitung**: New Architecture wird Pflicht - jetzt schon planen!
|
||||
2. **expo-av Migration**: Muss vor SDK 55 abgeschlossen sein
|
||||
3. **Testing**: Besonders Auth-Flow und Credit-System gründlich testen
|
||||
4. **EAS Build**: Image auf `macos-sequoia-15.5-xcode-26.0` setzen für iOS 26 Features
|
||||
|
||||
---
|
||||
|
||||
**Letzte Aktualisierung**: Januar 2025
|
||||
**Märchenzauber Version**: Nach Upgrade auf SDK 54
|
||||
307
apps/maerchenzauber/docs/expo-ui.md
Normal file
307
apps/maerchenzauber/docs/expo-ui.md
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
# Expo UI Documentation
|
||||
|
||||
## Überblick
|
||||
|
||||
**Expo UI** (@expo/ui) ist eine innovative Bibliothek von nativen UI-Komponenten, die es ermöglicht, vollständig native Benutzeroberflächen mit **SwiftUI** (iOS) und **Jetpack Compose** (Android) direkt in React Native Apps zu erstellen. Die Bibliothek bringt moderne, deklarative UI-Frameworks direkt in React Native und ermöglicht es Entwicklern, die Vorteile beider Welten zu nutzen.
|
||||
|
||||
## Status und Verfügbarkeit
|
||||
|
||||
- **Aktueller Status**: Alpha (Stand: 2025)
|
||||
- **Verfügbarkeit**: Nur in Development Builds (nicht in Expo Go)
|
||||
- **Breaking Changes**: Häufig zu erwarten während der Alpha-Phase
|
||||
- **Priorität**: SwiftUI-Support zuerst, dann Jetpack Compose und Web/DOM
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npx expo install @expo/ui
|
||||
```
|
||||
|
||||
## Kernkonzepte
|
||||
|
||||
### Host Component
|
||||
|
||||
Die `Host`-Komponente ist der Container für alle Expo UI Komponenten. Sie funktioniert ähnlich wie:
|
||||
- `<svg>` für DOM
|
||||
- `<Canvas>` für react-native-skia
|
||||
|
||||
Unter der Haube verwendet sie `UIHostingController` um SwiftUI Views in UIKit zu rendern.
|
||||
|
||||
```javascript
|
||||
import { Host } from '@expo/ui/swift-ui';
|
||||
|
||||
<Host style={{ flex: 1 }}>
|
||||
{/* Expo UI Komponenten hier */}
|
||||
</Host>
|
||||
```
|
||||
|
||||
### 1-zu-1 Mapping
|
||||
|
||||
Expo UI bietet eine direkte Abbildung zu nativen UI-Frameworks:
|
||||
- SwiftUI Views für iOS
|
||||
- Jetpack Compose Components für Android
|
||||
|
||||
## Verfügbare Komponenten
|
||||
|
||||
### SwiftUI Components (@expo/ui/swift-ui)
|
||||
|
||||
| Komponente | Beschreibung |
|
||||
|------------|-------------|
|
||||
| `Host` | Container für SwiftUI Komponenten |
|
||||
| `Button` | Native Button mit System-Images |
|
||||
| `Text` | Native Text-Komponente |
|
||||
| `VStack` | Vertikales Layout |
|
||||
| `ContextMenu` | Kontextmenü |
|
||||
| `DateTimePicker` | Datum/Zeit-Auswahl |
|
||||
| `Picker` | Segmented und Wheel-Varianten |
|
||||
| `Slider` | Schieberegler |
|
||||
| `Switch` | Toggle/Schalter |
|
||||
| `LinearProgress` | Fortschrittsbalken |
|
||||
| `BottomSheet` | Bottom Sheet Modal |
|
||||
|
||||
### Jetpack Compose Components (@expo/ui/jetpack-compose)
|
||||
|
||||
| Komponente | Beschreibung |
|
||||
|------------|-------------|
|
||||
| `TextInput` | Native Texteingabe |
|
||||
| `Button` | Native Android Button |
|
||||
| Weitere Komponenten in Entwicklung |
|
||||
|
||||
## Code-Beispiele
|
||||
|
||||
### Basis-Beispiel mit SwiftUI
|
||||
|
||||
```javascript
|
||||
import { Host, VStack, Text, Button } from '@expo/ui/swift-ui';
|
||||
|
||||
function MyComponent() {
|
||||
return (
|
||||
<Host style={{ flex: 1 }}>
|
||||
<VStack spacing={8}>
|
||||
<Text>Willkommen bei Expo UI!</Text>
|
||||
<Button onPress={() => console.log('Geklickt!')}>
|
||||
Klick mich
|
||||
</Button>
|
||||
</VStack>
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Bottom Sheet Beispiel
|
||||
|
||||
```javascript
|
||||
import { BottomSheet, Host, Text } from '@expo/ui/swift-ui';
|
||||
import { useState } from 'react';
|
||||
import { useWindowDimensions } from 'react-native';
|
||||
|
||||
function BottomSheetExample() {
|
||||
const [isOpened, setIsOpened] = useState(false);
|
||||
const { width } = useWindowDimensions();
|
||||
|
||||
return (
|
||||
<Host style={{ position: 'absolute', width }}>
|
||||
<BottomSheet
|
||||
isOpened={isOpened}
|
||||
onIsOpenedChange={e => setIsOpened(e)}
|
||||
>
|
||||
<Text>Sheet-Inhalt hier</Text>
|
||||
</BottomSheet>
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Jetpack Compose TextInput
|
||||
|
||||
```javascript
|
||||
import { TextInput } from '@expo/ui/jetpack-compose';
|
||||
|
||||
function AndroidInput() {
|
||||
const [value, setValue] = useState('');
|
||||
|
||||
return (
|
||||
<TextInput
|
||||
autocorrection={false}
|
||||
defaultValue="Standardtext"
|
||||
onChangeText={setValue}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Integration mit React Native
|
||||
|
||||
### Mixing Components
|
||||
|
||||
Du kannst React Native Komponenten als JSX-Children von Expo UI Komponenten verwenden:
|
||||
|
||||
```javascript
|
||||
import { Host, VStack } from '@expo/ui/swift-ui';
|
||||
import { View, Text as RNText } from 'react-native';
|
||||
|
||||
function MixedComponent() {
|
||||
return (
|
||||
<Host style={{ flex: 1 }}>
|
||||
<VStack>
|
||||
{/* React Native Komponente innerhalb von Expo UI */}
|
||||
<View>
|
||||
<RNText>React Native Text</RNText>
|
||||
</View>
|
||||
</VStack>
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Expo UI erstellt automatisch einen `UIViewRepresentable` Wrapper für React Native Komponenten.
|
||||
|
||||
## Vorteile von Expo UI
|
||||
|
||||
### 1. Native Performance
|
||||
- Direkte Nutzung von SwiftUI und Jetpack Compose
|
||||
- Keine Bridge-Overhead für UI-Updates
|
||||
- Optimierte native Animationen und Transitions
|
||||
|
||||
### 2. Moderne UI-Patterns
|
||||
- Zugriff auf die neuesten nativen UI-Features
|
||||
- System-konsistentes Design out-of-the-box
|
||||
- Native Gesten und Interaktionen
|
||||
|
||||
### 3. Flexibilität
|
||||
- Full-App Support: Gesamte App in Expo UI schreibbar
|
||||
- Component-Level Mixing: Mische React Native, Expo UI, DOM und Custom 2D Components
|
||||
- Schrittweise Migration möglich
|
||||
|
||||
### 4. Developer Experience
|
||||
- TypeScript Support mit vollständigen Typen
|
||||
- Hot Reload Support
|
||||
- Vertraute React-Patterns
|
||||
|
||||
## Einschränkungen und Überlegungen
|
||||
|
||||
### Aktuelle Einschränkungen
|
||||
|
||||
1. **Alpha Status**: API kann sich häufig ändern
|
||||
2. **Dokumentation**: Noch nicht vollständig, nutze TypeScript-Typen zur API-Exploration
|
||||
3. **Platform Support**: SwiftUI-Support priorisiert, Jetpack Compose noch in Entwicklung
|
||||
4. **Expo Go**: Nicht unterstützt, Development Build erforderlich
|
||||
|
||||
### Performance-Überlegungen
|
||||
|
||||
- Host-Components haben einen gewissen Overhead
|
||||
- Für einfache UI-Elemente kann React Native effizienter sein
|
||||
- Ideal für komplexe, native UI-Patterns
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Strukturierung
|
||||
|
||||
```javascript
|
||||
// Separiere native UI in eigene Komponenten
|
||||
function NativeSheet({ children }) {
|
||||
return (
|
||||
<Host style={{ flex: 1 }}>
|
||||
<BottomSheet>
|
||||
{children}
|
||||
</BottomSheet>
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Platform-spezifischer Code
|
||||
|
||||
```javascript
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
const NativeButton = Platform.select({
|
||||
ios: require('@expo/ui/swift-ui').Button,
|
||||
android: require('@expo/ui/jetpack-compose').Button,
|
||||
});
|
||||
```
|
||||
|
||||
### 3. TypeScript nutzen
|
||||
|
||||
```typescript
|
||||
import type { ButtonProps } from '@expo/ui/swift-ui';
|
||||
|
||||
interface MyButtonProps extends ButtonProps {
|
||||
variant?: 'primary' | 'secondary';
|
||||
}
|
||||
```
|
||||
|
||||
## Zukunft von Expo UI
|
||||
|
||||
### Roadmap 2025
|
||||
|
||||
1. **Q1-Q2 2025**: Stabilisierung der SwiftUI-Integration
|
||||
2. **Q3 2025**: Vollständiger Jetpack Compose Support
|
||||
3. **Q4 2025**: Web/DOM Support
|
||||
4. **2026**: Stable Release geplant
|
||||
|
||||
### Geplante Features
|
||||
|
||||
- Mehr native Komponenten
|
||||
- Bessere React Native Integration
|
||||
- Custom Native Component Support
|
||||
- Theming und Styling System
|
||||
- Animation APIs
|
||||
|
||||
## Migration Guide
|
||||
|
||||
### Von React Native zu Expo UI
|
||||
|
||||
```javascript
|
||||
// Vorher (React Native)
|
||||
import { TouchableOpacity, Text } from 'react-native';
|
||||
|
||||
<TouchableOpacity onPress={handlePress}>
|
||||
<Text>Click me</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
// Nachher (Expo UI)
|
||||
import { Host, Button } from '@expo/ui/swift-ui';
|
||||
|
||||
<Host>
|
||||
<Button onPress={handlePress}>Click me</Button>
|
||||
</Host>
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Häufige Probleme
|
||||
|
||||
**Problem**: Components werden nicht angezeigt
|
||||
- **Lösung**: Stelle sicher, dass Components in einem `Host` gewrappt sind
|
||||
|
||||
**Problem**: Build-Fehler mit Expo Go
|
||||
- **Lösung**: Verwende Development Build: `npx expo run:ios` oder `npx expo run:android`
|
||||
|
||||
**Problem**: TypeScript-Fehler
|
||||
- **Lösung**: Update auf neueste @expo/ui Version
|
||||
|
||||
## Ressourcen
|
||||
|
||||
### Offizielle Dokumentation
|
||||
- [Expo UI Docs](https://docs.expo.dev/versions/latest/sdk/ui/)
|
||||
- [SwiftUI Guide](https://docs.expo.dev/guides/expo-ui-swift-ui/)
|
||||
- [GitHub Repository](https://github.com/expo/expo/tree/main/packages/expo-ui)
|
||||
|
||||
### Community
|
||||
- [Expo Discord](https://discord.gg/expo)
|
||||
- [GitHub Discussions](https://github.com/expo/expo/discussions)
|
||||
|
||||
### Beispiel-Projekte
|
||||
- [Liquid Glass App](https://expo.dev/blog/liquid-glass-app-with-expo-ui-and-swiftui)
|
||||
- [Live Activity Example](https://christopher.engineering/en/blog/live-activity-with-react-native/)
|
||||
|
||||
## Fazit
|
||||
|
||||
Expo UI repräsentiert einen innovativen Ansatz für React Native Development, der die Grenzen zwischen React Native und nativen UI-Frameworks verschwimmen lässt. Während es sich noch in der Alpha-Phase befindet, zeigt es bereits das Potenzial für die Zukunft der mobilen App-Entwicklung mit React Native.
|
||||
|
||||
Für das Märchenzauber-Projekt könnte Expo UI besonders interessant sein für:
|
||||
- Native Picker-Komponenten für Sprachauswahl
|
||||
- BottomSheets für Story-Optionen
|
||||
- Native Animationen für magische Übergänge
|
||||
- System-konsistente UI-Elemente
|
||||
Loading…
Add table
Add a link
Reference in a new issue