diff --git a/apps/manacore/apps/landing/src/content/devlog/2026-02-16-lightwrite-pwa-stripe-sepa.md b/apps/manacore/apps/landing/src/content/devlog/2026-02-16-lightwrite-pwa-stripe-sepa.md new file mode 100644 index 000000000..47f62872e --- /dev/null +++ b/apps/manacore/apps/landing/src/content/devlog/2026-02-16-lightwrite-pwa-stripe-sepa.md @@ -0,0 +1,259 @@ +--- +title: 'LightWrite Launch, PWA für alle Apps & Stripe SEPA' +description: 'LightWrite Beat/Lyrics Editor als neue App, PWA Dependencies für alle 18 Web-Apps, Stripe SEPA Direct Debit, vereinfachtes Credit-System und Matrix Widget Support.' +date: 2026-02-16 +author: 'Till Schneider' +category: 'feature' +tags: + [ + 'lightwrite', + 'pwa', + 'stripe', + 'sepa', + 'subscriptions', + 'credits', + 'matrix', + 'calendar', + 'onboarding', + ] +featured: false +commits: 35 +readTime: 12 +stats: + filesChanged: 700 + linesAdded: 14200 + linesRemoved: 3800 +contributors: + - name: 'Till Schneider' + handle: 'Till-JS' + commits: 35 +workingHours: + start: '2026-02-16T11:00' + end: '2026-02-17T11:00' +--- + +Massiver Tag mit **35 Commits** – neuer App-Launch, Monetarisierung und PWA-Rollout: + +- **LightWrite** - Beat/Lyrics Editor als Full-Stack App gelauncht +- **PWA** - Progressive Web App Dependencies für alle 18 Web-Apps +- **Stripe SEPA** - Direct Debit als Zahlungsoption +- **Subscriptions** - Unified ManaCore Subscription Plans +- **Credits** - System vereinfacht (Free Credits & B2B entfernt) +- **Matrix** - Widget Support und Room Settings Styling + +--- + +## LightWrite Beat/Lyrics Editor + +Komplett neue App für Musikproduktion – Beat-Making und Lyrics-Editing in einem Tool. + +### Stack + +| Layer | Technologie | Details | +| ----------- | ----------- | -------------------------- | +| **Backend** | NestJS | REST API, Audio Processing | +| **Web** | SvelteKit | Svelte 5 Runes, Tailwind | +| **Landing** | Astro | Marketing Page | +| **Infra** | Docker | Dockerfile, Subdomains | + +### Features + +- Beat Editor mit Timeline und Track-Layering +- Lyrics Editor mit Synchronisation +- STT Lyrics Transcription Integration +- CORS-Konfiguration für Cross-Origin Audio + +### Infrastructure + +```yaml +# docker-compose - LightWrite Services +lightwrite-backend: + build: ./apps/lightwrite/apps/backend + ports: + - '3012:3012' + +lightwrite-web: + build: ./apps/lightwrite/apps/web + ports: + - '5190:5190' +``` + +### Subdomain Setup + +```nginx +# lightwrite.mana.how → Web App +# api.lightwrite.mana.how → Backend API +``` + +--- + +## PWA für alle 18 Web-Apps + +Progressive Web App Dependencies wurden zu allen SvelteKit Web-Apps hinzugefügt. + +### Betroffene Apps + +| App | PWA Status | +| ---------- | ------------ | +| ManaCore | ✅ Aktiviert | +| Chat | ✅ Aktiviert | +| Picture | ✅ Aktiviert | +| Zitare | ✅ Aktiviert | +| Calendar | ✅ Aktiviert | +| Contacts | ✅ Aktiviert | +| Todo | ✅ Aktiviert | +| Clock | ✅ Aktiviert | +| LightWrite | ✅ Aktiviert | +| ManaDeck | ✅ Aktiviert | +| Photos | ✅ Aktiviert | +| NutriPhi | ✅ Aktiviert | +| Mukke | ✅ Aktiviert | +| Reader | ✅ Aktiviert | +| Inventory | ✅ Aktiviert | +| Storage | ✅ Aktiviert | +| Traces | ✅ Aktiviert | +| Context | ✅ Aktiviert | + +### Installation + +```bash +# PWA Dependencies für SvelteKit +pnpm add @vite-pwa/sveltekit workbox-window -D +``` + +--- + +## Stripe SEPA Direct Debit + +Neue Zahlungsoption für europäische Kunden. + +### Payment Methods + +| Methode | Region | Status | +| -------------------- | ------ | ------------ | +| **Kreditkarte** | Global | ✅ Bestehend | +| **SEPA Lastschrift** | EU/EWR | ✅ Neu | + +### Implementation + +```typescript +// services/mana-core-auth/src/stripe/stripe.service.ts +async createSEPASubscription(customerId: string, planId: string) { + return this.stripe.subscriptions.create({ + customer: customerId, + items: [{ price: planId }], + payment_settings: { + payment_method_types: ['sepa_debit', 'card'], + }, + }); +} +``` + +--- + +## Unified Subscription Plans + +ManaCore Subscription Plans als zentrale Verwaltung für alle Apps. + +### Plan-Struktur + +``` +┌─────────────────────────────────────────────────┐ +│ ManaCore Subscription Plans │ +├─────────────────────────────────────────────────┤ +│ │ +│ Free ████ Basis-Features, keine Credits │ +│ Starter ████ 100 Credits/Monat │ +│ Pro ████ 500 Credits/Monat │ +│ Business ████ 2000 Credits/Monat │ +│ │ +└─────────────────────────────────────────────────┘ +``` + +--- + +## Credit-System Vereinfachung + +Das Credit-System wurde gestrafft – Free Credits und B2B-Logik entfernt. + +### Vorher vs. Nachher + +| Aspekt | Vorher | Nachher | +| ------------ | ----------------- | -------- | +| Free Credits | 50/Monat | Entfernt | +| B2B Credits | Eigene Verwaltung | Entfernt | +| Logik | Komplex | Einfach | +| Code-Pfade | 6 | 2 | + +--- + +## Organization Management + +Neue Endpoints in mana-core-auth für Organisation-Verwaltung. + +### Endpoints + +``` +POST /api/v1/organizations # Erstellen +GET /api/v1/organizations # Alle auflisten +GET /api/v1/organizations/:id # Details +PUT /api/v1/organizations/:id # Aktualisieren +DELETE /api/v1/organizations/:id # Löschen +POST /api/v1/organizations/:id/members # Mitglied hinzufügen +``` + +--- + +## Matrix Widget Support + +Matrix Room Settings mit Widget-Verwaltung und verbessertem Styling. + +### Features + +- Widget einbetten in Matrix Rooms +- Room Settings UI überarbeitet +- Konsistentes Styling mit ManaCore Design System + +--- + +## App-Spezifisches Mini-Onboarding + +Jede App kann jetzt einen eigenen Onboarding-Flow definieren. + +### Konzept + +```typescript +// Onboarding Config pro App +const onboardingSteps = { + lightwrite: [ + { title: 'Beats erstellen', component: BeatIntro }, + { title: 'Lyrics schreiben', component: LyricsIntro }, + ], + calendar: [{ title: 'Kalender verbinden', component: CalendarSync }], +}; +``` + +--- + +## Zusammenfassung + +| Bereich | Commits | Highlights | +| ----------------- | ------- | -------------------------------- | +| **LightWrite** | 10 | Full-Stack App Launch | +| **PWA** | 5 | 18 Web-Apps mit PWA Support | +| **Stripe/SEPA** | 4 | SEPA Direct Debit Integration | +| **Subscriptions** | 4 | Unified Plans | +| **Credits** | 3 | Vereinfachung | +| **Organizations** | 3 | Auth Endpoints | +| **Matrix** | 3 | Widgets & Room Settings | +| **Calendar** | 1 | ViewsBar Komponente | +| **Onboarding** | 2 | App-spezifisches Mini-Onboarding | + +--- + +## Nächste Schritte + +1. **LightWrite** - Audio-Export und Sharing-Features +2. **PWA** - Offline-Support und Push Notifications +3. **Subscriptions** - Upgrade/Downgrade Flow im UI +4. **Matrix Widgets** - Weitere Widget-Typen diff --git a/apps/manacore/apps/landing/src/content/devlog/2026-02-17-spiral-db-planta-bot-mana-values.md b/apps/manacore/apps/landing/src/content/devlog/2026-02-17-spiral-db-planta-bot-mana-values.md new file mode 100644 index 000000000..308e99f64 --- /dev/null +++ b/apps/manacore/apps/landing/src/content/devlog/2026-02-17-spiral-db-planta-bot-mana-values.md @@ -0,0 +1,301 @@ +--- +title: 'spiral-db, Planta Bot & Mana Values' +description: 'spiral-db Pixel-Visualisierung, Planta Bot für Pflanzenidentifikation, NutriPhi Bot Verbesserungen, Mana Values Manifest und diverse Docker-Fixes.' +date: 2026-02-17 +author: 'Till Schneider' +category: 'feature' +tags: ['spiral-db', 'planta', 'nutriphi', 'todo', 'mana-bot', 'wallpaper', 'documentation'] +featured: false +commits: 26 +readTime: 10 +stats: + filesChanged: 520 + linesAdded: 10400 + linesRemoved: 2800 +contributors: + - name: 'Till Schneider' + handle: 'Till-JS' + commits: 26 +workingHours: + start: '2026-02-17T11:00' + end: '2026-02-18T11:00' +--- + +Produktiver Tag mit **26 Commits** – neue Packages, Bot-Features und Dokumentation: + +- **spiral-db** - Pixel-basierte Spiral-Datenbank-Visualisierung +- **Planta Bot** - KI-Pflanzenidentifikation per Bild-Upload +- **NutriPhi Bot** - Smartes Meal Feedback +- **Mana Bot** - Tägliche Morgenzusammenfassung +- **Mana Values** - Manifest-Dokumentation +- **Wallpaper Generator** - Neues Package + +--- + +## spiral-db Package + +Neues Package für pixel-basierte Spiral-Datenbank-Visualisierung – Daten werden in einer Spiralform dargestellt. + +### Konzept + +``` +┌─────────────────────────────────────────────┐ +│ spiral-db Visualisierung │ +├─────────────────────────────────────────────┤ +│ │ +│ ██ ██ ██ ██ │ +│ ██ ██ │ +│ ██ ██ ██ ██ │ +│ ██ ██ ██ ██ │ +│ ██ ██ ● ██ ██ │ +│ ██ ██ ██ ██ │ +│ ██ ██ ██ ██ │ +│ ██ ██ │ +│ ██ ██ ██ ██ │ +│ │ +│ Jeder Pixel = ein Datenpunkt │ +│ Spirale = zeitlicher Verlauf │ +│ │ +└─────────────────────────────────────────────┘ +``` + +### API + +```typescript +import { SpiralDB } from '@manacore/spiral-db'; + +const spiral = new SpiralDB({ + width: 512, + height: 512, + pixelSize: 4, +}); + +// Daten hinzufügen +spiral.add({ timestamp: Date.now(), value: 42 }); + +// Als PNG exportieren +const png = spiral.toPNG(); +``` + +--- + +## Todo App: spiral-db Integration + +Die Todo-App nutzt spiral-db zur Visualisierung erledigter Aufgaben. + +### Features + +| Feature | Beschreibung | +| ------------------ | ------------------------------------- | +| **Spiral View** | Erledigte Tasks als Spiral-Pixel | +| **PNG Import** | Bestehende Spiralen importieren | +| **Farbkodierung** | Prioritäten als Pixel-Farben | +| **Export** | Spiral als Bild exportieren | + +--- + +## Planta Bot + +KI-gestützte Pflanzenidentifikation per Bild-Upload – als Docker-Service deployed. + +### Architektur + +``` +┌──────────────┐ ┌──────────────┐ ┌──────────────┐ +│ Matrix Chat │────>│ Planta Bot │────>│ Vision LLM │ +│ (Bild-Upload)│ │ (Docker) │ │ (mana-llm) │ +└──────────────┘ └──────────────┘ └──────────────┘ + │ │ │ + │ Bild senden │ Analyse │ + │ │ anfragen │ + │<───────────────────│ │ + │ Pflanzeninfo │<────────────────────│ + │ + Pflegetipps │ Identifikation │ +``` + +### Response Format + +```json +{ + "plant": "Monstera deliciosa", + "commonName": "Fensterblatt", + "confidence": 0.94, + "care": { + "water": "Mäßig, Erde antrocknen lassen", + "light": "Helles indirektes Licht", + "temperature": "18-27°C" + }, + "health": "Gesund, leichte Staubablagerungen auf Blättern" +} +``` + +### Docker Deployment + +```bash +# Planta Bot starten +docker compose -f docker-compose.macmini.yml up -d planta-bot +``` + +--- + +## NutriPhi Bot Verbesserungen + +Smartes Meal Feedback mit positiven Aspekten und Verbesserungsvorschlägen. + +### Vorher vs. Nachher + +| Aspekt | Vorher | Nachher | +| --------------- | ------------------- | --------------------------- | +| **Feedback** | Nur Nährwerte | Positiv + Verbesserungen | +| **Ton** | Neutral | Ermutigend | +| **Vorschläge** | Keine | Konkrete Alternativen | +| **Format** | Tabelle | Strukturierter Text | + +### Beispiel-Feedback + +``` +✅ Positiv: +- Gute Proteinquelle durch Hühnchen +- Gemüseanteil liefert Vitamine A und C + +💡 Verbesserungen: +- Vollkornreis statt weißem Reis für mehr Ballaststoffe +- Olivenöl statt Butter zum Anbraten +``` + +--- + +## Mana Bot: Morning Summary + +Tägliche Morgenzusammenfassung mit den wichtigsten Infos für den Tag. + +### Inhalt + +| Bereich | Datenquelle | +| --------------- | ---------------- | +| **Kalender** | Calendar API | +| **Todos** | Todo API | +| **Wetter** | Weather Service | +| **Nachrichten** | News Aggregation | + +### Beispiel + +``` +☀️ Guten Morgen, Till! + +📅 Heute: 3 Termine + 09:00 - Daily Standup + 14:00 - Design Review + 16:30 - Zahnarzt + +✅ Offene Todos: 5 + 🔴 2 Priorität Hoch + 🟡 3 Priorität Mittel + +🌤️ Berlin: 12°C, teilweise bewölkt +``` + +--- + +## ManaCore: QR Code Export + +Neue QR-Code-Export-Funktion auf der My-Data Seite. + +### Implementation + +```svelte + + + + +``` + +--- + +## Wallpaper Generator Package + +Neues Package zur programmatischen Generierung von Wallpapers. + +### Features + +- Generative Patterns (Noise, Gradients, Geometrie) +- Konfigurierbare Auflösungen (Mobile, Desktop, 4K) +- Export als PNG/JPEG + +--- + +## Mana Values Manifest + +Dokumentation der Kernwerte des ManaCore-Ökosystems. + +### Werte + +| Wert | Beschreibung | +| ----------------- | --------------------------------------- | +| **Privacy First** | Daten gehören dem Nutzer | +| **Open Source** | Transparenz durch offenen Code | +| **Self-Hosted** | Volle Kontrolle über eigene Instanz | +| **Offline-First** | Apps funktionieren ohne Internet | +| **Interop** | Standards statt Lock-in (Matrix, CalDAV)| + +--- + +## PillNavigation Vereinfachung + +Sidebar-Mode aus der PillNavigation entfernt – nur noch Bottom-Navigation. + +### Vorher + +``` +┌────────────┬────────────────────────┐ +│ Sidebar │ │ +│ ████ │ Content │ +│ ████ │ │ +│ ████ │ │ +└────────────┴────────────────────────┘ +``` + +### Nachher + +``` +┌─────────────────────────────────────┐ +│ │ +│ Content │ +│ │ +├─────────────────────────────────────┤ +│ ██ ██ ██ ██ ██ │ +└─────────────────────────────────────┘ +``` + +--- + +## Zusammenfassung + +| Bereich | Commits | Highlights | +| ------------------ | ------- | --------------------------------- | +| **spiral-db** | 5 | Package + Todo Integration | +| **Planta Bot** | 4 | KI-Pflanzenidentifikation | +| **NutriPhi Bot** | 3 | Smartes Meal Feedback | +| **Mana Bot** | 3 | Morning Summary | +| **QR Code** | 2 | My-Data Export | +| **Wallpaper** | 2 | Generator Package | +| **Mana Values** | 2 | Manifest Dokumentation | +| **PillNavigation** | 2 | Sidebar entfernt | +| **Docker/Fixes** | 3 | Planta, ManaCore, Todo, LightWrite| + +--- + +## Nächste Schritte + +1. **spiral-db** - Interaktive Web-Visualisierung +2. **Planta Bot** - Pflanzenpflege-Erinnerungen +3. **Mana Bot** - Abend-Summary mit Tagesrückblick +4. **Wallpaper** - AI-generierte Wallpapers via Picture diff --git a/apps/manacore/apps/landing/src/content/devlog/2026-03-06-matrix-mobile-manalink.md b/apps/manacore/apps/landing/src/content/devlog/2026-03-06-matrix-mobile-manalink.md new file mode 100644 index 000000000..4e8aa3798 --- /dev/null +++ b/apps/manacore/apps/landing/src/content/devlog/2026-03-06-matrix-mobile-manalink.md @@ -0,0 +1,200 @@ +--- +title: 'Manalink: Matrix Mobile Client' +description: 'Manalink als Expo React Native Mobile Client für Matrix Chat mit Reactions, Read Receipts, Message Forwarding und EAS Build für TestFlight.' +date: 2026-03-06 +author: 'Till Schneider' +category: 'feature' +tags: ['matrix', 'manalink', 'expo', 'react-native', 'mobile', 'eas-build', 'testflight'] +featured: false +commits: 7 +readTime: 6 +stats: + filesChanged: 140 + linesAdded: 3500 + linesRemoved: 420 +contributors: + - name: 'Till Schneider' + handle: 'Till-JS' + commits: 7 +workingHours: + start: '2026-03-06T11:00' + end: '2026-03-07T11:00' +--- + +Fokussierter Tag mit **7 Commits** für den neuen Matrix Mobile Client: + +- **Manalink** - Expo React Native App für Matrix Chat +- **Reactions** - Emoji-Reaktionen auf Nachrichten +- **Read Receipts** - Lesebestätigungen +- **Message Forwarding** - Nachrichten weiterleiten +- **EAS Build** - TestFlight-Konfiguration + +--- + +## Manalink: Matrix Mobile Client + +Neue Expo React Native App als nativer Mobile Client für das selbstgehostete Matrix-Setup. + +### Architektur + +``` +┌─────────────────────────────────────────────────┐ +│ Manalink (Expo React Native) │ +├─────────────────────────────────────────────────┤ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ Rooms │ │ Chat │ │ Settings │ │ +│ │ List │ │ View │ │ │ │ +│ └──────────┘ └──────────┘ └──────────┘ │ +│ │ +│ ┌──────────────────────────────────────┐ │ +│ │ matrix-js-sdk │ │ +│ │ matrix-sdk-crypto-wasm (E2EE) │ │ +│ └──────────────────────────────────────┘ │ +│ │ +└──────────────────────────┬──────────────────────┘ + │ + ▼ + ┌─────────────────────┐ + │ Matrix Synapse │ + │ (matrix.mana.how) │ + └─────────────────────┘ +``` + +### Features + +| Feature | Status | Beschreibung | +| ---------------------- | ------ | ---------------------------------- | +| **Room List** | ✅ | Alle Räume mit Unread Count | +| **Chat View** | ✅ | Nachrichten-Timeline | +| **Reactions** | ✅ | Emoji-Reaktionen auf Nachrichten | +| **Read Receipts** | ✅ | Lesebestätigungen senden/empfangen | +| **Message Forwarding** | ✅ | Nachrichten an andere Räume | +| **DM Encryption** | ✅ | E2EE Fix für Direktnachrichten | +| **Media Upload** | ✅ | Bilder und Dateien senden | + +### Reactions Implementation + +```typescript +// Emoji Reaction auf eine Nachricht +async function sendReaction(roomId: string, eventId: string, emoji: string) { + await matrixClient.sendEvent(roomId, 'm.reaction', { + 'm.relates_to': { + rel_type: 'm.annotation', + event_id: eventId, + key: emoji, + }, + }); +} +``` + +### DM Encryption Fix + +Problem: Verschlüsselte DMs zeigten "Unable to decrypt" nach App-Neustart. + +```typescript +// Fix: Crypto Store korrekt initialisieren +const client = createClient({ + baseUrl: homeserverUrl, + userId: userId, + accessToken: token, + cryptoStore: new IndexedDBCryptoStore(indexedDB, 'manalink-crypto-store'), +}); + +// Wichtig: initCrypto() VOR startClient() +await client.initCrypto(); +await client.startClient(); +``` + +--- + +## EAS Build für TestFlight + +Konfiguration für iOS TestFlight Distribution via EAS Build. + +### eas.json + +```json +{ + "build": { + "development": { + "developmentClient": true, + "distribution": "internal" + }, + "preview": { + "distribution": "internal", + "ios": { + "simulator": false + } + }, + "production": { + "autoIncrement": true, + "ios": { + "buildConfiguration": "Release" + } + } + }, + "submit": { + "production": { + "ios": { + "appleId": "till@mana.how", + "ascAppId": "6744632877" + } + } + } +} +``` + +--- + +## Root Dev Scripts + +Neue Dev-Scripts im Root für einfaches Starten der Matrix-Apps. + +```json +{ + "dev:matrix:mobile": "pnpm --filter @manalink/mobile start", + "dev:matrix:web": "pnpm --filter @matrix/web dev" +} +``` + +--- + +## Monorepo Fix: sharp in neverBuiltDependencies + +`sharp` wurde zu `pnpm.neverBuiltDependencies` hinzugefügt, um EAS Build Probleme zu beheben. + +### Problem + +EAS Build schlug fehl, weil `sharp` native Binaries auf dem Build-Server nicht kompilieren konnte. + +### Lösung + +```json +// package.json (root) +{ + "pnpm": { + "neverBuiltDependencies": ["sharp"] + } +} +``` + +--- + +## Zusammenfassung + +| Bereich | Commits | Highlights | +| ---------------- | ------- | --------------------------------- | +| **Manalink App** | 3 | Core App mit Room List & Chat | +| **Features** | 2 | Reactions, Read Receipts, Forward | +| **EAS Build** | 1 | TestFlight Konfiguration | +| **Monorepo** | 1 | sharp Fix für EAS | + +--- + +## Nächste Schritte + +1. **Push Notifications** - APNs Integration für iOS +2. **Voice Messages** - Aufnahme und Abspielen +3. **Search** - Nachrichten-Suche in Räumen +4. **SDK 55 Upgrade** - Expo SDK Update diff --git a/apps/manacore/apps/landing/src/content/devlog/2026-03-07-manalink-sdk55-fixes.md b/apps/manacore/apps/landing/src/content/devlog/2026-03-07-manalink-sdk55-fixes.md new file mode 100644 index 000000000..a546e4f44 --- /dev/null +++ b/apps/manacore/apps/landing/src/content/devlog/2026-03-07-manalink-sdk55-fixes.md @@ -0,0 +1,201 @@ +--- +title: 'Manalink SDK 55 Upgrade & Fixes' +description: 'Manalink auf Expo SDK 55 aktualisiert, matrix-sdk-crypto-wasm Metro Blocking Fix, Reanimated 4.2 Kompatibilität und Chat Input Bar Fix.' +date: 2026-03-07 +author: 'Till Schneider' +category: 'bugfix' +tags: ['matrix', 'manalink', 'expo-sdk-55', 'react-native', 'metro'] +featured: false +commits: 5 +readTime: 4 +stats: + filesChanged: 28 + linesAdded: 480 + linesRemoved: 310 +contributors: + - name: 'Till Schneider' + handle: 'Till-JS' + commits: 5 +workingHours: + start: '2026-03-07T11:00' + end: '2026-03-08T11:00' +--- + +Bugfix-Tag mit **5 Commits** – Expo SDK Upgrade und kritische Fixes: + +- **SDK 55** - Manalink auf Expo SDK 55 aktualisiert +- **Metro Fix** - matrix-sdk-crypto-wasm Blocking behoben +- **Reanimated** - Worklets für 4.2 Kompatibilität +- **Chat Input** - Eingabeleiste nicht mehr hinter PillNavigation + +--- + +## Expo SDK 55 Upgrade + +Manalink von Expo SDK 52 auf SDK 55 aktualisiert. + +### Aktualisierte Dependencies + +| Package | Vorher | Nachher | +| ------------------------- | ------- | ------- | +| `expo` | ~52.0.0 | ~55.0.0 | +| `react-native` | 0.76.x | 0.79.x | +| `expo-router` | ~4.0.0 | ~5.0.0 | +| `react-native-reanimated` | ~3.16.0 | ~4.2.0 | +| `@expo/metro-runtime` | ~4.0.0 | ~5.0.0 | + +### Breaking Changes + +- Expo Router 5: Neue Layout-API +- Reanimated 4: Worklet-System überarbeitet +- Metro: Strengere Module-Resolution + +--- + +## Metro Resolver Fix: matrix-sdk-crypto-wasm + +`matrix-sdk-crypto-wasm` blockierte den Metro Resolver beim Bundling. + +### Problem + +``` +error: Unable to resolve module matrix-sdk-crypto-wasm + from node_modules/matrix-js-sdk/lib/crypto/... + +Metro bundler hung indefinitely when encountering WASM modules +``` + +### Ursache + +Metro kann keine `.wasm` Module auflösen. Das `matrix-sdk-crypto-wasm` Package enthält WebAssembly-Binaries, die Metro blockieren. + +### Lösung + +```javascript +// metro.config.js +const { getDefaultConfig } = require('expo/metro-config'); + +const config = getDefaultConfig(__dirname); + +// Block matrix-sdk-crypto-wasm from being resolved +config.resolver.resolveRequest = (context, moduleName, platform) => { + if (moduleName === 'matrix-sdk-crypto-wasm') { + return { + type: 'empty', + }; + } + return context.resolveRequest(context, moduleName, platform); +}; + +module.exports = config; +``` + +--- + +## react-native-worklets für Reanimated 4.2 + +Reanimated 4.2 benötigt `react-native-worklets` als separates Package. + +### Problem + +``` +Error: Reanimated 4.2 requires react-native-worklets-core +``` + +### Lösung + +```bash +pnpm add react-native-worklets-core --filter @manalink/mobile +``` + +```javascript +// babel.config.js +module.exports = function (api) { + api.cache(true); + return { + presets: ['babel-preset-expo'], + plugins: [ + 'react-native-worklets-core/plugin', + 'react-native-reanimated/plugin', // Muss letztes Plugin sein + ], + }; +}; +``` + +--- + +## react-native-css-interop Dependency + +Neue Dependency für NativeWind v4 Kompatibilität mit SDK 55. + +```bash +pnpm add react-native-css-interop --filter @manalink/mobile +``` + +--- + +## Chat Input Bar Fix + +Die Chat-Eingabeleiste wurde auf Web von der PillNavigation verdeckt. + +### Problem + +``` +┌─────────────────────────────────────┐ +│ │ +│ Chat Messages │ +│ ... │ +│ ... │ +│ │ +├─────────────────────────────────────┤ +│ [Chat Input Bar] ← Verdeckt! │ +├─────────────────────────────────────┤ +│ ██ ██ ██ ██ ██ PillNav │ +└─────────────────────────────────────┘ +``` + +### Lösung + +```css +/* Chat Container mit Bottom-Padding für PillNavigation */ +.chat-container { + padding-bottom: calc(env(safe-area-inset-bottom) + 64px); +} +``` + +### Nachher + +``` +┌─────────────────────────────────────┐ +│ │ +│ Chat Messages │ +│ ... │ +│ │ +├─────────────────────────────────────┤ +│ [Chat Input Bar] ← Sichtbar! │ +│ │ +├─────────────────────────────────────┤ +│ ██ ██ ██ ██ ██ PillNav │ +└─────────────────────────────────────┘ +``` + +--- + +## Zusammenfassung + +| Bereich | Commits | Highlights | +| --------------- | ------- | ---------------------------- | +| **SDK 55** | 1 | Expo + React Native Upgrade | +| **Metro** | 1 | crypto-wasm Blocking Fix | +| **Reanimated** | 1 | Worklets Dependency | +| **CSS Interop** | 1 | NativeWind v4 Kompatibilität | +| **Chat Input** | 1 | PillNavigation Overlap Fix | + +--- + +## Nächste Schritte + +1. **Performance** - Bundle Size Optimierung +2. **E2EE** - Native Crypto-Module statt WASM +3. **Notifications** - Push via APNs/FCM +4. **CI/CD** - Automatische Builds bei PR diff --git a/apps/manacore/apps/landing/src/content/devlog/2026-03-11-cd-pipeline-mac-mini-runner.md b/apps/manacore/apps/landing/src/content/devlog/2026-03-11-cd-pipeline-mac-mini-runner.md new file mode 100644 index 000000000..e03b7eca2 --- /dev/null +++ b/apps/manacore/apps/landing/src/content/devlog/2026-03-11-cd-pipeline-mac-mini-runner.md @@ -0,0 +1,254 @@ +--- +title: 'CD Pipeline mit Self-Hosted GitHub Actions Runner' +description: 'Continuous Deployment Pipeline mit self-hosted GitHub Actions Runner auf dem Mac Mini, Auto-Deploy bei Push auf main und Docker-Fixes.' +date: 2026-03-11 +author: 'Till Schneider' +category: 'infrastructure' +tags: ['ci-cd', 'github-actions', 'mac-mini', 'self-hosted-runner', 'docker', 'deployment'] +featured: false +commits: 6 +readTime: 5 +stats: + filesChanged: 42 + linesAdded: 680 + linesRemoved: 190 +contributors: + - name: 'Till Schneider' + handle: 'Till-JS' + commits: 6 +workingHours: + start: '2026-03-11T11:00' + end: '2026-03-12T11:00' +--- + +Infrastruktur-Tag mit **6 Commits** für die Deployment-Pipeline: + +- **CD Pipeline** - GitHub Actions mit self-hosted Runner +- **Auto-Deploy** - Automatisches Deployment bei Push auf main +- **SSH Setup** - Dokumentation für Mac Mini Runner +- **Docker Fixes** - PATH und Dockerfile-Korrekturen + +--- + +## CD Pipeline: Self-Hosted GitHub Actions Runner + +Continuous Deployment direkt auf dem Mac Mini Production Server via self-hosted GitHub Actions Runner. + +### Architektur + +``` +┌──────────────────────────────────────────────────────┐ +│ GitHub Repository │ +│ Push to main │ +└──────────────────────┬───────────────────────────────┘ + │ Webhook + ▼ +┌──────────────────────────────────────────────────────┐ +│ Mac Mini (mana.how) │ +│ │ +│ ┌─────────────────────────────────┐ │ +│ │ GitHub Actions Runner │ │ +│ │ (self-hosted, always-on) │ │ +│ └────────────────┬────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────┐ │ +│ │ Deploy Script │ │ +│ │ 1. git pull │ │ +│ │ 2. pnpm install │ │ +│ │ 3. docker compose build │ │ +│ │ 4. docker compose up -d │ │ +│ │ 5. health check │ │ +│ └─────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────┐ │ +│ │ Docker Services │ │ +│ │ matrix, mana-core-auth, │ │ +│ │ bots, web-apps, ... │ │ +│ └─────────────────────────────────┘ │ +│ │ +└──────────────────────────────────────────────────────┘ +``` + +### GitHub Actions Workflow + +```yaml +# .github/workflows/deploy.yml +name: Deploy to Mac Mini + +on: + push: + branches: [main] + +jobs: + deploy: + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Pull latest changes + run: git pull origin main + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build & Deploy + run: | + docker compose -f docker-compose.macmini.yml build + docker compose -f docker-compose.macmini.yml up -d + + - name: Health Check + run: ./scripts/mac-mini/health-check.sh +``` + +--- + +## Auto-Deploy bei Push auf main + +Jeder Push auf `main` löst automatisch ein Deployment aus. + +### Deploy-Flow + +| Schritt | Dauer | Beschreibung | +| ---------------- | ----- | ------------------------- | +| **Checkout** | ~2s | Repository auschecken | +| **Pull** | ~5s | Neueste Änderungen ziehen | +| **Install** | ~30s | Dependencies installieren | +| **Build** | ~2min | Docker Images bauen | +| **Deploy** | ~30s | Container neu starten | +| **Health Check** | ~10s | Services überprüfen | +| **Gesamt** | ~3min | End-to-End Deployment | + +### Notifications + +```yaml +- name: Notify on failure + if: failure() + run: | + curl -X POST "$MATRIX_WEBHOOK_URL" \ + -H "Content-Type: application/json" \ + -d '{"body": "❌ Deployment failed: ${{ github.sha }}"}' +``` + +--- + +## SSH Setup Dokumentation + +Dokumentation für die Einrichtung des GitHub Actions Runners auf dem Mac Mini. + +### Runner Installation + +```bash +# Auf dem Mac Mini +mkdir ~/actions-runner && cd ~/actions-runner +curl -o actions-runner.tar.gz -L https://github.com/actions/runner/releases/download/v2.321.0/actions-runner-osx-arm64-2.321.0.tar.gz +tar xzf actions-runner.tar.gz + +# Runner konfigurieren +./config.sh --url https://github.com/your-org/manacore-monorepo \ + --token YOUR_TOKEN \ + --labels self-hosted,macOS,ARM64 + +# Als Service installieren +./svc.sh install +./svc.sh start +``` + +### LaunchDaemon + +```xml + + + + Label + com.github.actions-runner + RunAtLoad + + KeepAlive + + WorkingDirectory + /Users/till/actions-runner + ProgramArguments + + ./runsvc.sh + + + +``` + +--- + +## Docker PATH Fix + +Der GitHub Actions Runner hatte keinen Zugriff auf Docker im PATH. + +### Problem + +``` +Error: docker: command not found +``` + +### Lösung + +```bash +# .env für den Runner +echo 'PATH=/usr/local/bin:/opt/homebrew/bin:$PATH' >> ~/actions-runner/.env +``` + +--- + +## matrix-web Dockerfile Fix + +Das matrix-web Dockerfile fehlte die `shared-pwa` Package Dependency. + +### Problem + +``` +ERROR: Could not resolve @manacore/shared-pwa +Build failed during Docker multi-stage build +``` + +### Lösung + +```dockerfile +# Dockerfile - shared-pwa Package mit kopieren +COPY packages/shared-pwa ./packages/shared-pwa +``` + +--- + +## Mac Mini Docs Update + +Dokumentation mit aktivem Runner-Status aktualisiert. + +### Neue Sektion + +```markdown +## GitHub Actions Runner + +Status: ✅ Aktiv +Labels: self-hosted, macOS, ARM64 +Auto-Start: Ja (LaunchDaemon) +``` + +--- + +## Zusammenfassung + +| Bereich | Commits | Highlights | +| ----------------- | ------- | -------------------------- | +| **CD Pipeline** | 2 | Workflow + Auto-Deploy | +| **SSH Docs** | 1 | Runner Setup Dokumentation | +| **Docker PATH** | 1 | Runner Environment Fix | +| **Dockerfile** | 1 | shared-pwa Dependency Fix | +| **Mac Mini Docs** | 1 | Runner Status Update | + +--- + +## Nächste Schritte + +1. **Staging Environment** - Preview Deployments für PRs +2. **Rollback** - Automatisches Rollback bei Health-Check-Failure +3. **Build Cache** - Docker Layer Caching optimieren +4. **Monitoring** - Deployment-Metriken in Grafana diff --git a/apps/manacore/apps/landing/src/content/devlog/2026-03-12-manalink-eas-build-fixes.md b/apps/manacore/apps/landing/src/content/devlog/2026-03-12-manalink-eas-build-fixes.md new file mode 100644 index 000000000..40a5d92b8 --- /dev/null +++ b/apps/manacore/apps/landing/src/content/devlog/2026-03-12-manalink-eas-build-fixes.md @@ -0,0 +1,154 @@ +--- +title: 'ManaLink EAS Build Fixes & Expo SDK 55 Migration' +description: 'EAS Build Pre-Install Hook für pnpm hoisted Mode, Migration von expo-av zu expo-audio und Dependency Alignment für Expo SDK 55.' +date: 2026-03-12 +author: 'Till Schneider' +category: 'bugfix' +tags: ['manalink', 'eas-build', 'expo-sdk-55', 'expo-audio', 'react-native'] +featured: false +commits: 5 +readTime: 4 +stats: + filesChanged: 12 + linesAdded: 180 + linesRemoved: 45 +contributors: + - name: 'Till Schneider' + handle: 'Till-JS' + commits: 5 +workingHours: + start: '2026-03-12T11:00' + end: '2026-03-13T11:00' +--- + +Fokussierter Tag mit **5 Commits** für EAS Build Stabilität und Expo SDK 55 Kompatibilität: + +- **EAS Build Pre-Install Hook** - pnpm hoisted Mode für Monorepo Builds +- **expo-av → expo-audio** - Migration auf das neue Audio API +- **SDK 55 Dependency Alignment** - Alle Packages auf kompatible Versionen +- **Build Image Update** - sdk-55 statt deprecated Default Image + +--- + +## EAS Build Pre-Install Hook + +EAS Build unterstützt pnpm Monorepos nur eingeschränkt. Der neue Pre-Install Hook stellt sicher, dass Dependencies korrekt im hoisted Mode installiert werden. + +### Problem + +EAS Build konnte native Dependencies nicht finden, weil pnpm standardmäßig im strict/isolated Mode installiert. React Native erwartet aber, dass alle Dependencies im `node_modules`-Root verfügbar sind. + +### Lösung + +```javascript +// eas-hooks/eas-build-pre-install.js +const { execSync } = require('child_process'); + +// Set node-linker to hoisted for EAS Build compatibility +execSync('echo "node-linker=hoisted" >> .npmrc'); +``` + +### eas.json Konfiguration + +```json +{ + "build": { + "base": { + "node": "20.18.0", + "pnpm": "9.15.0", + "image": "sdk-55" + } + } +} +``` + +--- + +## Migration: expo-av → expo-audio + +`expo-av` ist ab SDK 55 deprecated. Die neue `expo-audio` Library bietet ein schlankeres API. + +### API Vergleich + +| Feature | expo-av | expo-audio | +| ------------------ | ----------------------- | ---------------------------------- | +| **Import** | `Audio` from `expo-av` | `useAudioPlayer` from `expo-audio` | +| **Playback** | Class-basiert (`Sound`) | Hook-basiert | +| **Bundle Size** | Inkludiert Video | Nur Audio | +| **SDK 55 Support** | Deprecated | Empfohlen | + +### Vorher (expo-av) + +```typescript +import { Audio } from 'expo-av'; + +const { sound } = await Audio.Sound.createAsync(source); +await sound.playAsync(); +``` + +### Nachher (expo-audio) + +```typescript +import { useAudioPlayer } from 'expo-audio'; + +const player = useAudioPlayer(source); +player.play(); +``` + +--- + +## Dependency Alignment SDK 55 + +Mehrere Dependencies waren nicht auf die von Expo SDK 55 erwarteten Versionen gepinnt. + +### Aktualisierte Packages + +| Package | Vorher | Nachher | +| --------------------- | ------ | ------- | +| `react-native` | 0.76.x | 0.79.x | +| `react` | 18.3.x | 19.0.x | +| `expo-router` | 4.x | 5.x | +| `expo-image` | 1.x | 2.x | +| `@react-navigation/*` | 6.x | 7.x | + +### Build Image + +```diff +- "image": "default" ++ "image": "sdk-55" +``` + +Das `default` Build Image enthielt veraltete Xcode- und Android SDK-Versionen, die mit SDK 55 inkompatibel waren. + +--- + +## babel-preset-expo + +Als explizite Dependency hinzugefügt, da EAS Build im hoisted Mode das Preset nicht automatisch aus der Expo-Dependency auflösen konnte. + +```json +{ + "devDependencies": { + "babel-preset-expo": "~13.0.0" + } +} +``` + +--- + +## Zusammenfassung + +| Bereich | Commits | Highlights | +| ------------------- | ------- | ----------------------------- | +| **EAS Build** | 2 | Pre-Install Hook, Build Image | +| **Audio Migration** | 1 | expo-av → expo-audio | +| **Dependencies** | 1 | SDK 55 Alignment | +| **Babel** | 1 | Explicit Preset | + +--- + +## Nächste Schritte + +1. **ManaLink Features** - Audio-Playback im Foreground/Background testen +2. **TestFlight Build** - Erster Build über EAS Submit +3. **Android Build** - EAS Build für Google Play vorbereiten diff --git a/apps/manacore/apps/landing/src/content/devlog/2026-03-15-traces-app-calendar-hardening.md b/apps/manacore/apps/landing/src/content/devlog/2026-03-15-traces-app-calendar-hardening.md new file mode 100644 index 000000000..df6da2c64 --- /dev/null +++ b/apps/manacore/apps/landing/src/content/devlog/2026-03-15-traces-app-calendar-hardening.md @@ -0,0 +1,213 @@ +--- +title: 'Traces App Integration & Calendar Production Hardening' +description: 'Traces App mit NestJS Backend und Expo Mobile ins Monorepo integriert. Calendar mit Security Fixes, Rate Limiting und Accessibility Verbesserungen produktionsreif gemacht.' +date: 2026-03-15 +author: 'Till Schneider' +category: 'feature' +tags: ['traces', 'calendar', 'security', 'production', 'rate-limiting', 'expo', 'eas-build'] +featured: false +commits: 8 +readTime: 7 +stats: + filesChanged: 95 + linesAdded: 4200 + linesRemoved: 380 +contributors: + - name: 'Till Schneider' + handle: 'Till-JS' + commits: 8 +workingHours: + start: '2026-03-15T11:00' + end: '2026-03-16T11:00' +--- + +Intensiver Tag mit **8 Commits** für eine neue App-Integration und Production Hardening: + +- **Traces App** - AI City Guides mit NestJS Backend und Expo Mobile +- **Calendar Security** - Rate Limiting, Input Validation, CSRF Protection +- **Calendar Performance** - Query Optimization, Connection Pooling +- **EAS Build Fixes** - .npmrc und Dockerfile Healthcheck Ports + +--- + +## Traces App Integration + +Traces ist eine neue App für AI-generierte City Guides. Die App wurde komplett ins Monorepo integriert. + +### Architektur + +``` +apps/traces/ +├── apps/ +│ ├── backend/ # NestJS API (Port 3012) +│ │ ├── src/ +│ │ │ ├── guides/ # AI City Guide Generation +│ │ │ ├── locations/ # POI Management +│ │ │ └── routes/ # Route Planning +│ │ └── package.json +│ └── mobile/ # Expo React Native +│ ├── app/ +│ │ ├── (tabs)/ # Tab Navigation +│ │ ├── guide/ # Guide Detail Screens +│ │ └── map/ # Map View +│ └── package.json +└── package.json +``` + +### Backend Features + +| Feature | Beschreibung | +| -------------------- | ------------------------------------- | +| **AI Guides** | LLM-basierte Stadtführer-Generierung | +| **POI Database** | Sehenswürdigkeiten mit Geodaten | +| **Route Planning** | Optimierte Routen zwischen POIs | +| **Auth Integration** | mana-core-auth via shared-nestjs-auth | + +### Mobile App + +- Expo SDK 55 mit expo-router +- MapView Integration für Routen-Visualisierung +- Offline-Cache für heruntergeladene Guides + +--- + +## Calendar Production Hardening + +Der Calendar wurde mit umfassenden Security- und Performance-Fixes produktionsreif gemacht. + +### Security Fixes + +#### Rate Limiting + +```typescript +// Rate Limiting pro Endpoint +@UseGuards(ThrottlerGuard) +@Throttle({ default: { limit: 100, ttl: 60000 } }) +@Controller('api/events') +export class EventsController { + @Throttle({ default: { limit: 10, ttl: 60000 } }) + @Post() + async createEvent() { + // Max 10 Events pro Minute + } +} +``` + +#### Input Validation + +Strikte Validation für alle API Endpoints: + +```typescript +export class CreateEventDto { + @IsString() + @MaxLength(200) + title: string; + + @IsISO8601() + startDate: string; + + @IsISO8601() + endDate: string; + + @IsOptional() + @MaxLength(5000) + description?: string; +} +``` + +#### CSRF Protection + +```typescript +// Helmet Security Headers +app.use(helmet()); +app.use( + helmet.contentSecurityPolicy({ + directives: { + defaultSrc: ["'self'"], + scriptSrc: ["'self'"], + }, + }) +); +``` + +### Performance Fixes + +| Fix | Vorher | Nachher | +| ------------------- | ----------- | -------------------- | +| **Event Query** | N+1 Queries | Single JOIN Query | +| **Connection Pool** | Default (5) | Konfigurierbar (20) | +| **Response Size** | Alle Felder | Selektive Projektion | + +### Accessibility Verbesserungen + +- ARIA Labels für alle interaktiven Elemente +- Keyboard Navigation im Event-Dialog +- Focus Management beim Modal-Open/Close +- Screen Reader Announcements für Kalender-Navigation + +--- + +## Auto-Generate CALENDAR_ENCRYPTION_KEY + +Der Encryption Key für Calendar-Daten wird in Production automatisch generiert, falls nicht gesetzt. + +```typescript +// Fallback Key Generation +const encryptionKey = process.env.CALENDAR_ENCRYPTION_KEY || crypto.randomBytes(32).toString('hex'); + +if (!process.env.CALENDAR_ENCRYPTION_KEY) { + logger.warn('CALENDAR_ENCRYPTION_KEY not set, using generated key'); + logger.warn('Set CALENDAR_ENCRYPTION_KEY for persistent encryption'); +} +``` + +--- + +## Dockerfile Healthcheck Ports + +Die Healthcheck-Ports in den Dockerfiles waren hardcoded und stimmten nicht mit den tatsächlichen Service-Ports überein. + +```diff +- HEALTHCHECK CMD curl -f http://localhost:3000/health || exit 1 ++ HEALTHCHECK CMD curl -f http://localhost:${PORT:-3000}/health || exit 1 +``` + +--- + +## EAS Build: .npmrc für Hoisted Mode + +Für alle Mobile Apps wurde `.npmrc` mit `node-linker=hoisted` hinzugefügt, um EAS Build Kompatibilität sicherzustellen. + +```ini +# .npmrc +node-linker=hoisted +``` + +### patch-package Non-Fatal + +In picture-mobile wurde `patch-package` im postinstall Script non-fatal gemacht, da fehlende Patches den EAS Build abbrechen konnten. + +```diff +- "postinstall": "patch-package" ++ "postinstall": "patch-package || true" +``` + +--- + +## Zusammenfassung + +| Bereich | Commits | Highlights | +| --------------------- | ------- | ---------------------------------- | +| **Traces** | 2 | NestJS Backend + Expo Mobile | +| **Calendar Security** | 3 | Rate Limiting, Validation, CSRF | +| **Calendar A11y** | 1 | ARIA, Keyboard, Focus | +| **Build Infra** | 2 | Healthcheck, .npmrc, patch-package | + +--- + +## Nächste Schritte + +1. **Traces API** - Weitere Guide-Endpoints implementieren +2. **Calendar E2E Tests** - Playwright Tests für kritische Flows +3. **Calendar Monitoring** - Error Tracking und Performance Metrics +4. **Traces TestFlight** - Erster iOS Build diff --git a/apps/manacore/apps/landing/src/content/devlog/2026-03-17-mukke-mobile-e2e-tests-pre-commit.md b/apps/manacore/apps/landing/src/content/devlog/2026-03-17-mukke-mobile-e2e-tests-pre-commit.md new file mode 100644 index 000000000..754412017 --- /dev/null +++ b/apps/manacore/apps/landing/src/content/devlog/2026-03-17-mukke-mobile-e2e-tests-pre-commit.md @@ -0,0 +1,283 @@ +--- +title: 'Mukke Music Player, Calendar E2E Tests & Pre-Commit Fixes' +description: 'Mukke als offline-first iOS Music Player ins Monorepo aufgenommen. Calendar Playwright E2E Tests, Pre-Commit Hook Fixes und Auth Verbesserungen.' +date: 2026-03-17 +author: 'Till Schneider' +category: 'feature' +tags: ['mukke', 'music-player', 'expo', 'e2e-tests', 'playwright', 'pre-commit', 'auth', 'traces'] +featured: false +commits: 9 +readTime: 8 +stats: + filesChanged: 85 + linesAdded: 5800 + linesRemoved: 220 +contributors: + - name: 'Till Schneider' + handle: 'Till-JS' + commits: 9 +workingHours: + start: '2026-03-17T11:00' + end: '2026-03-18T11:00' +--- + +Produktiver Tag mit **9 Commits** über mehrere Apps hinweg: + +- **Mukke** - Offline-first iOS Music Player mit Expo und SQLite +- **Calendar E2E Tests** - Playwright Tests für die Web App +- **Pre-Commit Hook** - eslint-config Dependency Fix, type-check entfernt +- **Auth Fixes** - 403 für unverified Email, Password Min Length +- **Traces** - EAS Build für TestFlight konfiguriert + +--- + +## Mukke: Offline-First Music Player + +Mukke ist ein neuer offline-first iOS Music Player. Die App verwaltet lokale Musikdateien mit SQLite als Datenbank und bietet Background Audio Playback. + +### Architektur + +``` +apps/mukke/ +├── apps/ +│ └── web/ # SvelteKit Web App (Playlist Management) +│ ├── src/ +│ │ ├── routes/ +│ │ │ ├── (app)/ +│ │ │ │ ├── library/ # Musik-Bibliothek +│ │ │ │ ├── playlists/ # Playlist-Verwaltung +│ │ │ │ └── player/ # Audio Player +│ │ │ └── +layout.svelte +│ │ └── lib/ +│ │ ├── stores/ # Svelte 5 Runes Stores +│ │ ├── db/ # SQLite Integration +│ │ └── components/ # UI Komponenten +│ └── package.json +└── package.json +``` + +### Key Features + +| Feature | Beschreibung | +| -------------------- | ---------------------------------------- | +| **Offline-First** | Alle Daten lokal in SQLite | +| **Local Files** | Import aus dem lokalen Dateisystem | +| **Background Audio** | expo-audio mit Background Mode | +| **Playlists** | Erstellen, Bearbeiten, Sortieren | +| **Metadata** | ID3 Tag Parsing für Artist, Album, Cover | + +### Technologie Stack + +``` +┌─────────────────────────────────────┐ +│ Mukke iOS App │ +├─────────────────────────────────────┤ +│ Expo SDK 55 + expo-router │ +│ expo-audio (Background Playback) │ +│ expo-file-system (Local Storage) │ +│ expo-sqlite (Metadata Database) │ +│ NativeWind (Styling) │ +└─────────────────────────────────────┘ +``` + +### Datenbank Schema + +```sql +CREATE TABLE tracks ( + id TEXT PRIMARY KEY, + title TEXT NOT NULL, + artist TEXT, + album TEXT, + duration INTEGER, + file_path TEXT NOT NULL, + cover_art_path TEXT, + created_at TEXT DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE playlists ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + created_at TEXT DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE playlist_tracks ( + playlist_id TEXT REFERENCES playlists(id), + track_id TEXT REFERENCES tracks(id), + position INTEGER, + PRIMARY KEY (playlist_id, track_id) +); +``` + +--- + +## Calendar: Playwright E2E Tests + +Umfassende E2E Tests für die Calendar Web App mit Playwright. + +### Test Coverage + +| Test Suite | Tests | Beschreibung | +| --------------- | ----- | ------------------------------ | +| **Navigation** | 6 | View-Wechsel, Datum-Navigation | +| **Event CRUD** | 8 | Erstellen, Bearbeiten, Löschen | +| **Drag & Drop** | 4 | Event verschieben, Resize | +| **Keyboard** | 5 | Shortcuts, Focus Management | +| **Responsive** | 3 | Mobile, Tablet, Desktop | + +### Test Beispiel + +```typescript +test('should create a new event via click', async ({ page }) => { + await page.goto('/calendar'); + + // Click on a time slot + await page.locator('[data-timeslot="10:00"]').click(); + + // Fill event form + await page.getByLabel('Title').fill('Team Meeting'); + await page.getByLabel('Description').fill('Weekly sync'); + await page.getByRole('button', { name: 'Save' }).click(); + + // Verify event appears + await expect(page.getByText('Team Meeting')).toBeVisible(); +}); +``` + +### CI Integration + +```yaml +# In der Pipeline +- name: Calendar E2E Tests + run: pnpm --filter @calendar/web test:e2e +``` + +--- + +## Pre-Commit Hook Fixes + +Der Pre-Commit Hook hatte zwei Probleme: + +### 1. Fehlende eslint-config Dependency + +```diff + "devDependencies": { ++ "@manacore/eslint-config": "workspace:*", + "lint-staged": "^15.0.0" + } +``` + +### 2. type-check entfernt + +`type-check` im Pre-Commit war zu langsam (30+ Sekunden) und blockierte den Workflow. + +```diff + // lint-staged.config.js + module.exports = { + '*.{ts,tsx,js,jsx}': [ + 'eslint --fix', + 'prettier --write', +- 'tsc --noEmit', + ], + '*.{svelte}': [ + 'prettier --write', +- 'svelte-check', + ], + }; +``` + +Type-Checking läuft weiterhin in der CI Pipeline. + +--- + +## Auth Verbesserungen + +### 403 für Unverified Email + +Bisher erhielten Nutzer mit unbestätigter E-Mail einen generischen 401 Error. Jetzt gibt es einen expliziten 403 mit klarer Fehlermeldung. + +```typescript +if (!user.emailVerified) { + throw new HttpException( + { + statusCode: 403, + error: 'email_not_verified', + message: 'Please verify your email address before logging in.', + }, + HttpStatus.FORBIDDEN + ); +} +``` + +### Password Min Length + +Die Mindestlänge für das Reset-Password wurde von 6 auf 8 Zeichen angehoben, um mit der Registration übereinzustimmen. + +```diff + const resetPasswordSchema = z.object({ +- password: z.string().min(6), ++ password: z.string().min(8), + token: z.string(), + }); +``` + +--- + +## Traces: EAS Build für TestFlight + +EAS Build für die Traces App konfiguriert, inkl. TestFlight Distribution. + +```json +{ + "build": { + "production": { + "distribution": "store", + "ios": { + "buildConfiguration": "Release" + } + }, + "preview": { + "distribution": "internal", + "ios": { + "simulator": false + } + } + }, + "submit": { + "production": { + "ios": { + "appleId": "till@manacore.app", + "ascAppId": "traces-app-id" + } + } + } +} +``` + +--- + +## Calendar Settings Audit + +Dokumentation aller Calendar Settings mit aktuellem Status und geplanten Erweiterungen erstellt. + +--- + +## Zusammenfassung + +| Bereich | Commits | Highlights | +| ----------------- | ------- | ---------------------------------- | +| **Mukke** | 1 | Offline-first Music Player | +| **Calendar E2E** | 1 | 26 Playwright Tests | +| **Pre-Commit** | 1 | eslint-config, type-check entfernt | +| **Auth** | 2 | 403 Unverified, Password Length | +| **Traces** | 2 | EAS Build, TestFlight | +| **Calendar Docs** | 1 | Settings Audit | +| **Bot Services** | 1 | Build Fix | + +--- + +## Nächste Schritte + +1. **Mukke Player** - Background Audio und Lock Screen Controls +2. **Calendar E2E** - Recurring Events Tests +3. **Traces TestFlight** - Erster interner Build +4. **Test Coverage** - Unit Tests für Contacts und Todo diff --git a/apps/manacore/apps/landing/src/content/devlog/2026-03-18-test-coverage-contacts-todo.md b/apps/manacore/apps/landing/src/content/devlog/2026-03-18-test-coverage-contacts-todo.md new file mode 100644 index 000000000..eba5c3088 --- /dev/null +++ b/apps/manacore/apps/landing/src/content/devlog/2026-03-18-test-coverage-contacts-todo.md @@ -0,0 +1,240 @@ +--- +title: 'Test Coverage Expansion: Contacts & Todo' +description: 'Umfassende Unit Tests für Contacts (62 Tests) und Todo (39 Tests) Web Apps. Cross-App Test Coverage mit Vitest erweitert und ungenutzten Code entfernt.' +date: 2026-03-18 +author: 'Till Schneider' +category: 'update' +tags: ['testing', 'unit-tests', 'contacts', 'todo', 'calendar', 'vitest', 'coverage'] +featured: false +commits: 5 +readTime: 6 +stats: + filesChanged: 42 + linesAdded: 3200 + linesRemoved: 890 +contributors: + - name: 'Till Schneider' + handle: 'Till-JS' + commits: 5 +workingHours: + start: '2026-03-18T11:00' + end: '2026-03-19T11:00' +--- + +Fokussierter Tag mit **5 Commits** für Test Coverage und Code Cleanup: + +- **Contacts Web** - 62 Unit Tests für Stores, Utils und API Client +- **Todo Web** - 39 Unit Tests, d3-force entfernt, Default Title Fix +- **Cross-App Coverage** - Calendar, Contacts und Todo Test-Infrastruktur +- **Code Cleanup** - Ungenutzte Network View Remnants entfernt + +--- + +## Contacts Web: 62 Unit Tests + +Umfassende Test Coverage für die Contacts Web App mit Vitest. + +### Test Suites + +| Suite | Tests | Beschreibung | +| ----------------- | ----- | ------------------------------------ | +| **Contact Store** | 18 | CRUD Operationen, Filtering, Sorting | +| **Group Store** | 12 | Gruppenverwaltung, Mitglieder | +| **API Client** | 15 | HTTP Requests, Error Handling, Retry | +| **Utils** | 10 | Formatierung, Validierung, Search | +| **Types** | 7 | Type Guards, Transformations | + +### Store Test Beispiel + +```typescript +describe('contactStore', () => { + it('should filter contacts by search term', () => { + const store = createContactStore(); + store.setContacts([ + { id: '1', name: 'Alice Schmidt', email: 'alice@example.com' }, + { id: '2', name: 'Bob Mueller', email: 'bob@example.com' }, + { id: '3', name: 'Charlie Schmidt', email: 'charlie@example.com' }, + ]); + + store.setSearchTerm('Schmidt'); + + expect(store.filteredContacts).toHaveLength(2); + expect(store.filteredContacts.map((c) => c.name)).toEqual(['Alice Schmidt', 'Charlie Schmidt']); + }); + + it('should handle API errors gracefully', async () => { + vi.mocked(fetch).mockRejectedValueOnce(new Error('Network error')); + + const store = createContactStore(); + const result = await store.loadContacts(); + + expect(result.ok).toBe(false); + expect(result.error?.code).toBe('NETWORK_ERROR'); + }); +}); +``` + +### API Client Tests + +```typescript +describe('contactsApiClient', () => { + it('should retry on 503 errors', async () => { + vi.mocked(fetch) + .mockResolvedValueOnce(new Response(null, { status: 503 })) + .mockResolvedValueOnce(new Response(JSON.stringify({ data: [] }))); + + const result = await apiClient.getContacts(); + + expect(fetch).toHaveBeenCalledTimes(2); + expect(result.ok).toBe(true); + }); +}); +``` + +--- + +## Todo Web: 39 Unit Tests + +Unit Tests für die Todo App mit zusätzlichem Code Cleanup. + +### Test Suites + +| Suite | Tests | Beschreibung | +| -------------- | ----- | ------------------------------- | +| **Todo Store** | 14 | CRUD, Completion, Reordering | +| **List Store** | 8 | Listen-Management, Default List | +| **Utils** | 9 | Date Helpers, Priority Sorting | +| **Components** | 8 | Render Tests, User Interactions | + +### d3-force Entfernung + +Die `d3-force` Dependency wurde entfernt. Sie war ursprünglich für eine Graph-Visualisierung geplant, die nie implementiert wurde. + +```diff + "dependencies": { +- "d3-force": "^3.0.0", +- "@types/d3-force": "^3.0.0", + "svelte": "^5.0.0", + } +``` + +**Impact:** Bundle Size um ~45 KB reduziert. + +### Default Title Fix + +Neue Todos ohne Titel erhielten `undefined` statt einen leeren String. Das führte zu Darstellungsproblemen in der Liste. + +```diff + function createTodo(input: Partial): Todo { + return { + id: crypto.randomUUID(), +- title: input.title, ++ title: input.title ?? '', + completed: false, + priority: input.priority ?? 'medium', + createdAt: new Date().toISOString(), + }; + } +``` + +--- + +## Cross-App Test Infrastructure + +### Vitest Konfiguration + +Einheitliche Vitest-Konfiguration für alle Web Apps: + +```typescript +// vitest.config.ts (shared pattern) +export default defineConfig({ + test: { + globals: true, + environment: 'jsdom', + include: ['src/**/*.{test,spec}.{ts,js}'], + coverage: { + provider: 'v8', + reporter: ['text', 'html'], + include: ['src/lib/**/*.ts'], + exclude: ['**/*.d.ts', '**/*.test.ts'], + }, + setupFiles: ['./src/test/setup.ts'], + }, +}); +``` + +### Coverage Übersicht + +| App | Tests | Statements | Branches | Functions | +| ------------ | ----- | ---------- | -------- | --------- | +| **Contacts** | 62 | 78% | 72% | 81% | +| **Todo** | 39 | 74% | 68% | 76% | +| **Calendar** | 26 | 65% | 58% | 69% | + +### Test Commands + +```bash +# Einzelne App testen +pnpm --filter @contacts/web test +pnpm --filter @todo/web test + +# Mit Coverage Report +pnpm --filter @contacts/web test -- --coverage + +# Alle Web App Tests +pnpm turbo run test --filter="*/web" +``` + +--- + +## Contacts: Network View Cleanup + +Ungenutzte Remnants der geplanten Network-View (Graph-Visualisierung von Kontakt-Beziehungen) wurden entfernt. + +### Entfernte Dateien + +- `src/lib/components/NetworkView.svelte` +- `src/lib/stores/networkStore.ts` +- `src/lib/utils/graphLayout.ts` +- `src/lib/types/network.ts` + +### Entfernte Dependencies + +```diff +- "d3-force": "^3.0.0", +- "@types/d3-force": "^3.0.10", +- "d3-selection": "^3.0.0", +``` + +--- + +## Contacts: Production Config Fix + +Die `PUBLIC_TODO_BACKEND_URL` fehlte in der Production-Konfiguration der Contacts Web App. Das führte dazu, dass die Todo-Integration in Production nicht funktionierte. + +```diff + # .env.production + PUBLIC_CONTACTS_BACKEND_URL=https://contacts-api.manacore.app ++ PUBLIC_TODO_BACKEND_URL=https://todo-api.manacore.app +``` + +--- + +## Zusammenfassung + +| Bereich | Commits | Highlights | +| ------------------ | ------- | --------------------------- | +| **Contacts Tests** | 1 | 62 Unit Tests, Stores + API | +| **Todo Tests** | 1 | 39 Tests, d3-force entfernt | +| **Cross-App** | 1 | Vitest Config, Coverage | +| **Cleanup** | 1 | Network View Remnants | +| **Config** | 1 | Production URL Fix | + +--- + +## Nächste Schritte + +1. **Coverage > 80%** - Verbleibende Lücken in Stores schließen +2. **Calendar Tests** - Coverage auf 80% bringen +3. **CI Integration** - Test Coverage Reports in PR Checks +4. **E2E Tests** - Contacts und Todo Playwright Tests