fix(admin): storage backend needs api/v1 prefix in controller

Storage backend doesn't use setGlobalPrefix, so controller
needs full path @Controller('api/v1/admin')

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Till-JS 2026-02-12 13:59:33 +01:00
parent 42c0069553
commit cdb6e25885
9 changed files with 1955 additions and 11 deletions

View file

@ -0,0 +1,272 @@
---
title: '8 neue Matrix Bots, LLM Playground & Demo Mode Cleanup'
description: '8 spezialisierte Matrix Bots für verschiedene ManaCore Apps, SvelteKit LLM Playground UI mit allen Ollama-Modellen, und Entfernung des Demo Modes aus 6 Apps für klarere UX'
date: 2026-01-30
author: 'Till Schneider'
category: 'feature'
tags:
[
'matrix-bots',
'llm-playground',
'ollama',
'oidc',
'demo-mode',
'sveltekit',
'better-auth',
'shared-vite-config',
]
featured: false
commits: 41
readTime: 12
---
Produktiver Tag mit **41 Commits** und Fokus auf Matrix Bot Expansion und Developer Experience:
- **8 neue Matrix Bots** - Spezialisierte Bots für Planta, ManaDeck, Contacts, Picture, Chat, SkillTree, Presi, Questions
- **LLM Playground** - SvelteKit UI für alle Mac Mini Ollama-Modelle
- **Demo Mode Cleanup** - Entfernung aus 6 Apps für klarere Login-Flows
- **OIDC-Fixes** - Matrix Synapse als Trusted Client
---
## Neue Matrix Bots
8 neue spezialisierte Matrix Bots erstellt, die als NestJS Services laufen:
### Bot-Übersicht
| Bot | Port | Funktion |
| ---------------------- | ---- | ---------------------------------- |
| `matrix-planta-bot` | 3319 | Pflanzenpflege & Gieß-Erinnerungen |
| `matrix-manadeck-bot` | 3320 | Kartendecks & Lernkarten |
| `matrix-contacts-bot` | 3321 | Kontaktverwaltung |
| `matrix-picture-bot` | 3322 | AI-Bildgenerierung |
| `matrix-chat-bot` | 3323 | AI-Chat-Konversationen |
| `matrix-skilltree-bot` | 3324 | Skill-Tracking & XP |
| `matrix-presi-bot` | 3325 | Präsentationsverwaltung |
| `matrix-questions-bot` | 3326 | Q&A Research Management |
### Bot-Struktur
Alle Bots folgen dem gleichen Pattern:
```
services/matrix-{name}-bot/
├── src/
│ ├── bot/
│ │ ├── {name}.module.ts
│ │ └── {name}.service.ts
│ ├── health/
│ │ └── health.controller.ts
│ └── main.ts
├── Dockerfile
└── package.json
```
### Beispiel-Commands
**matrix-skilltree-bot:**
```
!skill list - Alle Skills anzeigen
!skill add "Coding" - Neuen Skill erstellen
!xp add Coding 50 - 50 XP zu Coding hinzufügen
!stats - Statistiken anzeigen
```
**matrix-picture-bot:**
```
!generate <prompt> - Bild generieren
!style <style> - Stil setzen (realistic, anime, etc.)
!variations - Variationen des letzten Bildes
```
---
## LLM Playground
Neue SvelteKit-Anwendung zum Testen aller verfügbaren LLM-Modelle.
### Features
| Feature | Beschreibung |
| -------------------- | ------------------------------- |
| **Model Selection** | Alle Mac Mini Ollama-Modelle |
| **Streaming** | SSE-basiertes Token-Streaming |
| **Chat History** | Konversations-Kontext |
| **Auth Integration** | Shared Auth UI mit ManaCore SSO |
### Verfügbare Modelle
```typescript
// apps/chat/apps/web/src/lib/config/models.ts
export const OLLAMA_MODELS = [
'gemma3:4b',
'gemma3:12b',
'llama3.2:3b',
'llama3.2:11b',
'mistral:7b',
'codellama:13b',
'deepseek-coder:6.7b',
'phi3:14b',
'qwen2.5:7b',
];
```
### Architektur
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ LLM Playground │────>│ mana-llm │────>│ Ollama │
│ (SvelteKit) │ │ (Port 3025) │ │ (Port 11434) │
│ Port 5197 │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
### Deployment
- Docker-Konfiguration für Production
- Shared-Auth-UI Integration
- Vite Config aus `@manacore/shared-vite-config`
---
## Demo Mode Cleanup
Entfernung des Demo Modes aus 6 Apps für klarere User Experience.
### Betroffene Apps
| App | Änderung |
| --------- | -------------------------------------- |
| Calendar | Demo Mode entfernt, Login erforderlich |
| Todo | Demo Mode entfernt, Login erforderlich |
| Contacts | Demo Mode entfernt, Login erforderlich |
| Clock | Demo Mode entfernt, Login erforderlich |
| Questions | Demo Mode entfernt, Login erforderlich |
| Chat | Demo Mode entfernt, Login erforderlich |
### Begründung
- **Klarere UX**: Kein Wechsel zwischen Guest/Auth-Modi
- **Einfacherer Code**: Keine Session-Storage-Logik
- **Konsistentes Verhalten**: Alle Apps gleich
- **SSO-Ready**: Nahtlose Auth über alle Apps
---
## OIDC-Verbesserungen
Fixes für die Matrix Synapse OIDC-Integration.
### Trusted Client Config
```typescript
// mana-core-auth: Better Auth OIDC Client
{
clientId: 'synapse',
clientSecret: process.env.MATRIX_OIDC_SECRET,
redirectUrls: [
'https://matrix.mana.how/_synapse/client/oidc/callback',
],
}
```
### Fixes
| Fix | Beschreibung |
| ----------------------- | --------------------------------------- |
| `redirectUrls` Property | Korrekter Property-Name für Better Auth |
| `client_id` Extraction | Aus returnUrl für Login-Flow |
| TypeScript Errors | OIDC-Login Controller |
| CSP Inline Scripts | Für OIDC Login Page |
---
## Shared Vite Config Integration
Integration von `@manacore/shared-vite-config` in alle Web-Apps.
### Vorher
```typescript
// Jede App hatte eigene Vite Config
export default defineConfig({
plugins: [tailwindcss(), sveltekit()],
server: { port: 5174 },
ssr: { noExternal: ['@manacore/shared-icons', ...] },
});
```
### Nachher
```typescript
import { createViteConfig, mergeViteConfig } from '@manacore/shared-vite-config';
export default defineConfig(
mergeViteConfig(createViteConfig({ port: 5174 }), { plugins: [tailwindcss(), sveltekit()] })
);
```
### Betroffene Apps
- calendar-web
- Alle Apps via Dockerfile-Updates
---
## Matrix Bots Standardisierung
Standardisierung aller 9+ Matrix Bots mit einheitlicher package.json.
### Einheitliche Dependencies
```json
{
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"matrix-bot-sdk": "^0.7.0"
}
}
```
### TypeScript Fixes
- Strict null checks behoben
- Einheitliche tsconfig
---
## Bugfixes
| Fix | Beschreibung |
| ------------------------- | -------------------------------------- |
| contacts-web syntax error | +layout.svelte Fix |
| calendar-web API calls | Client URL für Browser-Requests |
| calendar-web auth store | Initialisierung beim Mount |
| matrix-web SSR | Disabled für App-Routes ($state error) |
| mana-notify | Email-Benachrichtigungen deaktiviert |
---
## Zusammenfassung
| Bereich | Commits | Highlights |
| --------------------- | ------- | ------------------------------ |
| **Matrix Bots** | 8 | 8 neue spezialisierte Bots |
| **LLM Playground** | 3 | SvelteKit UI, Auth Integration |
| **Demo Mode Cleanup** | 6 | Entfernt aus 6 Apps |
| **OIDC** | 8 | Matrix Synapse Integration |
| **Shared Config** | 6 | Vite Config in alle Apps |
| **Bugfixes** | 10 | Web Apps, Matrix, Auth |
---
## Nächste Schritte
1. **Bot Migration** zu `@manacore/matrix-bot-common`
2. **LLM Playground** Production Deployment
3. **Voice Support** für Matrix Bots
4. **E2EE** für Matrix Client

