📝 docs(devlog): add devlogs for Feb 12 and Feb 13

- Feb 12: GDPR Self-Service, Matrix Mobile UX, Mac Mini Stability
- Feb 13: Gift Codes, Stripe Integration, Zitare Deployment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Till-JS 2026-02-14 00:02:53 +01:00
parent 284cd004aa
commit 40a3c89852
2 changed files with 1145 additions and 0 deletions

View file

@ -0,0 +1,426 @@
---
title: 'GDPR Self-Service, Matrix Mobile UX & Mac Mini Stability'
description: 'Neue GDPR Self-Service Endpoints für Nutzer-Daten, Matrix Web Mobile-Navigation mit FAB und Room Restoration, Mac Mini Stability-Improvements mit Health Checks und Container Recovery'
date: 2026-02-12
author: 'Till Schneider'
category: 'feature'
tags:
[
'gdpr',
'dsgvo',
'matrix',
'mobile',
'mac-mini',
'stability',
'monitoring',
'docker',
'admin',
'health-checks',
]
featured: true
commits: 22
readTime: 10
stats:
filesChanged: 102
linesAdded: 9395
linesRemoved: 126
contributors:
- name: 'Till Schneider'
handle: 'Till-JS'
commits: 22
workingHours:
start: '2026-02-12T11:00'
end: '2026-02-13T11:00'
---
**22 Commits** mit Fokus auf DSGVO-Compliance, Mobile UX und Server-Stabilität:
- **GDPR Self-Service** - Neue Endpoints für User Data Export
- **Matrix Mobile UX** - FAB für Sidebar, Room Restoration
- **Mac Mini Stability** - Health Checks, Container Recovery, LaunchD Fixes
- **Monitoring** - Alerting Stack mit Maintenance Scripts
- **Admin API Fixes** - Controller Route Prefix Korrekturen
---
## GDPR Self-Service Endpoints
Neue Self-Service Endpoints für Nutzer, um ihre Daten einzusehen und zu exportieren.
### Architektur
```
┌─────────────────────────────────────────────────────────────────┐
│ GDPR Data Aggregation │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ User Request │ │
│ │ /me/data │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ ┌─────────────────────────────────────┐│
│ │ mana-core-auth │────>│ Backend Services (parallel fetch) ││
│ │ │ │ ││
│ │ /me/data │ │ Calendar │ Todo │ Contacts │ ... ││
│ └─────────────────┘ └─────────────────────────────────────┘│
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Aggregated │ │
│ │ User Data │ │
│ │ (JSON/ZIP) │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Neue Endpoints
```typescript
// mana-core-auth: Self-Service Data
GET /me/data // Aggregierte Daten aller Services
GET /me/data/export // ZIP-Download für DSGVO-Auskunft
DELETE /me/data // Account und alle Daten löschen (Art. 17)
// Backend Services: GDPR Endpoints
GET /admin/gdpr/users/:userId/data
DELETE /admin/gdpr/users/:userId/data
```
### Implementierung
```typescript
// auth: me.controller.ts
@Get('data')
@UseGuards(JwtAuthGuard)
async getUserData(@CurrentUser() user: CurrentUserData) {
const services = ['calendar', 'todo', 'contacts', 'photos', 'clock', 'storage'];
const dataPromises = services.map(async (service) => {
const url = this.configService.get(`${service.toUpperCase()}_BACKEND_URL`);
return this.fetchServiceData(url, user.userId);
});
const results = await Promise.allSettled(dataPromises);
return this.aggregateResults(results, services);
}
```
### Backend Integration
Neue GDPR Endpoints zu Photos, Clock und Storage Backends hinzugefügt:
| Backend | Endpoint | Daten |
| ------- | ---------------------------- | ------------------ |
| Photos | `/admin/gdpr/users/:id/data` | Fotos, Alben, EXIF |
| Clock | `/admin/gdpr/users/:id/data` | Timer, Sessions |
| Storage | `/admin/gdpr/users/:id/data` | Dateien, Ordner |
---
## Matrix Web Mobile UX
Verbesserte Mobile-Navigation für die Matrix PWA.
### FAB für Sidebar
```svelte
<!-- FloatingActionButton für Mobile Sidebar -->
<script lang="ts">
let { onOpenSidebar } = $props();
</script>
<button class="fab fixed bottom-20 right-4 z-50 md:hidden" onclick={onOpenSidebar}>
<MenuIcon />
</button>
```
### Room Restoration
Automatische Wiederherstellung des zuletzt ausgewählten Chats:
```typescript
// Beim App-Start: Letzten Room wiederherstellen
onMount(() => {
const lastRoomId = localStorage.getItem('matrix:lastRoom');
if (lastRoomId && rooms.find((r) => r.roomId === lastRoomId)) {
selectRoom(lastRoomId);
}
});
// Bei Room-Wechsel: Speichern
function selectRoom(roomId: string) {
currentRoomId = roomId;
localStorage.setItem('matrix:lastRoom', roomId);
}
```
### Message Interface Fix
Fehlende Props zur Message.svelte Interface hinzugefügt:
```typescript
interface MessageProps {
message: MatrixMessage;
isOwn: boolean;
showAvatar: boolean;
// Neu hinzugefügt:
onReply?: (msg: MatrixMessage) => void;
onReact?: (msg: MatrixMessage, emoji: string) => void;
}
```
---
## Mac Mini Stability Improvements
Umfangreiche Verbesserungen für die Server-Stabilität.
### Health Check Updates
```yaml
# docker-compose.macmini.yml
services:
mana-core-auth:
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://localhost:3001/health']
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
zitare-backend:
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://localhost:3007/health']
# Korrigierter Pfad (vorher /api/health)
```
### Container Recovery Script
```bash
#!/bin/bash
# scripts/mac-mini/container-recovery.sh
UNHEALTHY=$(docker ps --filter "health=unhealthy" --format "{{.Names}}")
for container in $UNHEALTHY; do
echo "Restarting unhealthy container: $container"
docker restart "$container"
# Warte auf Health Check
sleep 30
# Prüfe Status
STATUS=$(docker inspect --format='{{.State.Health.Status}}' "$container")
if [ "$STATUS" != "healthy" ]; then
echo "WARNING: $container still unhealthy after restart"
fi
done
```
### LaunchD Plist Fix
```xml
<!-- com.mana.container-recovery.plist -->
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.mana.container-recovery</string>
<key>ProgramArguments</key>
<array>
<string>/Users/till/projects/manacore-monorepo/scripts/mac-mini/container-recovery.sh</string>
</array>
<key>StartInterval</key>
<integer>300</integer> <!-- Alle 5 Minuten -->
<key>StandardOutPath</key>
<string>/var/log/mana/container-recovery.log</string>
</dict>
</plist>
```
### Disabled Services
Temporär deaktivierte Services (fehlende Deployments):
```yaml
# Auskommentiert bis Deployment fertig
# inventory-backend:
# nutriphi-backend:
# wisekeep-backend:
```
---
## Monitoring: Alerting Stack
Neues Alerting-System mit Prometheus und Discord Notifications.
### Alert Rules
```yaml
# prometheus/alerts.yml
groups:
- name: service_alerts
rules:
- alert: ServiceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: '{{ $labels.job }} is down'
- alert: HighMemoryUsage
expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: 'Memory usage above 90%'
- alert: DiskSpaceLow
expr: node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} < 0.1
for: 10m
labels:
severity: critical
annotations:
summary: 'Disk space below 10%'
```
### Maintenance Scripts
```bash
# scripts/mac-mini/maintenance.sh
# 1. Docker Cleanup
docker system prune -f --volumes
# 2. Log Rotation
find /var/log/mana -name "*.log" -mtime +7 -delete
# 3. Health Report
./scripts/mac-mini/health-report.sh | tee /var/log/mana/daily-health.log
```
---
## Admin API Fixes
Korrekturen für Controller Route Prefixes.
### Problem
Doppelte API-Prefixes führten zu 404-Fehlern:
```
GET /api/v1/api/v1/admin/users → 404
```
### Lösung
```typescript
// VORHER (falsch)
@Controller('api/v1/admin') // + Global Prefix = /api/v1/api/v1/admin
export class AdminController {}
// NACHHER (korrekt)
@Controller('admin') // + Global Prefix = /api/v1/admin
export class AdminController {}
```
### Betroffene Controller
| Service | Controller | Route |
| ------- | --------------- | ---------- |
| Auth | MeController | `/me/*` |
| Storage | AdminController | `/admin/*` |
---
## Docker Fixes
Mehrere Docker-Build Korrekturen.
### mana-search Symlink Fix
```dockerfile
# VORHER: Symlinks funktionieren nicht im Docker Context
COPY packages/shared-types ./packages/shared-types
# NACHHER: pnpm deploy für korrekte Dependencies
RUN pnpm --filter @mana-search/service deploy --prod ./deploy
FROM node:20-slim
COPY --from=build /app/deploy ./
```
### Local Builds auf Mac Mini
Weitere Services auf lokale Builds umgestellt:
```yaml
presi-backend:
build:
context: .
dockerfile: apps/presi/apps/backend/Dockerfile
# Statt: image: ghcr.io/till-js/presi-backend
skilltree-web:
build:
context: .
dockerfile: apps/skilltree/apps/web/Dockerfile
mana-search:
build:
context: .
dockerfile: services/mana-search/Dockerfile
```
### Shared Packages in ManaCore Web
```dockerfile
# Fehlende Packages hinzugefügt
COPY packages/shared-stores ./packages/shared-stores
COPY packages/shared-api-client ./packages/shared-api-client
COPY packages/shared-vite-config ./packages/shared-vite-config
```
---
## Calendar Database Fix
User ID Felder zu Text geändert:
```typescript
// VORHER (UUID)
userId: uuid('user_id').references(() => users.id);
// NACHHER (Text für externe Auth)
userId: text('user_id').notNull();
```
**Grund:** mana-core-auth verwendet String-basierte User IDs, nicht UUIDs.
---
## Zusammenfassung
| Bereich | Commits | Highlights |
| ---------------------- | ------- | --------------------------- |
| **GDPR Self-Service** | 4 | User Data Endpoints, Export |
| **Matrix Mobile** | 4 | FAB, Room Restore, Props |
| **Mac Mini Stability** | 5 | Health Checks, Recovery |
| **Monitoring** | 1 | Alerting Stack |
| **Admin API** | 3 | Route Prefix Fixes |
| **Docker** | 5 | Symlinks, Local Builds |
---
## Nächste Schritte
1. **GDPR Export UI** - Download-Button im mana.how Dashboard
2. **Matrix E2EE** - Ende-zu-Ende Verschlüsselung aktivieren
3. **Alertmanager** - Discord Webhook Integration
4. **Service Deployments** - Inventory, NutriPhi, WiseKeep

View file

@ -0,0 +1,719 @@
---
title: 'Gift Codes, Stripe Integration & Zitare Deployment'
description: 'Neues Gift Code System mit Credit-Gutscheinen, Stripe Integration für Subscriptions und Credit-Käufe, Zitare Production Deployment mit multilingualer Quote-Datenbank, sowie Calendar Drag-to-Create und Matrix WhatsApp-Style Navigation'
date: 2026-02-13
author: 'Till Schneider'
category: 'feature'
tags:
[
'gift-codes',
'stripe',
'subscriptions',
'credits',
'zitare',
'calendar',
'matrix',
'avatar',
'onboarding',
'docker',
'pwa',
]
featured: true
commits: 55
readTime: 18
stats:
filesChanged: 287
linesAdded: 20500
linesRemoved: 5752
contributors:
- name: 'Till Schneider'
handle: 'Till-JS'
commits: 55
workingHours:
start: '2026-02-13T11:00'
end: '2026-02-14T11:00'
---
Ein massiver Tag mit **55 Commits** und mehreren Major Features:
- **Gift Codes** - Credit-Gutscheine mit Code-Einlösung
- **Stripe Integration** - Subscriptions und Credit-Käufe
- **Zitare Deployment** - Production-Ready mit multilingualer Quote-DB
- **Calendar UX** - Drag-to-Create, Resize Handles, Live Preview
- **Matrix Mobile** - WhatsApp-Style Navigation für PWA
- **Avatar Upload** - S3/MinIO Integration mit Onboarding
- **ManaCore Dashboard** - Profile, Subscriptions, Credits UI
---
## Gift Codes & Credit System
Neues Geschenkkarten-System für Credit-Gutscheine.
### Architektur
```
┌─────────────────────────────────────────────────────────────────┐
│ Gift Code System │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Admin erstellt Code User löst Code ein │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ POST /gifts │ │ POST /gifts/ │ │
│ │ │ │ redeem │ │
│ │ code: MANA-XXX │ │ code: MANA-XXX │ │
│ │ credits: 100 │ │ │ │
│ │ maxUses: 10 │ └────────┬────────┘ │
│ └─────────────────┘ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Credit Balance │ │
│ │ += 100 Credits │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### API Endpoints
```typescript
// Gift Codes verwalten
POST /api/v1/gifts // Code erstellen (Admin)
GET /api/v1/gifts // Alle Codes auflisten
GET /api/v1/gifts/:code // Code-Details abrufen
POST /api/v1/gifts/redeem // Code einlösen (User)
DELETE /api/v1/gifts/:code // Code löschen
// Request Body: Code einlösen
{
"code": "MANA-WELCOME-2026"
}
// Response
{
"success": true,
"credits": 100,
"message": "100 Credits wurden deinem Konto gutgeschrieben!"
}
```
### Database Schema
```typescript
// auth.schema.ts
export const giftCodes = authSchema.table('gift_codes', {
id: text('id').primaryKey(),
code: text('code').notNull().unique(),
credits: integer('credits').notNull(),
maxUses: integer('max_uses').default(1),
currentUses: integer('current_uses').default(0),
expiresAt: timestamp('expires_at'),
createdBy: text('created_by').references(() => users.id),
createdAt: timestamp('created_at').defaultNow(),
});
export const giftRedemptions = authSchema.table('gift_redemptions', {
id: text('id').primaryKey(),
codeId: text('code_id').references(() => giftCodes.id),
userId: text('user_id').references(() => users.id),
redeemedAt: timestamp('redeemed_at').defaultNow(),
});
```
### Matrix Bot Integration
Gift Codes können auch via Matrix eingelöst werden:
```
User: !redeem MANA-WELCOME-2026
Bot: ✅ Code eingelöst! Du hast 100 Credits erhalten.
Aktuelles Guthaben: 250 Credits
```
---
## Stripe Integration
Vollständige Stripe-Anbindung für Payments.
### Subscription Plans
```typescript
// Subscription Tiers
const SUBSCRIPTION_PLANS = {
free: {
name: 'Free',
price: 0,
credits: 50, // monatlich
features: ['Basic Apps', '50 Credits/Monat'],
},
plus: {
name: 'Plus',
price: 4.99,
stripePriceId: 'price_plus_monthly',
credits: 500,
features: ['Alle Apps', '500 Credits/Monat', 'Priority Support'],
},
pro: {
name: 'Pro',
price: 14.99,
stripePriceId: 'price_pro_monthly',
credits: 2000,
features: ['Alle Apps', '2000 Credits/Monat', 'API Zugang', 'Priorität'],
},
};
```
### Credit Purchases
```typescript
// Einmal-Käufe
POST /api/v1/credits/purchase
{
"package": "credits_500" // 500 Credits für 4.99€
}
// Verfügbare Pakete
const CREDIT_PACKAGES = {
credits_100: { credits: 100, price: 0.99, stripePriceId: '...' },
credits_500: { credits: 500, price: 4.99, stripePriceId: '...' },
credits_1000: { credits: 1000, price: 8.99, stripePriceId: '...' },
credits_5000: { credits: 5000, price: 39.99, stripePriceId: '...' },
};
```
### Webhook Handler
```typescript
// stripe.controller.ts
@Post('webhook')
async handleWebhook(@Req() req: Request) {
const event = this.stripe.webhooks.constructEvent(
req.body,
req.headers['stripe-signature'],
this.webhookSecret,
);
switch (event.type) {
case 'checkout.session.completed':
await this.handleCheckoutComplete(event.data.object);
break;
case 'customer.subscription.updated':
await this.handleSubscriptionUpdate(event.data.object);
break;
case 'invoice.paid':
await this.handleInvoicePaid(event.data.object);
break;
}
}
```
---
## Zitare Production Deployment
Zitare ist jetzt live auf zitare.mana.how!
### Docker Infrastructure
```yaml
# docker-compose.macmini.yml
zitare-backend:
build:
context: .
dockerfile: apps/zitare/apps/backend/Dockerfile
ports:
- '3007:3007'
environment:
DATABASE_URL: ${ZITARE_DATABASE_URL}
MANA_CORE_AUTH_URL: http://mana-core-auth:3001
healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://localhost:3007/health']
zitare-web:
build:
context: .
dockerfile: apps/zitare/apps/web/Dockerfile
ports:
- '5018:5018'
depends_on:
- zitare-backend
```
### @zitare/content Package
Neues Package für shared Quotes:
```typescript
// packages/zitare-content/src/quotes.ts
export interface Quote {
id: string;
text: string;
author: string;
source?: string;
year?: number;
language: 'de' | 'en';
category: QuoteCategory;
tags: string[];
}
export const quotes: Quote[] = [
{
id: 'goethe-001',
text: 'Es ist nicht genug zu wissen, man muss auch anwenden...',
author: 'Johann Wolfgang von Goethe',
source: 'Wilhelm Meisters Wanderjahre',
year: 1829,
language: 'de',
category: 'wisdom',
tags: ['wissen', 'handeln', 'motivation'],
},
// ... 500+ Zitate
];
```
### Multilingual Support
```typescript
// Backend: Sprache aus Header
@Get('quote/daily')
getDailyQuote(@Headers('accept-language') lang: string) {
const language = lang?.startsWith('de') ? 'de' : 'en';
return this.quoteService.getDailyQuote(language);
}
// Frontend: i18n Integration
const { t, locale } = useTranslation();
const quote = await fetchDailyQuote($locale);
```
### Quote Metadata
Alle Zitate mit vollständigen Metadaten:
| Feld | Beschreibung |
| ---------- | ----------------------------------- |
| `author` | Vollständiger Name |
| `source` | Buch/Werk/Rede |
| `year` | Entstehungsjahr |
| `category` | wisdom, motivation, love, life, ... |
| `tags` | Suchbare Schlagwörter |
---
## Calendar UX Improvements
Mehrere UX-Verbesserungen für den Kalender.
### Drag-to-Create
Events können jetzt durch Drag & Drop erstellt werden:
```svelte
<script lang="ts">
let dragStart = $state<{ hour: number; day: Date } | null>(null);
let dragEnd = $state<{ hour: number; day: Date } | null>(null);
function handleMouseDown(hour: number, day: Date) {
dragStart = { hour, day };
}
function handleMouseMove(hour: number, day: Date) {
if (dragStart) {
dragEnd = { hour, day };
}
}
function handleMouseUp() {
if (dragStart && dragEnd) {
createEvent({
start: new Date(dragStart.day.setHours(dragStart.hour)),
end: new Date(dragEnd.day.setHours(dragEnd.hour)),
});
}
dragStart = null;
dragEnd = null;
}
</script>
```
### Live Time Preview
Beim Ziehen wird die neue Zeit live angezeigt:
```svelte
{#if dragStart && dragEnd}
<div class="preview-overlay">
{formatTime(dragStart.hour)} - {formatTime(dragEnd.hour)}
</div>
{/if}
```
### Resize Handles
Größere Resize-Handles für bessere Touch-Bedienbarkeit:
```css
.event-resize-handle {
height: 12px; /* Vorher: 6px */
cursor: ns-resize;
touch-action: none;
}
/* Mobile: Noch größer */
@media (max-width: 768px) {
.event-resize-handle {
height: 20px;
}
}
```
### Mobile UX
- Tasks standardmäßig ausgeblendet
- Auto-Scroll zur aktuellen Stunde
- Mikrofon-Button in der Input Bar integriert
- Padding für Bottom-UI Sichtbarkeit
---
## Matrix WhatsApp-Style Navigation
Neue Mobile-Navigation für die Matrix PWA.
### Navigation Pattern
```
┌─────────────────────────────────────────┐
│ ← Rooms Matrix Settings│ ← Header
├─────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────┐ │
│ │ General > │ │
│ ├─────────────────────────────────┤ │
│ │ Development > │ │
│ ├─────────────────────────────────┤ │
│ │ @user:mana.how > │ │
│ └─────────────────────────────────┘ │
│ │
│ │ ← Room List
│ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ + New Chat │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
↓ Tap on Room ↓
┌─────────────────────────────────────────┐
│ ← General ⋮ │ ← Room Header
├─────────────────────────────────────────┤
│ │
│ Alice: Hey, wie geht's? │
│ │
│ Bob: Gut, danke! │
│ │
│ Alice: Hast du das Feature gesehen? │
│ │
├─────────────────────────────────────────┤
│ [Message input...] Send │
└─────────────────────────────────────────┘
```
### iOS PWA Swipe-Back
```svelte
<script lang="ts">
let touchStartX = 0;
function handleTouchStart(e: TouchEvent) {
touchStartX = e.touches[0].clientX;
}
function handleTouchEnd(e: TouchEvent) {
const touchEndX = e.changedTouches[0].clientX;
const diff = touchEndX - touchStartX;
// Swipe from left edge
if (touchStartX < 30 && diff > 100) {
goBack();
}
}
</script>
<div ontouchstart={handleTouchStart} ontouchend={handleTouchEnd}>
<!-- Room Content -->
</div>
```
### Mobile Web App Meta Tags
```html
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
```
---
## Avatar Upload & Onboarding
Neues Avatar-System mit S3/MinIO.
### Upload Flow
```typescript
// POST /api/v1/me/avatar
@Post('avatar')
@UseInterceptors(FileInterceptor('avatar'))
async uploadAvatar(
@UploadedFile() file: Express.Multer.File,
@CurrentUser() user: CurrentUserData,
) {
// Resize und optimieren
const optimized = await sharp(file.buffer)
.resize(256, 256)
.webp({ quality: 80 })
.toBuffer();
// Upload zu S3/MinIO
const key = `avatars/${user.userId}.webp`;
await this.storageService.upload(key, optimized, {
contentType: 'image/webp',
public: true,
});
// URL speichern
await this.userService.updateAvatar(user.userId, key);
return { avatarUrl: this.storageService.getPublicUrl(key) };
}
```
### Onboarding Wizard
Neuer Wizard für neue Nutzer:
```
┌─────────────────────────────────────────┐
│ Welcome to ManaCore! │
├─────────────────────────────────────────┤
│ │
│ ┌───────────────┐ │
│ │ 📷 │ ← Avatar │
│ │ Upload Photo │ │
│ └───────────────┘ │
│ │
│ Display Name: [________________] │
│ │
│ Language: [Deutsch ▼] │
│ │
│ Theme: ○ Light ● Dark ○ Auto │
│ │
│ [ Continue → ] │
│ │
└─────────────────────────────────────────┘
```
---
## ManaCore Dashboard
Neues Dashboard auf mana.how.
### Profile Section
```svelte
<div class="profile-card">
<Avatar src={user.avatarUrl} size="lg" />
<h2>{user.name}</h2>
<p>{user.email}</p>
<div class="stats">
<Stat label="Credits" value={credits} />
<Stat label="Subscription" value={subscription.name} />
<Stat label="Member since" value={formatDate(user.createdAt)} />
</div>
</div>
```
### Subscription Management
```svelte
<SubscriptionCard
current={subscription}
plans={SUBSCRIPTION_PLANS}
onUpgrade={handleUpgrade}
onCancel={handleCancel}
/>
```
### Credits Frontend
```svelte
<CreditsDashboard>
<CreditBalance balance={credits} />
<CreditHistory {transactions} />
<CreditPurchase packages={CREDIT_PACKAGES} />
</CreditsDashboard>
```
### Storage Usage Widget
```svelte
<StorageUsageWidget
used={storageUsed}
total={storageTotal}
breakdown={[
{ label: 'Photos', size: photosSize, color: 'blue' },
{ label: 'Documents', size: docsSize, color: 'green' },
{ label: 'Other', size: otherSize, color: 'gray' },
]}
/>
```
### API Keys Management
```svelte
<ApiKeysManager
keys={apiKeys}
onCreate={createKey}
onRevoke={revokeKey}
services={['stt', 'tts', 'llm']}
/>
```
---
## Settings Stores
Neue Settings-Stores für Zitare und Todo.
### Pattern
```typescript
// stores/settings.store.ts
import { persisted } from 'svelte-persisted-store';
export interface AppSettings {
theme: 'light' | 'dark' | 'auto';
language: string;
notifications: boolean;
// App-spezifische Settings
}
export const settings = persisted<AppSettings>('app-settings', {
theme: 'auto',
language: 'de',
notifications: true,
});
```
### Zitare Settings
```typescript
interface ZitareSettings extends AppSettings {
dailyNotificationTime: string; // "09:00"
favoriteCategories: string[];
showAuthorInfo: boolean;
}
```
### Todo Settings
```typescript
interface TodoSettings extends AppSettings {
defaultPriority: Priority;
showCompletedTasks: boolean;
sortOrder: 'priority' | 'dueDate' | 'created';
}
```
---
## Devlog Activity Grid
Neue Activity-Seite für Devlogs.
### Features
- GitHub-Style Contribution Grid
- Commit-Statistiken pro Tag
- Hover-Details mit Commit-Count
- Link zu Devlog-Einträgen
### Implementation
```svelte
<ActivityGrid
data={devlogStats}
colorScale={['#eee', '#9be9a8', '#40c463', '#30a14e', '#216e39']}
cellSize={12}
gap={3}
/>
```
---
## Weitere Änderungen
### Shared UI Refactoring
LoginPage und InputBar Komponenten verbessert:
```typescript
// Bessere Props-Struktur
interface LoginPageProps {
locale: string;
onLogin: (credentials: LoginCredentials) => Promise<void>;
onRegister?: () => void;
onForgotPassword?: () => void;
showRememberMe?: boolean;
allowSocialLogin?: boolean;
}
```
### Matrix Bot Enhancements
- Stats Bot: Detailliertere Statistiken
- Todo Bot: Cleaner Response Messages
- Offline Mode entfernt - Login erforderlich
### Docker Local Builds
Weitere Services auf lokale Builds umgestellt:
| Service | Grund |
| ------------------- | -------------------- |
| matrix-todo-bot | Native Dependencies |
| matrix-calendar-bot | Native Dependencies |
| presi-backend | Schnellere Iteration |
| mana-web | Shared Packages |
---
## Zusammenfassung
| Bereich | Commits | Highlights |
| --------------------- | ------- | ------------------------------- |
| **Gift Codes** | 4 | Code-System, Matrix Integration |
| **Stripe** | 3 | Subscriptions, Credit Purchases |
| **Zitare** | 10 | Docker, Quotes, i18n |
| **Calendar** | 6 | Drag-Create, Resize, Mobile UX |
| **Matrix** | 8 | WhatsApp-Nav, PWA, Swipe |
| **ManaCore** | 8 | Profile, Credits, Storage |
| **Avatar/Onboarding** | 3 | S3 Upload, Wizard |
| **Settings** | 2 | Zitare, Todo Stores |
| **Auth/Docker** | 8 | Healthchecks, Builds |
| **Devlog** | 3 | Activity Grid |
---
## Nächste Schritte
1. **Stripe Webhooks** - Production Webhook Secret konfigurieren
2. **Gift Code UI** - Admin-Panel für Code-Erstellung
3. **Subscription Emails** - Bestätigungen und Erinnerungen
4. **Matrix E2EE** - Verschlüsselung für DMs aktivieren
5. **Zitare Push** - Daily Quote Notifications