View file

@ -0,0 +1,372 @@
---
title: 'Matrix Bot Konsolidierung, Voice Support & Manalink PWA'
description: 'Massive Konsolidierung aller 19 Matrix Bots mit @manacore/matrix-bot-common, Voice Input/Output für mana-mana-bot, Manalink PWA Rebrand, und Telegram-zu-Matrix Migration'
date: 2026-01-31
author: 'Till Schneider'
category: 'feature'
tags:
[
'matrix-bots',
'voice',
'pwa',
'manalink',
'consolidation',
'shared-packages',
'mana-media',
'telegram',
'refactoring',
'docker',
]
featured: true
commits: 52
readTime: 18
---
Intensiver Tag (und Nacht!) mit **52 Commits** - der Fokus lag auf der Konsolidierung der Matrix Bot Infrastruktur:
- **@manacore/matrix-bot-common** - Neues Shared Package für alle 19 Matrix Bots
- **Voice Support** - 4-Phasen-Implementierung für Voice Input/Output im mana-mana-bot
- **Manalink PWA** - Rebrand des Matrix Web Clients mit PWA-Support
- **Telegram Removal** - Migration zu Matrix-only Strategie
- **mana-media MVP** - Unified Media Processing Platform
- **Docker Restructure** - Neues Port-Schema und Naming Convention
---
## @manacore/matrix-bot-common
Neues Shared Package, das gemeinsame Funktionalität für alle Matrix Bots bereitstellt.
### Komponenten
```
packages/matrix-bot-common/
├── src/
│ ├── base/
│ │ └── BaseMatrixService.ts # Abstrakte Basisklasse
│ ├── health/
│ │ └── HealthController.ts # Shared Health Endpoint
│ ├── utils/
│ │ ├── KeywordCommandDetector.ts # Command Detection ohne !
│ │ └── UserListMapper.ts # User-Formatierung
│ └── index.ts
└── package.json
```
### BaseMatrixService
Abstrakte Basisklasse mit Matrix-Verbindungslogik:
```typescript
export abstract class BaseMatrixService implements OnModuleInit {
protected client: MatrixClient;
async onModuleInit() {
this.client = new MatrixClient(this.config.homeserverUrl, this.config.accessToken);
await this.client.start();
this.client.on('room.message', this.handleMessage.bind(this));
}
protected abstract handleMessage(roomId: string, event: any): Promise<void>;
}
```
### KeywordCommandDetector
Erkennt natürlichsprachliche Befehle ohne `!`-Prefix:
```typescript
const detector = new KeywordCommandDetector({
keywords: ['todo', 'aufgabe', 'task'],
patterns: [/(?:erinnere mich|remind me)/i],
});
// "Füge Einkaufen zur Todo-Liste" → detected
// "Was steht auf meiner Aufgabenliste?" → detected
```
### Migration
Alle 19 Matrix Bots wurden migriert:
| Phase | Bots | Änderungen |
| ----- | ---- | ---------------------- |
| 1 | 5 | HealthController |
| 2 | 5 | BaseMatrixService |
| 3 | 4 | UserListMapper |
| 4 | 5 | KeywordCommandDetector |
---
## Voice Support für matrix-mana-bot
4-Phasen-Implementierung von Voice Input/Output.
### Phase 1: Voice Input
```typescript
// Sprachnachrichten via mana-stt transkribieren
async handleVoiceMessage(event: MatrixEvent): Promise<string> {
const audioUrl = event.content.url;
const audioBuffer = await this.downloadMedia(audioUrl);
const transcription = await this.sttClient.transcribe(audioBuffer);
return transcription.text;
}
```
### Phase 2: Voice Output (TTS)
```typescript
// Text-zu-Sprache für Antworten
async sendVoiceReply(roomId: string, text: string): Promise<void> {
const audioBuffer = await this.ttsClient.synthesize(text, {
voice: 'de-DE-FlorianNeural',
speed: 1.0,
});
await this.client.sendAudio(roomId, audioBuffer, 'response.mp3');
}
```
### Phase 3: Smart Voice Formatting
Intelligente Aufbereitung von Text für Sprachausgabe:
| Input | Voice Output |
| -------- | --------------------------- |
| `15:30` | "fünfzehn Uhr dreißig" |
| `3.5kg` | "drei Komma fünf Kilogramm" |
| URLs | Werden übersprungen |
| Markdown | Wird entfernt |
### Phase 4: Persistent Voice Preferences
```typescript
// User-Präferenzen in Redis speichern
interface VoicePreferences {
enabled: boolean;
voice: string;
speed: number;
autoTranscribe: boolean;
}
await this.redis.hset(`voice:${userId}`, preferences);
```
---
## Manalink PWA
Rebrand des Matrix Web Clients zu "Manalink" mit PWA-Support.
### PWA-Features
| Feature | Beschreibung |
| ---------------------- | ---------------------- |
| **Installierbar** | Add to Home Screen |
| **Offline** | Service Worker Caching |
| **Push Notifications** | Web Push API |
| **App-Icon** | Custom Manalink Icon |
### Manifest
```json
{
"name": "Manalink",
"short_name": "Manalink",
"description": "ManaCore Matrix Client",
"start_url": "/",
"display": "standalone",
"theme_color": "#6366f1",
"background_color": "#0f172a"
}
```
### UX-Änderungen
- SSO als primärer Login (manueller Login versteckt)
- Vereinfachte Login-Seite
- Dark Mode als Default
---
## Telegram Removal
Strategische Entscheidung: Fokus auf Matrix als einzige Chat-Plattform.
### Entfernte Services
```
services/
├── telegram-ollama-bot/ # ENTFERNT
├── telegram-project-doc-bot/ # ENTFERNT
├── telegram-nutriphi-bot/ # ENTFERNT
├── telegram-todo-bot/ # ENTFERNT
└── telegram-zitare-bot/ # ENTFERNT
```
### Begründung
| Aspekt | Telegram | Matrix |
| ---------------- | --------- | -------- |
| **Self-Hosted** | Nein | Ja |
| **E2EE** | Optional | Standard |
| **Bot Platform** | Limitiert | Flexibel |
| **Integration** | Extern | Native |
---
## mana-media MVP
Unified Media Processing Platform für alle ManaCore Apps.
### Features
```
services/mana-media/
├── src/
│ ├── processing/
│ │ ├── image.service.ts # Resize, Crop, Format
│ │ ├── video.service.ts # Transcode, Thumbnail
│ │ └── audio.service.ts # Convert, Normalize
│ ├── storage/
│ │ └── s3.service.ts # MinIO/S3 Storage
│ └── metadata/
│ └── exif.service.ts # EXIF Extraction
└── Dockerfile
```
### API Endpoints
| Endpoint | Beschreibung |
| --------------------- | ---------------------- |
| `POST /process/image` | Bildverarbeitung |
| `POST /process/video` | Videokonvertierung |
| `GET /metadata/:id` | EXIF/Metadaten abrufen |
---
## Docker Restructure
Neue Port-Schema und Naming Convention für alle Services.
### Port Ranges
| Range | Typ |
| --------- | --------------------------------- |
| 3001-3099 | Core Services (Auth, Search, LLM) |
| 3100-3199 | App Backends |
| 3300-3399 | Matrix Bots |
| 5100-5199 | Web Apps |
| 8000-8099 | Infrastructure |
### Naming Convention
```yaml
# Vorher
container_name: chat-backend
container_name: todo-backend
# Nachher
container_name: mana-chat-backend
container_name: mana-todo-backend
```
---
## Bot Services Consolidation
Konsolidierung von SessionService und TranscriptionService.
### @manacore/bot-services Updates
```typescript
// Vorher: In jedem Bot
class SessionService {
private sessions = new Map();
}
// Nachher: Shared Package
import { SessionService } from '@manacore/bot-services';
```
### Shared Services
| Service | Funktion |
| ---------------------- | ------------------------ |
| `SessionService` | User Sessions über Redis |
| `TranscriptionService` | STT via mana-stt |
| `CreditService` | Credit-Verbrauch tracken |
---
## Model Comparison Feature
Neues Feature im LLM Playground für Modellvergleiche.
### UI
```typescript
// Gleichzeitig mehrere Modelle abfragen
const models = ['gemma3:4b', 'llama3.2:3b', 'mistral:7b'];
const responses = await Promise.all(models.map((model) => llmClient.chat(model, prompt)));
```
### Metriken
| Metrik | Beschreibung |
| -------------- | -------------------- |
| **Latency** | Time to first token |
| **Throughput** | Tokens per second |
| **Quality** | Subjektive Bewertung |
---
## Grafana & Prometheus Fixes
Zahlreiche Fixes für das Monitoring-System.
### Fixes
| Fix | Beschreibung |
| -------------------- | --------------------------- |
| VictoriaMetrics Port | 8428 → 9090 |
| Backend Ports | Korrekte Scrape Targets |
| Missing Services | Neu hinzugefügt |
| Home Dashboard | Master Overview als Default |
---
## Bugfixes
| Fix | Beschreibung |
| --------------------- | -------------------------------- |
| matrix-bot-common ESM | Explicit Imports für Node.js v25 |
| bot-services Build | Compile Step hinzugefügt |
| Type Errors | Web Apps, mana-media, calendar |
| tsconfig Issues | Alle NestJS Backends |
| matrix-mana-bot DI | Service Modules als Global |
---
## Zusammenfassung
| Bereich | Commits | Highlights |
| ---------------------- | ------- | ---------------------- |
| **matrix-bot-common** | 8 | Neues Shared Package |
| **Bot Migration** | 12 | 19 Bots konsolidiert |
| **Voice Support** | 4 | 4 Phasen implementiert |
| **Manalink PWA** | 2 | Rebrand + PWA |
| **Telegram Removal** | 1 | Matrix-only Strategie |
| **mana-media** | 2 | MVP implementiert |
| **Docker Restructure** | 1 | Neues Port-Schema |
| **Grafana/Prometheus** | 8 | Monitoring Fixes |
| **Bugfixes** | 14 | Build, Types, ESM |
---
## Nächste Schritte
1. **Matrix E2EE** aktivieren
2. **Voice Preferences UI** im Manalink Client
3. **mana-media** mit NutriPhi integrieren
4. **Matrix Bots CI/CD** Pipeline

View file

@ -0,0 +1,365 @@
---
title: 'SSD Migration, i18n für Auth Pages & Matrix Bots CI/CD'
description: 'PostgreSQL und MinIO auf SSD migriert, mehrsprachige Auth-Pages für alle Apps, automatisierte CI/CD Pipeline für 19 Matrix Bots, und erweiterte Grafana Dashboards'
date: 2026-02-01
author: 'Till Schneider'
category: 'infrastructure'
tags:
[
'ssd',
'migration',
'i18n',
'ci-cd',
'github-actions',
'matrix-bots',
'grafana',
'monitoring',
'oidc',
'production',
]
featured: false
commits: 42
readTime: 14
---
Produktiver Tag mit **42 Commits** und Fokus auf Infrastructure und Production Readiness:
- **SSD Migration** - PostgreSQL und MinIO auf externe SSD verschoben
- **i18n für Auth** - Alle Auth-Pages mehrsprachig (DE/EN)
- **Matrix Bots CI/CD** - Automatisierte GHCR Deployment Pipeline
- **Grafana Dashboards** - Master Overview mit Key Metrics
- **OIDC Production** - mana-core-auth vollständig produktionsreif
- **node-exporter** - Host System Metrics für Monitoring
---
## SSD Migration
Migration der Datenbanken auf externe SSD für bessere Performance.
### Migrierte Services
| Service | Vorher | Nachher |
| ------- | ------ | ------- |
| PostgreSQL | Docker Volume | `/Volumes/ManaData/postgres` |
| MinIO | Docker Volume | `/Volumes/ManaData/minio` |
### Docker Compose Änderungen
```yaml
services:
manacore-postgres:
volumes:
- /Volumes/ManaData/postgres:/var/lib/postgresql/data
manacore-minio:
volumes:
- /Volumes/ManaData/minio:/data
```
### Vorteile
| Aspekt | HDD (intern) | SSD (extern) |
| ------ | ------------ | ------------ |
| **Read Speed** | ~100 MB/s | ~500 MB/s |
| **Write Speed** | ~100 MB/s | ~450 MB/s |
| **IOPS** | ~100 | ~10.000 |
| **Latency** | ~10ms | ~0.1ms |
### Dokumentation
Neue SSD-Dokumentation unter `docs/MAC_MINI_SSD.md`:
- Mount-Konfiguration
- Backup-Strategie
- Performance-Benchmarks
---
## i18n für Auth Pages
Alle Authentifizierungs-Seiten sind jetzt mehrsprachig.
### Unterstützte Sprachen
| Sprache | Code | Status |
| ------- | ---- | ------ |
| Deutsch | `de` | Vollständig |
| English | `en` | Vollständig |
### Betroffene Apps
- Calendar Web
- Chat Web
- Clock Web
- Contacts Web
- NutriPhi Web
- Picture Web
- Planta Web
- Questions Web
- SkillTree Web
- Todo Web
- Zitare Web
### Implementierung
```typescript
// Locale Detection
const locale = navigator.language.startsWith('de') ? 'de' : 'en';
// i18n Store
export const t = derived(locale, ($locale) => {
return (key: string) => translations[$locale][key] || key;
});
```
### Neue Auth Pages
Fehlende Auth-Pages für Zitare und Planta hinzugefügt:
- `/login`
- `/register`
- `/forgot-password`
- `/reset-password`
- `/verify-email`
---
## Matrix Bots CI/CD
Automatisierte Build und Deployment Pipeline für alle Matrix Bots.
### GitHub Actions Workflow
```yaml
# .github/workflows/matrix-bots.yml
name: Matrix Bots CI/CD
on:
push:
paths:
- 'services/matrix-*-bot/**'
jobs:
build-and-push:
runs-on: ubuntu-latest
strategy:
matrix:
bot:
- matrix-mana-bot
- matrix-todo-bot
- matrix-calendar-bot
# ... alle 19 Bots
steps:
- uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/manacore/${{ matrix.bot }}:latest
```
### Betroffene Bots
| Bot | GHCR Image |
| --- | ---------- |
| matrix-mana-bot | `ghcr.io/manacore/matrix-mana-bot` |
| matrix-todo-bot | `ghcr.io/manacore/matrix-todo-bot` |
| matrix-calendar-bot | `ghcr.io/manacore/matrix-calendar-bot` |
| ... | ... (19 total) |
### ARM64 Workaround
QEMU-Emulation für ARM64 deaktiviert aufgrund von CI-Fehlern:
```yaml
platforms: linux/amd64 # ARM64 temporär deaktiviert
```
---
## Grafana Dashboards
Erweiterte Monitoring Dashboards.
### Master Overview
Neues Home Dashboard mit Key Metrics:
| Panel | Metrik |
| ----- | ------ |
| **Total Requests** | Summe aller HTTP Requests |
| **Requests/sec** | Aktuelle Request-Rate |
| **Error Rate** | HTTP 5xx Errors |
| **Response Time** | P95 Latency |
### System Overview
Neugeschrieben mit verfügbaren Metriken:
- CPU Usage (per Container)
- Memory Usage (per Container)
- Network I/O
- Disk Usage
### Infinity Datasource
Plugin für Business Metrics installiert:
```bash
grafana-cli plugins install yesoreyeram-infinity-datasource
```
---
## node-exporter
Host System Metrics für macOS Docker.
### Metriken
| Metrik | Beschreibung |
| ------ | ------------ |
| `node_cpu_seconds_total` | CPU-Nutzung |
| `node_memory_MemTotal_bytes` | Gesamter RAM |
| `node_filesystem_size_bytes` | Disk-Größe |
| `node_network_receive_bytes_total` | Netzwerk RX |
### macOS-spezifische Konfiguration
```yaml
node-exporter:
image: prom/node-exporter:latest
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev)($|/)'
```
---
## OIDC Production Readiness
mana-core-auth ist jetzt vollständig produktionsreif.
### Fixes
| Fix | Beschreibung |
| --- | ------------ |
| **EdDSA Signing** | OIDC id_token mit EdDSA statt RS256 |
| **JWT Issuer** | BASE_URL als Issuer |
| **Token Exchange** | body-parser für form-urlencoded |
| **Test Fixes** | Alle Tests grün |
### OIDC Token Exchange
```typescript
// Vorher: JSON only
app.use(express.json());
// Nachher: JSON + form-urlencoded
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
```
### Token Endpoint
```bash
# OAuth2 Token Request (form-urlencoded)
curl -X POST https://auth.mana.how/oidc/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&code=xxx&client_id=synapse"
```
---
## Resend Verification Email
Neues Feature auf der Registrierungsseite.
### UI
```svelte
{#if registrationSuccess && !verified}
<div class="alert">
<p>Bitte bestätige deine Email-Adresse.</p>
<button onclick={resendVerification}>
Bestätigungsmail erneut senden
</button>
</div>
{/if}
```
### API
```typescript
// POST /api/v1/auth/resend-verification
await authService.resendVerificationEmail(email);
```
---
## Cloudflared Port Updates
Alle Service-Ports in Cloudflared aktualisiert.
### Geänderte Ports
| Service | Alt | Neu |
| ------- | --- | --- |
| matrix.mana.how | 8008 | 4000 |
| matrix-web | 5178 | 5180 |
| element.mana.how | 80 | 8088 |
---
## Bugfixes
| Fix | Beschreibung |
| --- | ------------ |
| **Matrix SSO** | loginToken Callback Handler |
| **Bot Health Checks** | wget installiert in Docker |
| **Crypto Module** | E2EE via pnpm override deaktiviert |
| **Native Modules** | node:20-slim für Bot Images |
| **CORS Origins** | Alle Apps hinzugefügt |
| **Questions Locale** | 'de' als Fallback |
---
## Test User Seeding
Neuer Test-User für Development.
```typescript
// scripts/seed-dev.ts
await db.insert(users).values({
email: 't@t.de',
password: await hash('test1234'),
verified: true,
});
```
---
## Zusammenfassung
| Bereich | Commits | Highlights |
| ------- | ------- | ---------- |
| **SSD Migration** | 4 | PostgreSQL + MinIO |
| **i18n** | 3 | Alle Auth Pages DE/EN |
| **Matrix Bots CI/CD** | 2 | 19 Bots automatisiert |
| **Grafana** | 6 | Master Overview, Infinity |
| **node-exporter** | 3 | Host Metrics |
| **OIDC** | 8 | Production Ready |
| **Cloudflared** | 4 | Port Updates |
| **Bugfixes** | 12 | Docker, Matrix, Auth |
---
## Nächste Schritte
1. **Cross-Domain SSO** für alle Web Apps
2. **Matrix Bots** auf Mac Mini deployen
3. **Grafana Alerts** konfigurieren
4. **Backup Workflow** mit n8n

View file

@ -0,0 +1,406 @@
---
title: 'Cross-Domain SSO, mana-media Integration & Matrix Bots Page'
description: 'Cross-Subdomain SSO für alle .mana.how Apps, mana-media NutriPhi Integration, neue Bots-Übersichtsseite in Manalink, und mana-llm Production Deployment'
date: 2026-02-02
author: 'Till Schneider'
category: 'feature'
tags:
[
'sso',
'cross-domain',
'mana-media',
'matrix',
'bots',
'mana-llm',
'production',
'nutriphi',
'calendar',
'ux',
]
featured: true
commits: 40
readTime: 15
---
Produktiver Tag mit **40 Commits** und Fokus auf nahtlose Authentifizierung über alle Apps:
- **Cross-Domain SSO** - Single Sign-On für alle .mana.how Subdomains
- **mana-media Integration** - NutriPhi mit zentraler Medienverarbeitung
- **Matrix Bots Page** - Übersicht aller 19 Bots in Manalink
- **mana-llm Production** - LLM Gateway auf Mac Mini deployed
- **i18n für Matrix Bots** - Mehrsprachige Bot-Antworten
- **Calendar UX** - Tasks versteckt, automatischer Scroll zu Mittag
---
## Cross-Domain SSO
Single Sign-On über alle ManaCore Web Apps.
### Architektur
```
┌─────────────────────────────────────────────────────────────────┐
│ Cross-Domain SSO Flow │
├─────────────────────────────────────────────────────────────────┤
│ │
│ User besucht Session Check Bereits eingeloggt │
│ calendar.mana.how ─────────────────────> auth.mana.how │
│ │ │ │
│ │ Cookie gefunden │ │
│ │<──────────────────────────────────────│ │
│ │ auf .mana.how │ │
│ │ │ │
│ ▼ │
│ Automatisch eingeloggt │
│ (kein Login-Redirect) │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Cookie-Konfiguration
```typescript
// mana-core-auth: Cookie Settings
{
name: 'manacore_session',
domain: '.mana.how', // Shared across subdomains
secure: true,
sameSite: 'lax',
httpOnly: true,
path: '/',
}
```
### Betroffene Apps
| App | URL | SSO Status |
| ---------- | ------------------- | ---------- |
| Calendar | calendar.mana.how | ✅ |
| Chat | chat.mana.how | ✅ |
| Clock | clock.mana.how | ✅ |
| Contacts | contacts.mana.how | ✅ |
| NutriPhi | nutriphi.mana.how | ✅ |
| Picture | picture.mana.how | ✅ |
| Planta | planta.mana.how | ✅ |
| Questions | questions.mana.how | ✅ |
| SkillTree | skilltree.mana.how | ✅ |
| Storage | storage.mana.how | ✅ |
| Todo | todo.mana.how | ✅ |
| Zitare | zitare.mana.how | ✅ |
| Manalink | manalink.mana.how | ✅ |
| Playground | playground.mana.how | ✅ |
### get-session Endpoint
Neuer Endpoint für Session-Validierung:
```typescript
// GET /api/auth/get-session
// Returns: { user, session } or null
const response = await fetch('https://auth.mana.how/api/auth/get-session', {
credentials: 'include', // Wichtig für Cross-Domain Cookies
});
const { user } = await response.json();
```
---
## mana-media Integration
Zentrale Medienverarbeitung mit NutriPhi als erster Integration.
### NutriPhi Integration
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ NutriPhi │────>│ mana-media │────>│ MinIO │
│ (Upload) │ │ (Process) │ │ (Storage) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
│ │ EXIF Extraction
│ │ Thumbnail Generation
│ │ Resize/Compress
│ ▼
│ ┌─────────────────┐
│ │ PostgreSQL │
│ │ (Metadata) │
│ └─────────────────┘
```
### Änderungen
| Änderung | Beschreibung |
| --------------- | ---------------------------------- |
| `userId` Type | UUID → TEXT (für Matrix User IDs) |
| Body Size Limit | 10mb → 50mb (Bilder) |
| Dockerfile | Vereinfacht auf Single Build Stage |
### API
```typescript
// POST /api/v1/media/upload
const formData = new FormData();
formData.append('file', imageFile);
formData.append('context', 'meal');
const response = await fetch('https://media.mana.how/api/v1/media/upload', {
method: 'POST',
body: formData,
headers: { Authorization: `Bearer ${token}` },
});
```
---
## Matrix Bots Page
Neue Übersichtsseite mit allen 19 Matrix Bots in Manalink.
### UI
```
┌─────────────────────────────────────────────────────────────────┐
│ Manalink - Bots │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ 🤖 mana-mana-bot ││
│ │ Der zentrale AI-Assistent mit Voice Support ││
│ │ Commands: !help, !model, Voice Messages ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ ✅ matrix-todo-bot ││
│ │ Task-Management mit natürlicher Sprache ││
│ │ Commands: todo, liste, erledigt ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ ... (17 weitere Bots) │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Bot-Liste
| Bot | Kategorie | Beschreibung |
| -------------------- | ------------ | ---------------------- |
| mana-mana-bot | AI | Zentraler AI-Assistent |
| matrix-todo-bot | Productivity | Task-Management |
| matrix-calendar-bot | Productivity | Termine & Erinnerungen |
| matrix-clock-bot | Utility | Timer & Weltzeit |
| matrix-contacts-bot | Productivity | Kontaktverwaltung |
| matrix-nutriphi-bot | Health | Ernährungs-Tracking |
| matrix-picture-bot | AI | Bildgenerierung |
| matrix-zitare-bot | Inspiration | Tägliche Zitate |
| matrix-skilltree-bot | Gamification | Skill-Tracking |
| matrix-planta-bot | Lifestyle | Pflanzenpflege |
| matrix-manadeck-bot | Learning | Lernkarten |
| matrix-presi-bot | Productivity | Präsentationen |
| matrix-questions-bot | Research | Q&A Management |
| matrix-chat-bot | AI | AI-Chat |
| matrix-ollama-bot | AI | LLM Direct Access |
| matrix-tts-bot | Media | Text-to-Speech |
| matrix-stt-bot | Media | Speech-to-Text |
| matrix-storage-bot | Utility | Dateiverwaltung |
| matrix-voice-bot | AI | Voice-to-Voice |
### Layout
Single Column Layout für bessere Lesbarkeit auf allen Geräten.
---
## mana-llm Production
LLM Gateway auf Mac Mini deployed.
### Docker Compose
```yaml
mana-llm:
image: ghcr.io/manacore/mana-llm:latest
ports:
- '3025:3025'
environment:
- OLLAMA_URL=http://host.docker.internal:11434
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
restart: unless-stopped
```
### SSE Fix
Double-Data-Prefix Problem behoben:
```python
# Vorher (falsch)
yield f"data: data: {json.dumps(chunk)}\n\n"
# Nachher (korrekt)
yield f"data: {json.dumps(chunk)}\n\n"
```
---
## i18n für Matrix Bots
Mehrsprachige Bot-Antworten basierend auf User-Präferenzen.
### Unterstützte Sprachen
| Sprache | Code |
| ------- | ---- |
| Deutsch | `de` |
| English | `en` |
### Implementierung
```typescript
// bot-services/i18n/index.ts
export function t(key: string, locale: string = 'de'): string {
return translations[locale]?.[key] || translations['de'][key] || key;
}
// Verwendung
const response = t('todo.created', userLocale);
// DE: "Aufgabe erstellt!"
// EN: "Task created!"
```
### Direct Message Fallback
Bots antworten jetzt auch in DMs statt nur in Rooms:
```typescript
if (event.sender !== this.client.getUserId()) {
// Auch Direct Messages beantworten
await this.handleCommand(event);
}
```
---
## Cross-Bot SSO via Redis
Single Sign-On über verschiedene Matrix Bots.
### Architektur
```
┌─────────────────┐ ┌─────────────────┐
│ matrix-todo- │ │ matrix-cal- │
│ bot │ │ endar-bot │
│ │ │ │
└────────┬────────┘ └────────┬────────┘
│ │
│ Redis Sessions │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
└───>│ Redis │<───┘
│ Sessions │
└─────────────┘
```
### Session Sharing
```typescript
// SessionService mit Redis
class SessionService {
async getSession(userId: string): Promise<BotSession | null> {
const session = await this.redis.get(`bot:session:${userId}`);
return session ? JSON.parse(session) : null;
}
async setSession(userId: string, session: BotSession): Promise<void> {
await this.redis.set(`bot:session:${userId}`, JSON.stringify(session), 'EX', 86400);
}
}
```
---
## Calendar UX Verbesserungen
Verbesserte User Experience für die Calendar App.
### Änderungen
| Änderung | Beschreibung |
| ------------------- | --------------------------- |
| **Tasks versteckt** | Standardmäßig ausgeblendet |
| **Auto-Scroll** | Scrollt zu 12:00 beim Laden |
| **PillNavigation** | Sidebar Mode entfernt |
### Auto-Scroll
```typescript
onMount(() => {
// Scroll to midday (12:00)
const hourElement = document.querySelector('[data-hour="12"]');
hourElement?.scrollIntoView({ block: 'center' });
});
```
---
## Matrix User Auto-Link
Automatische Verknüpfung von ManaCore-Accounts mit Matrix-Users bei OIDC Login.
### Flow
```
1. User loggt sich via OIDC in Matrix ein
2. mana-core-auth erhält OIDC Callback
3. Matrix User ID wird mit ManaCore Account verknüpft
4. Alle Bots erkennen den User automatisch
```
### Database Schema
```sql
ALTER TABLE users ADD COLUMN matrix_user_id TEXT;
-- Index für schnelle Lookups
CREATE INDEX idx_users_matrix_user_id ON users(matrix_user_id);
```
---
## Bugfixes
| Fix | Beschreibung |
| ----------------------- | ----------------------------- |
| **mana-llm SSE** | Double data prefix |
| **contacts-web** | Runtime URLs statt Build-time |
| **shared-ui** | calculateFadeOpacity Export |
| **nutriphi Dockerfile** | Fehlende shared packages |
| **SessionService** | Async Methods |
| **JWT Issuer** | Aligned mit Better Auth |
---
## Zusammenfassung
| Bereich | Commits | Highlights |
| -------------------- | ------- | -------------------- |
| **Cross-Domain SSO** | 5 | 14 Apps mit SSO |
| **mana-media** | 4 | NutriPhi Integration |
| **Matrix Bots Page** | 2 | 19 Bots Übersicht |
| **mana-llm** | 2 | Production + SSE Fix |
| **i18n Bots** | 2 | DE/EN Support |
| **Cross-Bot SSO** | 3 | Redis Sessions |
| **Calendar UX** | 3 | Tasks, Auto-Scroll |
| **Auth Fixes** | 8 | JWT, Sessions, OIDC |
| **Bugfixes** | 11 | Docker, UI, Types |
---
## Nächste Schritte
1. **Photos App** mit mana-media Integration
2. **Admin Dashboard** für User-Übersicht
3. **STT/TTS APIs** extern verfügbar machen
4. **Matrix E2EE** aktivieren

View file

@ -0,0 +1,429 @@
---
title: 'Photos App, STT/TTS API Keys & Admin Dashboard'
description: 'Neue Photos App mit mana-media EXIF-Integration, API Key Authentication für STT/TTS Services, Admin User Data Dashboard für Cross-Project Visualisierung, und vLLM Voxtral Integration'
date: 2026-02-11
author: 'Till Schneider'
category: 'feature'
tags:
[
'photos',
'mana-media',
'exif',
'stt',
'tts',
'api-keys',
'admin',
'dashboard',
'vllm',
'voxtral',
'docker',
]
featured: true
commits: 28
readTime: 14
---
Nach einer Woche Pause: **28 Commits** mit Fokus auf neue Apps und API-Infrastruktur:
- **Photos App** - Neue App mit mana-media EXIF-Integration
- **STT/TTS API Keys** - API Key Authentication mit Rate Limiting
- **Admin Dashboard** - Cross-Project User Data Visualisierung
- **vLLM Integration** - Voxtral Transcription für mana-stt
- **External APIs** - STT und TTS extern verfügbar
---
## Photos App
Neue ManaCore App für Foto-Management mit automatischer EXIF-Extraktion.
### Architektur
```
┌─────────────────────────────────────────────────────────────────┐
│ Photos App Architecture │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌────────────┐ │
│ │ Photos Web │────>│ Photos Backend │────>│ mana-media │ │
│ │ (SvelteKit) │ │ (NestJS) │ │ (EXIF) │ │
│ │ Port 5196 │ │ Port 3026 │ │ │ │
│ └─────────────────┘ └─────────────────┘ └────────────┘ │
│ │ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌────────────┐ │
│ │ PostgreSQL │ │ MinIO │ │
│ │ (Metadata) │ │ (Files) │ │
│ └─────────────┘ └────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Features
| Feature | Beschreibung |
| --------------------- | --------------------------------- |
| **EXIF Extraction** | Kamera, Datum, GPS, Einstellungen |
| **Auto-Organization** | Sortierung nach Datum/Ort |
| **Thumbnails** | Automatische Generierung |
| **Albums** | Manuelle Organisation |
| **Timeline View** | Chronologische Ansicht |
### mana-media Integration
```typescript
// EXIF-Daten werden automatisch extrahiert
interface PhotoMetadata {
camera: string;
lens: string;
focalLength: string;
aperture: string;
shutterSpeed: string;
iso: number;
dateTaken: Date;
gps?: {
latitude: number;
longitude: number;
};
}
```
### Docker Deployment
```yaml
photos-backend:
build:
context: .
dockerfile: apps/photos/apps/backend/Dockerfile
ports:
- '3026:3026'
depends_on:
- mana-media
photos-web:
build:
context: .
dockerfile: apps/photos/apps/web/Dockerfile
ports:
- '5196:5196'
```
### Cloudflare Tunnel
Neue Routes für Photos App:
- `photos.mana.how` → Photos Web (5196)
- `photos-api.mana.how` → Photos Backend (3026)
---
## STT/TTS API Key Authentication
Neue API Key Authentifizierung für Speech Services.
### API Key Management
In mana-core-auth wurde ein API Key Management System hinzugefügt:
```typescript
// Auth API: API Key erstellen
POST /api/v1/api-keys
{
"name": "My STT App",
"services": ["stt", "tts"],
"rateLimit": 100 // requests per minute
}
// Response
{
"apiKey": "mana_sk_xxx...",
"name": "My STT App",
"services": ["stt", "tts"],
"rateLimit": 100,
"createdAt": "2026-02-11T14:00:00Z"
}
```
### Rate Limiting
```typescript
// Per-Key Rate Limiting
interface RateLimitConfig {
windowMs: 60000; // 1 Minute
max: number; // Aus API Key Config
}
// Redis-basiertes Tracking
const key = `rate:${apiKey}:${currentMinute}`;
await redis.incr(key);
await redis.expire(key, 60);
```
### Service Integration
```bash
# STT mit API Key
curl -X POST https://stt.mana.how/api/v1/transcribe \
-H "Authorization: Bearer mana_sk_xxx" \
-F "audio=@recording.mp3"
# TTS mit API Key
curl -X POST https://tts.mana.how/api/v1/synthesize \
-H "Authorization: Bearer mana_sk_xxx" \
-H "Content-Type: application/json" \
-d '{"text": "Hallo Welt", "voice": "de-DE-FlorianNeural"}'
```
---
## Admin User Data Dashboard
Neues Admin Dashboard für Cross-Project User Data Visualisierung.
### Features
```
┌─────────────────────────────────────────────────────────────────┐
│ Admin Dashboard - User Data │
├─────────────────────────────────────────────────────────────────┤
│ │
│ User: till@mana.how │
│ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ Calendar: 47 Events, 12 Calendars ││
│ │ Last activity: 2 hours ago ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ Todo: 156 Tasks (23 completed today) ││
│ │ Active projects: 8 ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ Contacts: 234 Contacts, 15 Groups ││
│ │ Recent additions: 3 this week ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ ... (weitere Apps) │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### API
```typescript
// GET /api/v1/admin/users/:userId/data
{
"calendar": {
"events": 47,
"calendars": 12,
"lastActivity": "2026-02-11T12:30:00Z"
},
"todo": {
"tasks": 156,
"completed": 89,
"projects": 8
},
"contacts": {
"total": 234,
"groups": 15
},
// ...
}
```
### Database Fix
```typescript
// Vorher: NodePgDatabase
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
// Nachher: PostgresJsDatabase
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
```
---
## vLLM Integration für mana-stt
Integration von vLLM für Voxtral Transcription.
### Architektur
```
┌─────────────────────────────────────────────────────────────────┐
│ mana-stt Architecture │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ Audio Input │ │
│ │ (MP3/WAV) │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Whisper Model │────>│ vLLM │ │
│ │ (ASR) │ │ (Voxtral) │ │
│ └─────────────────┘ └─────────────────┘ │
│ │ │ │
│ │ │ Post-Processing │
│ │ │ (Punctuation, Formatting) │
│ │ │ │
│ ▼ ▼ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Final Transcript │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### vLLM Configuration
```python
# CPU Mode Configuration
vllm_config = {
"model": "mistralai/Voxtral-Mini-3B-2025",
"dtype": "float32", # CPU Mode
"device": "cpu",
"max_model_len": 4096,
}
```
### API
```bash
# Transcription mit Voxtral Post-Processing
curl -X POST https://stt.mana.how/api/v1/transcribe \
-H "Authorization: Bearer $API_KEY" \
-F "audio=@recording.mp3" \
-F "enhance=true" # Voxtral Enhancement aktivieren
```
---
## External STT/TTS APIs
Speech Services sind jetzt extern verfügbar.
### Cloudflare Tunnel Routes
| Service | URL | Port |
| ------- | ------------ | ---- |
| STT API | stt.mana.how | 3020 |
| TTS API | tts.mana.how | 3022 |
### Port Fix
TTS API Port korrigiert:
```yaml
# Vorher
tts-api:
ports:
- "3020:3020" # Falsch
# Nachher
tts-api:
ports:
- "3022:3022" # Korrekt
```
### LaunchD Configuration
```bash
# STT/TTS Services laden .env automatisch
launchctl setenv STT_API_KEY $(cat /etc/mana/stt.env | grep API_KEY | cut -d= -f2)
```
---
## Docker Improvements
Zahlreiche Docker-Verbesserungen für alle Services.
### Backend Dockerfiles
`--ignore-scripts` zu allen Backend Dockerfiles hinzugefügt:
```dockerfile
# Verhindert postinstall-Fehler
RUN pnpm install --frozen-lockfile --ignore-scripts
```
### Shared Packages in Dockerfiles
Fehlende Shared Packages zu allen Dockerfiles hinzugefügt:
```dockerfile
# Vorher
COPY packages/shared-utils ./packages/shared-utils
# Nachher
COPY packages/shared-utils ./packages/shared-utils
COPY packages/shared-stores ./packages/shared-stores
COPY packages/shared-types ./packages/shared-types
COPY packages/shared-vite-config ./packages/shared-vite-config
```
### Local Builds
Einige Services werden jetzt lokal auf dem Mac Mini gebaut statt GHCR Images:
```yaml
# Mac Mini: Local Build
mana-auth:
build:
context: .
dockerfile: services/mana-core-auth/Dockerfile
```
---
## Bugfixes
| Fix | Beschreibung |
| ---------------------- | --------------------------------------- |
| **admin DB type** | PostgresJsDatabase statt NodePgDatabase |
| **photos Svelte 5** | Valide Event Syntax |
| **mana-media paths** | Korrekter Pfad zu main.js |
| **storage-web Docker** | Alle shared packages |
| **todo click targets** | Verbesserte Klickflächen |
| **matrix type safety** | Strict null checks |
| **ARM64 CI** | Deaktiviert für storage-backend |
---
## Dokumentation
### mana-stt Architecture
Neue Dokumentation unter `services/mana-stt/ARCHITECTURE.md`:
- Whisper Model Details
- vLLM Integration
- API Endpoints
- Performance Benchmarks
---
## Zusammenfassung
| Bereich | Commits | Highlights |
| -------------------- | ------- | ----------------------------- |
| **Photos App** | 8 | EXIF, Docker, Cloudflare |
| **STT/TTS API Keys** | 3 | Rate Limiting, Auth |
| **Admin Dashboard** | 2 | Cross-Project Data |
| **vLLM Integration** | 2 | Voxtral, CPU Mode |
| **External APIs** | 2 | STT/TTS Tunnel |
| **Docker Fixes** | 8 | Shared Packages, Local Builds |
| **Bugfixes** | 3 | Types, Paths, UI |
---
## Nächste Schritte
1. **Photos App** Production Deployment
2. **Admin Dashboard** erweitern (GDPR Export)
3. **vLLM GPU Mode** aktivieren
4. **API Key Dashboard** in mana.how

View file

@ -53,6 +53,15 @@
}
});
// Auto-focus input when room changes or component mounts
$effect(() => {
const roomId = matrixStore.currentRoomId;
if (roomId && textarea) {
// Small delay to ensure DOM is ready
setTimeout(() => textarea?.focus(), 50);
}
});
async function handleSend() {
const trimmed = message.trim();
if (!trimmed) return;
@ -416,13 +425,17 @@
<div
class="mb-2 rounded-xl bg-white dark:bg-zinc-800 border border-black/10 dark:border-white/10 shadow-xl overflow-hidden"
>
<div class="px-3 py-1.5 text-xs text-muted-foreground border-b border-black/5 dark:border-white/5">
<div
class="px-3 py-1.5 text-xs text-muted-foreground border-b border-black/5 dark:border-white/5"
>
Erwähne jemanden
</div>
{#each mentionResults as member, i}
<button
class="flex items-center gap-3 w-full px-3 py-2 transition-colors text-left
{i === selectedMentionIndex ? 'bg-violet-500/10 dark:bg-violet-500/20' : 'hover:bg-black/5 dark:hover:bg-white/5'}"
{i === selectedMentionIndex
? 'bg-violet-500/10 dark:bg-violet-500/20'
: 'hover:bg-black/5 dark:hover:bg-white/5'}"
onclick={() => insertMention(member)}
>
<!-- Avatar -->

View file

@ -22,6 +22,8 @@
let prevMessageCount = $state(0);
let hasInitiallyScrolled = $state(false);
let currentRoomId = $state<string | null>(null);
// Track if user manually scrolled up (to read history)
let userScrolledUp = $state(false);
// Reset state when room changes
$effect(() => {
@ -32,6 +34,7 @@
prevMessageCount = 0;
loadingMore = false;
showScrollButton = false;
userScrolledUp = false;
}
});
@ -51,15 +54,16 @@
return;
}
// Auto-scroll on new messages (if already at bottom)
// Auto-scroll on new messages (only if user hasn't manually scrolled up)
if (messageCount > prevMessageCount && container && hasInitiallyScrolled) {
const isAtBottom =
container.scrollHeight - container.scrollTop - container.clientHeight < 100;
if (isAtBottom) {
if (!userScrolledUp) {
// Use double tick to ensure DOM has rendered the new message
tick().then(() => {
if (container) {
container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' });
}
tick().then(() => {
if (container) {
container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' });
}
});
});
}
}
@ -69,9 +73,19 @@
function handleScroll() {
if (!container) return;
// Show scroll button if not at bottom
// Calculate distance from bottom
const distanceFromBottom =
container.scrollHeight - container.scrollTop - container.clientHeight;
// Track if user manually scrolled up (more than 150px from bottom)
// Reset when they scroll back to bottom (within 50px)
if (distanceFromBottom > 150) {
userScrolledUp = true;
} else if (distanceFromBottom < 50) {
userScrolledUp = false;
}
// Show scroll button if not at bottom
showScrollButton = distanceFromBottom > 200;
// Load more when scrolled to top (only after initial scroll and with messages present)
@ -104,6 +118,7 @@
}
function scrollToBottom() {
userScrolledUp = false;
container?.scrollTo({ top: container.scrollHeight, behavior: 'smooth' });
}
</script>

View file

@ -17,7 +17,7 @@ import { UserDataResponse, DeleteUserDataResponse } from './dto/user-data-respon
* Used by mana-core-auth aggregation service
* Protected by X-Service-Key authentication
*/
@Controller('admin')
@Controller('api/v1/admin')
@UseGuards(ServiceAuthGuard)
export class AdminController {
private readonly logger = new Logger(AdminController.name);