📝 docs: restructure CLAUDE.md and documentation (74% reduction)

Optimize CLAUDE.md based on industry best practices from HN and HumanLayer:

Changes:
- Trim CLAUDE.md from 678 to 176 lines (74% reduction, 5.7KB)
- Add "Critical Gotchas" section for common AI mistakes
- Add verification signature (🏗️ ManaCore Monorepo)
- Create docs/README.md navigation hub with "I want to..." index
- Delete 5 outdated audit files (ENV_AUDIT_*, DEPENDENCY_ALIGNMENT)
- Archive 7 analysis/historical docs to docs/archive/
- Keep authentication docs separate per request (.claude/guidelines/)

Benefits:
- Better AI instruction adherence (within ~150-200 line budget)
- Progressive disclosure via signposting to detailed docs
- Cleaner navigation with topic-based organization
- Reduced maintenance burden (stale docs archived)

Backup: CLAUDE.md.backup preserves original 678-line version
Change log: docs/archive/RESTRUCTURE_2025-12-16.md
This commit is contained in:
Wuesteon 2025-12-16 17:37:19 +01:00
parent d2c2326ed7
commit ad495b2044
16 changed files with 1008 additions and 1900 deletions

View file

@ -0,0 +1,946 @@
# Backend-Architektur im Manacore Monorepo
Diese Dokumentation beschreibt die Backend-Implementierungen aller Projekte im Manacore Monorepo.
## Übersicht
Das Monorepo enthält 6 Hauptprojekte mit unterschiedlichen Backend-Architekturen:
| Projekt | Backend-Typ | Datenbank | Status |
|---------|-------------|-----------|--------|
| **Maerchenzauber** | NestJS v10 | Supabase (PostgreSQL) | Aktiv |
| **Manadeck** | NestJS v11 | PostgreSQL + Drizzle ORM | Aktiv |
| **Uload** | NestJS v11 | PostgreSQL + Drizzle ORM | Aktiv |
| **Picture** | Kein Backend | - | Frontend-only |
| **Memoro** | Kein Backend | - | Frontend-only |
| **Manacore** | Kein Backend (extern) | - | Externes Backend |
---
## 1. Maerchenzauber
**Pfad:** `/maerchenzauber/apps/backend`
**Zweck:** KI-gestützte Kindergeschichten-Generierung mit benutzerdefinierten Charakteren.
### Technologie-Stack
- **Framework:** NestJS 10.0.0
- **Datenbank:** Supabase (PostgreSQL)
- **ORM:** `@supabase/supabase-js` v2.81.1
- **AI-Services:** Azure OpenAI, Google Gemini, Replicate
### Architektur
```
apps/backend/
├── src/
│ ├── character/ # Charakter-Modul
│ │ ├── character.controller.ts
│ │ ├── character.service.ts
│ │ └── character.repository.ts
│ ├── story/ # Story-Modul
│ │ ├── story.controller.ts
│ │ ├── story.service.ts
│ │ └── pipelines/ # Story-Generierung-Pipelines
│ ├── core/ # Kern-Services
│ │ └── services/
│ │ └── prompting.service.ts
│ ├── settings/ # Benutzereinstellungen
│ ├── health/ # Health-Checks
│ └── feedback/ # Feedback-Modul
```
### Datenbank-Schema
**Tabellen:**
- `characters` - Benutzercharaktere
- `stories` - Generierte Geschichten
- `story_collections` - Sammlungen von Geschichten
- `user_settings` - Benutzereinstellungen
**Sicherheit:** Row-Level Security (RLS) für Datenzugriffskontrolle
### Authentifizierung
Mana Core Integration via `@mana-core/nestjs-integration`:
```typescript
// Beispiel: Geschützter Endpoint
@UseGuards(AuthGuard)
@Get('characters')
async getCharacters(@CurrentUser() user: User) {
return this.characterService.findByUser(user.id);
}
```
**Auth-Endpoint:** `https://mana-core-middleware-111768794939.europe-west3.run.app`
### AI-Services
| Service | Verwendung | API |
|---------|------------|-----|
| Azure OpenAI (GPT-4) | Story-Generierung | `MAERCHENZAUBER_AZURE_OPENAI_ENDPOINT` |
| Google Gemini | Charakter-Generierung | `GOOGLE_GEMINI_API_KEY` |
| Replicate (Flux) | Bildgenerierung | `REPLICATE_API_TOKEN` |
### File Storage
- **Provider:** Supabase Storage
- **Bucket:** `maerchenzauber`
- **Verwendung:** Charakter- und Story-Bilder
### Deployment
- **Plattform:** Google Cloud Run
- **Region:** europe-west3
- **URL:** `https://storyteller-backend-111768794939.europe-west3.run.app`
- **Port:** 3002 (Development)
---
## 2. Manadeck
**Pfad:** `/manadeck/apps/backend`
**Zweck:** KI-gestützte Lernkarten-Generierung (Flashcards, Quizzes, Mixed).
### Technologie-Stack
- **Framework:** NestJS 11.0.1
- **Datenbank:** PostgreSQL 16
- **ORM:** Drizzle ORM
- **AI-Service:** Google Gemini API
### Architektur
```
apps/backend/
├── src/
│ ├── api.controller.ts # Haupt-API-Endpoints
│ ├── public.controller.ts # Öffentliche Endpoints
│ ├── health.controller.ts # Health-Checks
│ ├── ai.service.ts # AI-Generierung
│ └── repositories/
│ ├── deck.repository.ts
│ ├── card.repository.ts
│ ├── user-stats.repository.ts
│ └── deck-template.repository.ts
```
### Datenbank-Package
Das Datenbank-Schema ist in einem separaten Package ausgelagert:
**Pfad:** `/packages/manadeck-database`
```typescript
// Verwendung im Backend
import { db, schema } from '@manacore/manadeck-database';
const decks = await db.query.decks.findMany({
where: eq(schema.decks.userId, userId)
});
```
**Drizzle-Konfiguration:**
```typescript
// drizzle.config.ts
export default {
schema: './src/schema/*',
out: './migrations',
driver: 'pg',
dbCredentials: {
connectionString: process.env.DATABASE_URL
}
};
```
### Authentifizierung
```typescript
import { AuthGuard, CurrentUser } from '@mana-core/nestjs-integration';
@Controller('api')
@UseGuards(AuthGuard)
export class ApiController {
@Post('decks')
async createDeck(@CurrentUser() user: User, @Body() dto: CreateDeckDto) {
// Credit-Prüfung und Deck-Erstellung
}
}
```
### Credit-System
Integration mit Mana Core Credit Service:
```typescript
import { CreditClientService } from '@mana-core/nestjs-integration';
@Injectable()
export class AiService {
constructor(private creditClient: CreditClientService) {}
async generateDeck(userId: string, input: GenerateInput) {
// 1. Credit-Balance prüfen
const hasCredits = await this.creditClient.checkBalance(userId, 'DECK_CREATION');
// 2. Deck generieren
const deck = await this.generateWithGemini(input);
// 3. Credits abziehen
await this.creditClient.deduct(userId, 'DECK_CREATION');
return deck;
}
}
```
### AI-Generierung
**Unterstützte Kartentypen:**
- `text` - Textbasierte Karten
- `flashcard` - Klassische Lernkarten
- `quiz` - Multiple-Choice Quiz
- `mixed` - Gemischte Inhalte
**Schwierigkeitsgrade:**
- `beginner`
- `intermediate`
- `advanced`
### Docker-Setup
```yaml
# docker-compose.yml (Lokale Entwicklung)
services:
postgres:
image: postgres:16
ports:
- "5433:5432"
environment:
POSTGRES_DB: manadeck
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
pgadmin:
image: dpage/pgadmin4
ports:
- "5050:80"
```
### Deployment
- **Docker Image:** Multi-stage Build (Node 18-alpine)
- **Port:** 8080
- **Health-Check:** `/health`
---
## 3. Uload
**Pfad:** `/uload/apps/backend`
**Zweck:** URL-Shortener mit Link-Analytics.
### Technologie-Stack
- **Framework:** NestJS 11.0.1
- **Datenbank:** PostgreSQL 16
- **ORM:** Drizzle ORM
- **Cache:** Redis (optional)
### Architektur
```
uload/apps/backend/
├── src/
│ ├── main.ts
│ ├── app.module.ts
│ ├── config/
│ │ └── validation.schema.ts
│ ├── controllers/
│ │ ├── redirect.controller.ts # GET /:code (public redirect)
│ │ ├── links.controller.ts # CRUD /api/links
│ │ ├── analytics.controller.ts # GET /api/analytics
│ │ └── health.controller.ts
│ ├── services/
│ │ ├── links.service.ts
│ │ ├── redirect.service.ts
│ │ └── analytics.service.ts
│ └── database/
│ ├── database.module.ts
│ └── repositories/
│ ├── link.repository.ts
│ └── click.repository.ts
├── Dockerfile
└── package.json
```
### Datenbank-Package
**Pfad:** `/packages/uload-database`
```typescript
// Verwendung im Backend
import { db, links, clicks, eq, desc } from '@manacore/uload-database';
const userLinks = await db.query.links.findMany({
where: eq(links.userId, userId),
orderBy: desc(links.createdAt)
});
```
### API Endpoints
| Endpoint | Method | Auth | Beschreibung |
|----------|--------|------|--------------|
| `/:code` | GET | Public | Redirect zu Original-URL |
| `/api/links` | GET | Protected | Liste aller Links |
| `/api/links` | POST | Protected | Link erstellen |
| `/api/links/:id` | GET | Protected | Link Details |
| `/api/links/:id` | PATCH | Protected | Link aktualisieren |
| `/api/links/:id` | DELETE | Protected | Link löschen |
| `/api/analytics/:linkId` | GET | Protected | Link-Statistiken |
| `/health` | GET | Public | Health Check |
### Authentifizierung
Mana Core Integration via `@mana-core/nestjs-integration`:
```typescript
import { AuthGuard, CurrentUser } from '@mana-core/nestjs-integration';
@Controller('api/links')
@UseGuards(AuthGuard)
export class LinksController {
@Get()
async getLinks(@CurrentUser() user: any) {
return this.linksService.getLinks(user.sub);
}
}
```
### Deployment
- **Docker Image:** Multi-stage Build (Node 20-alpine)
- **Port:** 3003
- **Health-Check:** `/health`
---
## 4. Picture
**Pfad:** `/picture`
**Zweck:** Bild- und Medienverwaltung.
### Architektur
**Kein dediziertes Backend.** Picture verwendet:
- SvelteKit Server-Routes für Backend-Logik
- Mana Core für Authentifizierung
- Shared Packages aus `/packages`
```
picture/
├── apps/
│ ├── mobile/ # React Native Expo
│ ├── web/ # SvelteKit
│ └── landing/ # Astro
└── packages/
├── design-tokens/ # Design System
├── mobile-ui/ # Mobile UI Components
└── shared/ # Utilities
```
---
## 5. Memoro
**Pfad:** `/memoro`
**Zweck:** Legacy-Content und Memory-Preservation.
### Architektur
**Kein dediziertes Backend.** Memoro verwendet:
- SvelteKit Server-Routes
- Mana Core für Authentifizierung
- Supabase (Legacy-Konfiguration vorhanden)
```
memoro/
├── apps/
│ ├── mobile/
│ ├── web/
│ └── landing/
└── supabase/ # Legacy Supabase Config
```
---
## 6. Manacore
**Pfad:** `/manacore`
**Zweck:** Core-Authentifizierung und Credit-System.
### Architektur
Das Manacore-Backend ist **extern gehostet** und nicht Teil des Monorepos:
- **URL:** `https://mana-core-middleware-111768794939.europe-west3.run.app`
- **Integration:** Via `@mana-core/nestjs-integration` Package
```
manacore/
├── apps/
│ ├── mobile/ # Auth-Flow UI
│ ├── web/ # Dashboard
│ └── landing/ # Marketing
```
---
## Shared Packages für Backend
### @manacore/manadeck-database
PostgreSQL-Datenbankschema für Manadeck.
```
packages/manadeck-database/
├── src/
│ ├── schema/ # Drizzle Schema
│ ├── client.ts # DB Client
│ └── index.ts # Exports
├── drizzle.config.ts
└── docker-compose.yml
```
### @manacore/uload-database
PostgreSQL-Datenbankschema für Uload URL-Shortener.
```
packages/uload-database/
├── src/
│ ├── schema/
│ │ ├── users.ts
│ │ ├── links.ts
│ │ ├── clicks.ts
│ │ ├── tags.ts
│ │ ├── workspaces.ts
│ │ ├── accounts.ts
│ │ └── relations.ts
│ ├── client.ts # DB Client
│ └── index.ts # Exports
├── drizzle.config.ts
└── docker-compose.yml
```
### @mana-core/nestjs-integration
Externe Dependency für Backend-Integration:
```typescript
// Installation via git
"@mana-core/nestjs-integration": "git+https://github.com/mana-core/nestjs-integration.git"
```
**Bereitgestellte Features:**
- `AuthGuard` - JWT-Authentifizierung
- `@CurrentUser()` - User-Context Decorator
- `CreditClientService` - Credit-Operationen
- Konfigurationsmodule
---
## Authentifizierungs-Pattern
Alle Projekte nutzen zentrale **Mana Core Authentifizierung**:
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Frontend │────▶│ Project Backend │────▶│ Mana Core │
│ (Web/Mobile) │ │ (NestJS/etc.) │ │ Middleware │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ │ │
▼ ▼ ▼
shared-auth AuthGuard JWT Validation
shared-auth-ui @CurrentUser Credit Service
shared-auth-stores CreditClient User Management
```
### Frontend-Integration
```typescript
// Shared Auth Store (Svelte)
import { authStore } from '@manacore/shared-auth-stores';
// Login
await authStore.login(email, password);
// Token für API-Requests
const token = authStore.getAccessToken();
```
### Backend-Integration
```typescript
// NestJS Module Setup
@Module({
imports: [
ManaCoreModule.forRoot({
serviceKey: process.env.MANA_CORE_SERVICE_KEY,
baseUrl: process.env.MANA_CORE_URL,
}),
],
})
export class AppModule {}
```
---
## Datenbank-Migrationen
### Manadeck (Drizzle)
```bash
# Migration generieren
pnpm --filter @manacore/manadeck-database drizzle-kit generate
# Migration ausführen
pnpm --filter @manacore/manadeck-database drizzle-kit push
```
### Maerchenzauber (Supabase)
```bash
# Supabase CLI
supabase migration new <name>
supabase db push
```
---
## Umgebungsvariablen
### Maerchenzauber Backend
```env
# Supabase
SUPABASE_URL=
SUPABASE_SERVICE_ROLE_KEY=
# Mana Core
MANA_CORE_URL=https://mana-core-middleware-111768794939.europe-west3.run.app
MANA_CORE_SERVICE_KEY=
# AI Services
MAERCHENZAUBER_AZURE_OPENAI_ENDPOINT=
AZURE_OPENAI_API_KEY=
GOOGLE_GEMINI_API_KEY=
REPLICATE_API_TOKEN=
```
### Manadeck Backend
```env
# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/manadeck
# Mana Core
MANA_CORE_URL=
MANA_CORE_SERVICE_KEY=
# AI
GOOGLE_GEMINI_API_KEY=
# Server
PORT=8080
```
### Uload
```env
# Database
DATABASE_URL=postgresql://...
# Redis
REDIS_URL=redis://localhost:6379
# PocketBase
POCKETBASE_URL=
```
---
## Lokale Entwicklung
### Maerchenzauber Backend
```bash
cd maerchenzauber/apps/backend
pnpm install
pnpm run start:dev
# Läuft auf Port 3002
```
### Manadeck Backend
```bash
# 1. Datenbank starten
cd packages/manadeck-database
docker-compose up -d
# 2. Backend starten
cd manadeck/apps/backend
pnpm install
pnpm run start:dev
# Läuft auf Port 8080
```
### Uload
```bash
cd uload
docker-compose up -d # PostgreSQL + Redis
pnpm install
pnpm run dev
```
---
## Zusammenfassung
Das Manacore Monorepo verwendet verschiedene Backend-Strategien:
1. **Full Backend (NestJS):** Maerchenzauber, Manadeck - Für komplexe Geschäftslogik und AI-Integration
2. **Embedded Database (PocketBase):** Uload - Für einfache CRUD-Operationen
3. **Frontend-only:** Picture, Memoro - Server-Routes in SvelteKit
4. **External Backend:** Manacore - Zentrale Auth/Credit-Services
Alle Projekte teilen sich:
- Gemeinsame Authentifizierung via Mana Core
- Shared Packages für UI, Auth, Types
- Einheitliches Deployment-Pattern (Docker + Cloud Run)
---
## Vereinheitlichungs-Roadmap
### Aktuelle Fragmentierung
| Aspekt | Maerchenzauber | Manadeck | Uload |
|--------|----------------|----------|-------|
| Framework | NestJS v10 | NestJS v11 | PocketBase |
| Datenbank | Supabase | PostgreSQL | PocketBase + PG |
| ORM | @supabase/js | Drizzle | Drizzle |
| Auth | Mana Core | Mana Core | PocketBase + Mana Core |
---
### Strategie 1: Shared NestJS Backend Package
**Ziel:** Ein gemeinsames `@manacore/shared-backend` Package mit wiederverwendbaren Modulen.
```
packages/shared-backend/
├── src/
│ ├── auth/
│ │ ├── auth.module.ts
│ │ ├── auth.guard.ts
│ │ └── current-user.decorator.ts
│ ├── database/
│ │ ├── database.module.ts
│ │ ├── drizzle.provider.ts
│ │ └── base.repository.ts
│ ├── health/
│ │ └── health.module.ts
│ ├── credits/
│ │ └── credits.module.ts
│ └── common/
│ ├── filters/
│ ├── interceptors/
│ └── pipes/
```
**Vorteile:**
- Einheitliche Auth-Integration
- Wiederverwendbare Module
- Konsistente Error-Handling
**Aufwand:** Mittel
---
### Strategie 2: Einheitliche Datenbank-Strategie
#### Option A: Alles auf Drizzle + PostgreSQL (Empfohlen)
```typescript
// packages/shared-database/src/base-schema.ts
export const baseColumns = {
id: uuid('id').primaryKey().defaultRandom(),
createdAt: timestamp('created_at').defaultNow(),
updatedAt: timestamp('updated_at').defaultNow(),
userId: text('user_id').notNull(),
};
// Projekt-spezifische Erweiterung
// maerchenzauber/database/schema/characters.ts
import { baseColumns } from '@manacore/shared-database';
export const characters = pgTable('characters', {
...baseColumns,
name: text('name').notNull(),
traits: jsonb('traits'),
});
```
**Migration von Supabase:**
- Supabase ist PostgreSQL → Schema kann übernommen werden
- RLS-Policies in Application-Layer verschieben
- Storage → S3/Cloudflare R2
#### Option B: Alles auf Supabase
```typescript
// packages/shared-supabase/src/client.ts
export const createProjectClient = (project: 'maerchenzauber' | 'manadeck' | 'uload') => {
return createClient(
process.env[`${project.toUpperCase()}_SUPABASE_URL`],
process.env[`${project.toUpperCase()}_SUPABASE_KEY`]
);
};
```
**Vorteile Supabase:**
- Eingebaute Auth (optional nutzbar)
- Storage inklusive
- Realtime-Subscriptions
- Edge Functions möglich
**Nachteile Supabase:**
- Vendor Lock-in
- Weniger Kontrolle über Schema
**Empfehlung:** Drizzle + PostgreSQL wegen Type-Safety, moderner API und keinem Vendor Lock-in.
---
### Strategie 3: Einheitliche Monorepo Backend Struktur
**Ziel-Architektur:**
```
packages/
├── shared-backend/ # Gemeinsame NestJS Module
│ ├── auth/
│ ├── database/
│ ├── health/
│ └── credits/
├── shared-database/ # Drizzle Basis-Schema
│ ├── base-schema.ts
│ ├── migrations/
│ └── client.ts
├── maerchenzauber-database/ # Projekt-Schema
├── manadeck-database/ # ✓ Existiert bereits
└── uload-database/ # Neu
apps/
├── maerchenzauber-backend/ # Nutzt shared-backend
├── manadeck-backend/ # Nutzt shared-backend
└── uload-backend/ # Neues NestJS Backend (ersetzt PocketBase)
```
---
### Strategie 4: Shared Backend als Service-Layer
**Ziel:** Gemeinsamer Service-Layer, projekt-spezifische Controller.
```typescript
// packages/shared-backend/src/services/ai.service.ts
@Injectable()
export class BaseAiService {
constructor(
private gemini: GeminiClient,
private credits: CreditService,
) {}
protected async generateWithCredits<T>(
userId: string,
operation: string,
generator: () => Promise<T>
): Promise<T> {
await this.credits.check(userId, operation);
const result = await generator();
await this.credits.deduct(userId, operation);
return result;
}
}
// maerchenzauber/backend/src/story/story.service.ts
@Injectable()
export class StoryService extends BaseAiService {
async generateStory(userId: string, input: StoryInput) {
return this.generateWithCredits(userId, 'STORY_GENERATION', async () => {
// Projekt-spezifische Logik
});
}
}
```
---
### Strategie 5: API-Gateway Pattern (Optional)
**Ziel:** Ein zentrales Gateway vor allen Backends.
```
┌─────────────────┐
│ API Gateway │
│ (Kong/Traefik) │
└────────┬────────┘
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Maerchenzauber│ │ Manadeck │ │ Uload │
│ Backend │ │ Backend │ │ Backend │
└───────────────┘ └───────────────┘ └───────────────┘
```
**Vorteile:**
- Zentrale Auth-Validierung
- Rate Limiting
- Request Logging
- Einheitliche API-Struktur
**Aufwand:** Hoch - Empfohlen erst bei Skalierungsbedarf
---
### Empfohlene Implementierungsreihenfolge
#### Phase 1: Shared Backend Package
**Priorität:** Hoch
**Aufwand:** 2-3 Wochen
Neues Package `packages/shared-backend/` mit:
- Auth Module (wraps @mana-core/nestjs-integration)
- Health Module
- Credits Module
- Base Repository Pattern
- Common Decorators, Guards, Filters
#### Phase 2: Datenbank-Vereinheitlichung
**Priorität:** Hoch
**Aufwand:** 3-4 Wochen
1. `packages/shared-database/` mit Drizzle Basis-Schema erstellen
2. Maerchenzauber von Supabase auf Drizzle migrieren
3. Uload PocketBase durch PostgreSQL + Drizzle ersetzen
#### Phase 3: Uload Backend Neubau (Optional)
**Priorität:** Mittel
**Aufwand:** 2-3 Wochen
PocketBase → NestJS Migration:
- Konsistenz mit anderen Projekten
- Bessere Integration mit Mana Core
- Einheitliches Deployment
---
### Optionen-Vergleich
| Option | Aufwand | Benefit | Empfehlung |
|--------|---------|---------|------------|
| Shared Backend Package | Mittel | Hoch | ✅ Priorität 1 |
| Drizzle überall | Mittel-Hoch | Hoch | ✅ Priorität 2 |
| Uload auf NestJS | Hoch | Mittel | ⚡ Optional |
| API Gateway | Sehr Hoch | Mittel | ⏳ Später |
---
### Quick Wins (sofort umsetzbar)
1. **NestJS Version angleichen** → Alle auf v11
2. **Einheitliche Health-Endpoints**`/health`, `/health/ready`
3. **Gemeinsame ESLint/Prettier Config**`@manacore/eslint-config-backend`
4. **Einheitliche Error-Response-Struktur:**
```typescript
// Einheitliches Error-Format für alle Backends
interface ApiError {
statusCode: number;
error: string;
message: string;
timestamp: string;
path: string;
}
```
5. **Einheitliche Logging-Struktur:**
```typescript
// packages/shared-backend/src/logging/logger.service.ts
@Injectable()
export class AppLogger {
log(context: string, message: string, meta?: Record<string, any>) {
console.log(JSON.stringify({
level: 'info',
context,
message,
timestamp: new Date().toISOString(),
...meta,
}));
}
}
```
---
### Ziel-Architektur nach Vereinheitlichung
```
┌─────────────────────────────────────────────────────────────┐
│ Shared Packages │
├─────────────────┬─────────────────┬─────────────────────────┤
│ shared-backend │ shared-database │ shared-types │
│ - AuthModule │ - baseColumns │ - ApiError │
│ - HealthModule │ - drizzleClient │ - User │
│ - CreditsModule │ - migrations │ - CreditOperation │
│ - BaseRepo │ │ │
└────────┬────────┴────────┬────────┴────────┬────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Maerchenzauber │ │ Manadeck │ │ Uload │
│ Backend │ │ Backend │ │ Backend │
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
│ NestJS v11 │ │ NestJS v11 │ │ NestJS v11 │
│ PostgreSQL │ │ PostgreSQL │ │ PostgreSQL │
│ Drizzle ORM │ │ Drizzle ORM │ │ Drizzle ORM │
│ Port: 3002 │ │ Port: 8080 │ │ Port: 3003 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└─────────────────┼─────────────────┘
┌─────────────────────┐
│ Mana Core │
│ (Auth + Credits) │
└─────────────────────┘
```

View file

@ -0,0 +1,356 @@
# Changelog - Shared Packages Integration (2025-11-24)
## Übersicht
Dieses Update führt eine umfassende **Shared Packages Architektur** ein, die gemeinsamen Code über alle vier Web-Apps im Monorepo vereinheitlicht. Die Änderungen reduzieren duplizierter Code erheblich (ca. 3.000 LOC gelöscht), verbessern die Wartbarkeit und sorgen für konsistentes Verhalten und Design.
---
## Neue Shared Packages
### 1. `@manacore/shared-auth` (Neu)
**Pfad**: `packages/shared-auth/`
Einheitliche Authentifizierungslogik für alle Web-Apps:
- **Core Services**:
- `authService.ts` - Login, Logout, Register, Passwort-Reset
- `tokenManager.ts` - JWT Token Storage, Refresh, Validierung
- `jwtUtils.ts` - Token-Dekodierung, Ablaufprüfung, B2B-Erkennung
- **Adapter-Pattern für Plattformunabhängigkeit**:
- `storage` - LocalStorage/Memory-Adapter
- `device` - Geräte-Info für Token-Binding
- `network` - Netzwerk-Status-Erkennung
- **Interceptor**:
- `fetchInterceptor.ts` - Automatische Token-Injection in API-Calls
- **API**:
```typescript
import { initializeWebAuth } from '@manacore/shared-auth';
const { authService, tokenManager } = initializeWebAuth({
baseUrl: 'https://api.example.com',
});
```
### 2. `@manacore/shared-auth-ui` (Neu)
**Pfad**: `packages/shared-auth-ui/`
Wiederverwendbare Auth-UI-Komponenten:
- **Pages**:
- `LoginPage.svelte` - Vollständige Login-Seite mit OAuth
- `RegisterPage.svelte` - Vollständige Registrierungs-Seite
- `ResetPasswordPage.svelte` - Passwort-Reset-Flow
- **Components**:
- `GoogleSignInButton.svelte` - Google OAuth Button
- `AppleSignInButton.svelte` - Apple OAuth Button
- `PasswordInput.svelte` - Passwort-Input mit Validierung
- **Icons**:
- Google/Apple Logos als Svelte-Komponenten
- **Konfiguration**:
```typescript
import { setGoogleClientId, setAppleConfig } from '@manacore/shared-auth-ui';
setGoogleClientId('your-client-id');
setAppleConfig({ clientId: '...', redirectUri: '...' });
```
### 3. `@manacore/shared-tailwind` (Neu)
**Pfad**: `packages/shared-tailwind/`
Einheitliche Tailwind-Konfiguration mit 4 Theme-Varianten:
- **Themes**:
- `lume` - Gold & Modern (Primary: #f8d62b)
- `nature` - Grün & Beruhigend (Primary: #4CAF50)
- `stone` - Slate & Elegant (Primary: #607D8B)
- `ocean` - Blau & Tranquil (Primary: #039BE5)
- **Features**:
- Light/Dark Mode für jedes Theme
- 13+ semantische Farb-Tokens pro Theme
- CSS-Variable-basiertes Theming
- Fertige Component-Utilities
- **Verwendung**:
```javascript
// tailwind.config.js
import preset from '@manacore/shared-tailwind/preset';
export default {
presets: [preset],
content: ['./src/**/*.{html,js,svelte,ts}'],
};
```
### 4. `@manacore/shared-icons` (Neu)
**Pfad**: `packages/shared-icons/`
Einheitliche Icon-Bibliothek basierend auf Phosphor Icons:
- **Komponente**:
```svelte
<script>
import { Icon } from '@manacore/shared-icons';
</script>
<Icon name="play" size={24} class="text-primary" />
```
- **Icons**: 40+ häufig verwendete Icons (play, pause, settings, user, etc.)
### 5. `@manacore/shared-ui` (Erweitert)
**Pfad**: `packages/shared-ui/`
Atomic Design System für Svelte-Komponenten:
- **Atoms** (`src/atoms/`):
- `Text.svelte` - Typography mit Varianten
- `Button.svelte` - Primary, Secondary, Ghost, Danger
- `Badge.svelte` - Status-Badges
- **Molecules** (`src/molecules/`):
- `Toggle.svelte` - Toggle-Switch
- `Input.svelte` - Text-Input mit Label & Validation
- **Organisms** (`src/organisms/`):
- `Modal.svelte` - Overlay-Modal mit Slots
### 6. `@manacore/shared-types` (Erweitert)
**Pfad**: `packages/shared-types/`
Neue Type-Module hinzugefügt:
- `auth.ts` - Auth-bezogene Types (User, Session, Token)
- `theme.ts` - Theme-Konfiguration Types
- `ui.ts` - UI-Komponenten Types
- `common.ts` - Gemeinsame Utility Types
### 7. `@manacore/shared-utils` (Erweitert)
**Pfad**: `packages/shared-utils/`
Neue Utility-Module hinzugefügt:
- `format.ts` - formatDuration, formatFileSize, formatNumber, formatCurrency
- `validation.ts` - isValidEmail, isValidUrl, validatePassword
### 8. `@manacore/shared-i18n` (Neu)
**Pfad**: `packages/shared-i18n/`
Einheitliche Internationalisierung:
- Locale-Detection
- Common Translations (Buttons, Errors)
- svelte-i18n Integration
### 9. `@manacore/shared-config` (Neu)
**Pfad**: `packages/shared-config/`
Environment-Konfiguration:
- Zod-basierte Env-Validierung
- Typsichere Config-Objekte
### 10. `@manacore/shared-subscription-types` (Neu) / `@manacore/shared-subscription-ui` (Neu)
**Pfad**: `packages/shared-subscription-types/`, `packages/shared-subscription-ui/`
Subscription-bezogene Types und UI-Komponenten (Vorbereitung für zukünftige Integration).
---
## App-Spezifische Änderungen
### Memoro Web (`memoro/apps/web/`)
**Gelöschte Dateien** (Migration zu Shared Packages):
- `src/lib/components/AppleSignInButton.svelte``@manacore/shared-auth-ui`
- `src/lib/components/GoogleSignInButton.svelte``@manacore/shared-auth-ui`
- `src/lib/components/Modal.svelte``@manacore/shared-ui`
- `src/lib/components/Toggle.svelte``@manacore/shared-ui`
- `src/lib/components/BillingToggle.svelte` → Nicht mehr benötigt
- `src/lib/components/CostCard.svelte` → Refactored
- `src/lib/components/PackageCard.svelte` → Refactored
- `src/lib/components/SubscriptionCard.svelte` → Refactored
- `src/lib/components/SubscriptionButton.svelte` → Refactored
- `src/lib/components/UsageCard.svelte` → Refactored
- `src/lib/components/ManaIcon.svelte``@manacore/shared-icons`
- `src/lib/components/atoms/Text.svelte``@manacore/shared-ui`
- `src/lib/components/icons/``@manacore/shared-icons`
- `src/lib/utils/appleAuth.ts``@manacore/shared-auth-ui`
- `src/lib/utils/googleAuth.ts``@manacore/shared-auth-ui`
**Modifizierte Dateien**:
- `tailwind.config.js` - Reduziert von 165 auf 12 Zeilen (nutzt shared-tailwind preset)
- `src/app.css` - Drastisch reduziert (nutzt shared-tailwind CSS)
- `src/routes/(public)/login/+page.svelte` - Von 549 auf 46 Zeilen (nutzt LoginPage)
- `src/routes/(public)/register/+page.svelte` - Von 400+ auf 50 Zeilen (nutzt RegisterPage)
- 30+ Komponenten - Icon-Import auf `@manacore/shared-icons` umgestellt
### ManaCore Web (`manacore/apps/web/`)
**Gelöschte Dateien**:
- `src/routes/(auth)/login/+page.server.ts` → Client-side Auth
- `src/routes/(auth)/register/+page.server.ts` → Client-side Auth
**Neue Dateien**:
- `src/lib/stores/authStore.svelte.ts` - Auth-Store mit shared-auth
- `src/lib/components/Icon.svelte` - Icon-Wrapper
- `src/lib/components/ManaCoreLogo.svelte` - Logo-Komponente
- `src/lib/components/ThemeToggle.svelte` - Theme-Umschalter
- `src/lib/components/AppSlider.svelte` - App-Slider
**Modifizierte Dateien**:
- `tailwind.config.js` - Nutzt shared-tailwind preset
- `src/routes/(auth)/login/+page.svelte` - Nutzt LoginPage von shared-auth-ui
- `src/routes/(auth)/register/+page.svelte` - Nutzt RegisterPage von shared-auth-ui
### ManaDeck Web (`manadeck/apps/web/`)
**Gelöschte Dateien**:
- `src/lib/services/authService.ts``@manacore/shared-auth`
- `src/lib/services/tokenManager.ts``@manacore/shared-auth`
- `src/lib/services/deviceManager.ts``@manacore/shared-auth`
- `src/lib/utils/jwt.ts``@manacore/shared-auth`
**Neue Dateien**:
- `src/lib/auth.ts` - Auth-Initialisierung mit shared-auth
- `src/lib/components/Icon.svelte` - Icon-Wrapper
- `src/lib/components/ManaDeckLogo.svelte` - Logo-Komponente
**Modifizierte Dateien**:
- `tailwind.config.js` - Nutzt shared-tailwind
- `src/lib/stores/authStore.svelte.ts` - Nutzt shared-auth
- `src/routes/(auth)/login/+page.svelte` - Nutzt LoginPage
- `src/routes/(auth)/register/+page.svelte` - Nutzt RegisterPage
### Märchenzauber Web (`maerchenzauber/apps/web/`)
**Neue Dateien**:
- `src/lib/auth.ts` - Auth-Setup
- `src/lib/stores/` - Store-Implementierungen
- `src/lib/components/` - Komponenten
- `src/lib/utils/` - Utilities
- `src/lib/types/` - Type-Definitionen
- `src/routes/(auth)/` - Auth-Routen
- `src/app.css` - App-Styles
- `postcss.config.js` - PostCSS-Config
- `.env.example` - Environment-Template
---
## Quantitative Zusammenfassung
| Metrik | Vorher | Nachher | Einsparung |
|--------|--------|---------|------------|
| Dateien geändert | - | 102 | - |
| Zeilen hinzugefügt | - | ~1,400 | - |
| Zeilen gelöscht | - | ~4,300 | ~3,000 LOC |
| Login-Page LOC (Memoro) | 549 | 46 | 92% |
| Tailwind Config LOC (Memoro) | 165 | 12 | 93% |
---
## Abhängigkeiten
Neue Dependencies in App `package.json`:
```json
{
"dependencies": {
"@manacore/shared-auth": "workspace:*",
"@manacore/shared-auth-ui": "workspace:*",
"@manacore/shared-icons": "workspace:*",
"@manacore/shared-tailwind": "workspace:*",
"@manacore/shared-types": "workspace:*",
"@manacore/shared-ui": "workspace:*",
"@manacore/shared-utils": "workspace:*"
}
}
```
---
## Breaking Changes
1. **Icon-Import-Pfade** - Alle Icons müssen von `@manacore/shared-icons` importiert werden
2. **Modal-Import** - Modal kommt jetzt von `@manacore/shared-ui`
3. **Auth-Services** - Lokale authService/tokenManager durch shared-auth ersetzt
4. **OAuth-Buttons** - Konfiguration erfolgt über `setGoogleClientId()` / `setAppleConfig()`
---
## Migration Guide
### Icon Migration
```svelte
<!-- Vorher -->
<script>
import Icon from '$lib/components/Icon.svelte';
</script>
<!-- Nachher -->
<script>
import { Icon } from '@manacore/shared-icons';
</script>
```
### Login Page Migration
```svelte
<!-- Vorher: 500+ Zeilen eigener Code -->
<!-- Nachher -->
<script>
import { LoginPage } from '@manacore/shared-auth-ui';
import MyLogo from '$lib/components/MyLogo.svelte';
import { authStore } from '$lib/stores/authStore';
async function handleSignIn(email, password) {
return authStore.signIn(email, password);
}
</script>
<LoginPage
onSignIn={handleSignIn}
onForgotPassword={handleForgotPassword}
registerUrl="/register"
>
{#snippet logo()}
<MyLogo />
{/snippet}
</LoginPage>
```
### Tailwind Config Migration
```javascript
// Vorher: 150+ Zeilen mit Theme-Definitionen
// Nachher
import preset from '@manacore/shared-tailwind/preset';
export default {
presets: [preset],
content: ['./src/**/*.{html,js,svelte,ts}'],
};
```
---
## Nächste Schritte
1. **Testing** - Alle Apps auf Funktionalität prüfen
2. **Type-Checking** - `pnpm run type-check` in allen Apps ausführen
3. **Build-Verification** - Production Builds testen
4. **Dokumentation** - README-Dateien für neue Packages erstellen
---
## Referenzen
- `SHARED_PACKAGES_ROADMAP.md` - Vollständige Roadmap der Shared Packages
- `packages/shared-auth/src/index.ts` - Auth-API Dokumentation
- `packages/shared-tailwind/src/preset.js` - Theme-Konfiguration

View file

@ -0,0 +1,750 @@
# Docker Setup Analysis - Current State
**Analysis Date**: 2025-12-01
**Scope**: Complete monorepo Docker configuration for Hetzner deployment
## Executive Summary
The monorepo has **solid Docker foundations** with multi-environment compose files and containerized services, but requires **critical fixes** before production deployment to Hetzner.
**Status**: ⚠️ **Not Production Ready** - 4 critical blockers identified
---
## Table of Contents
- [Docker Files Inventory](#docker-files-inventory)
- [Current Architecture](#current-architecture)
- [Containerized Services](#containerized-services)
- [Critical Blocking Issues](#critical-blocking-issues)
- [Configuration Gaps](#configuration-gaps)
- [Best Practices Currently Followed](#best-practices-currently-followed)
- [Immediate Actions Required](#immediate-actions-required)
---
## Docker Files Inventory
### Root-Level Compose Files
| File | Lines | Purpose | Status |
|------|-------|---------|--------|
| `docker-compose.yml` | 190 | Full production stack with Traefik, PostgreSQL, Redis, PgBouncer, Prometheus, Grafana | ⚠️ Missing configs |
| `docker-compose.dev.yml` | 117 | Development setup with minimal infrastructure | ✅ Working |
| `docker-compose.staging.yml` | 273 | Staging environment with 5 backends and registry images | ✅ Working |
| `docker-compose.production.yml` | 253 | Production deployment with resource constraints | ⚠️ Missing external services |
### Active Service Dockerfiles
| Service | Path | Base Image | Status |
|---------|------|------------|--------|
| mana-core-auth | `services/mana-core-auth/Dockerfile` | Node 20-alpine | ✅ Working |
| chat-backend | `apps/chat/apps/backend/Dockerfile` | Node 20-alpine | ✅ Working |
| picture-backend | `apps/picture/apps/backend/Dockerfile` | Node 20-alpine | ✅ Working |
| manadeck-backend | `apps/manadeck/apps/backend/Dockerfile` | Node 18 | ❌ Inconsistent |
### Docker Templates (Reusable)
```
docker/templates/
├── Dockerfile.nestjs # Multi-service NestJS template
├── Dockerfile.sveltekit # SvelteKit web app template
└── Dockerfile.astro # Astro static site with Nginx
```
### Supporting Infrastructure
```
docker/
├── init-db/
│ └── 01-create-databases.sql # Database initialization
├── nginx/
│ └── astro.conf # Nginx config for static sites
├── prometheus/
│ └── prometheus.yml # ❌ MISSING
└── grafana/
└── provisioning/ # ❌ MISSING
```
### Entrypoint Scripts
- `services/mana-core-auth/docker-entrypoint.sh`
- `apps/chat/apps/backend/docker-entrypoint.sh`
- `apps/picture/apps/backend/docker-entrypoint.sh`
- `apps/manadeck/apps/backend/docker-entrypoint.sh` ❌ Missing
---
## Current Architecture
### Development Environment
**File**: `docker-compose.dev.yml`
```
Services:
- PostgreSQL 16-alpine (port 5432)
- Redis 7-alpine (port 6379)
- Optional services via profiles ("auth", "chat", "all")
Network: manacore-network (bridge)
Health Checks: 10-second intervals
Restart Policy: unless-stopped
```
**Purpose**: Minimal stack for local development with hot reload support.
### Staging Environment
**File**: `docker-compose.staging.yml`
```
Services:
- 5 backend microservices (maerchenzauber, chat, manadeck, nutriphi, news)
- PostgreSQL and Redis infrastructure
- Nginx reverse proxy (ports 80/443)
Images: Pre-built from Docker registry
Health Checks: 30-second intervals
Logging: Structured JSON (10MB max-size, 3 files)
Network: manacore-staging (bridge)
```
**Purpose**: Pre-production testing environment.
### Production Environment
**File**: `docker-compose.production.yml`
```
Services:
- 5 backend microservices only (no web apps)
- External PostgreSQL/Redis (not containerized)
Ports: All bound to 127.0.0.1 (localhost only)
Resource Constraints: 1-2 CPUs, 512MB-1GB memory per service
Volumes: None (external services)
Network: manacore-production (bridge)
```
**Purpose**: Minimal application footprint for managed infrastructure.
### Full Infrastructure Stack
**File**: `docker-compose.yml`
```
Services:
- Traefik v3.0 (reverse proxy with Let's Encrypt SSL)
- PostgreSQL 16-alpine + PgBouncer (connection pooling)
- Redis 7-alpine (session management)
- Prometheus (metrics collection) ⚠️ Missing config
- Grafana (monitoring dashboards) ⚠️ Missing provisioning
Features:
- Automatic SSL via Traefik
- Database connection pooling
- Metrics collection
- Dashboard monitoring
```
**Purpose**: Complete on-premises deployment with monitoring.
---
## Containerized Services
### Active & Containerized
| Service | Technology | Port | Status |
|---------|------------|------|--------|
| mana-core-auth | NestJS | 3001 | ✅ Production Ready |
| chat-backend | NestJS | 3002 | ✅ Production Ready |
| picture-backend | NestJS | 3006 | ✅ Production Ready |
| manadeck-backend | NestJS | 3009 | ⚠️ Needs Updates |
### Not Yet Containerized
**Web Apps (SvelteKit)**:
- Templates available in `docker/templates/Dockerfile.sveltekit`
- Need per-project Dockerfiles
- SSR support included
**Landing Pages (Astro)**:
- Templates available in `docker/templates/Dockerfile.astro`
- Nginx configuration ready (`docker/nginx/astro.conf`)
- Static site optimization included
**Mobile Apps (Expo/React Native)**:
- Not containerized (not applicable for Hetzner deployment)
- Built and deployed to app stores separately
---
## Critical Blocking Issues
### 1. ❌ Missing Prometheus Configuration
**Impact**: High - Blocks monitoring deployment
**File**: `docker/prometheus/prometheus.yml`
**Issue**: Referenced in `docker-compose.yml` but file doesn't exist.
**Error**:
```yaml
# docker-compose.yml line ~150
volumes:
- ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
```
**Solution Required**:
```bash
mkdir -p docker/prometheus
```
Create basic `prometheus.yml`:
```yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'postgres'
static_configs:
- targets: ['postgres:9187']
- job_name: 'redis'
static_configs:
- targets: ['redis:9121']
```
### 2. ❌ Missing Grafana Provisioning
**Impact**: High - Blocks monitoring dashboard deployment
**Directory**: `docker/grafana/provisioning/`
**Issue**: Referenced in docker-compose but directories don't exist:
- `docker/grafana/provisioning/dashboards/`
- `docker/grafana/provisioning/datasources/`
**Solution Required**:
```bash
mkdir -p docker/grafana/provisioning/{dashboards,datasources}
```
Create `docker/grafana/provisioning/datasources/prometheus.yml`:
```yaml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true
```
Create `docker/grafana/provisioning/dashboards/default.yml`:
```yaml
apiVersion: 1
providers:
- name: 'Default'
orgId: 1
folder: ''
type: file
disableDeletion: false
updateIntervalSeconds: 10
allowUiUpdates: true
options:
path: /var/lib/grafana/dashboards
```
### 3. ❌ Node Version Inconsistency
**Impact**: Medium - May cause runtime issues
**File**: `apps/manadeck/apps/backend/Dockerfile`
**Issue**: ManaDeck uses Node 18 while all other services use Node 20.
**Current**:
```dockerfile
FROM node:18-alpine AS base
```
**Should Be**:
```dockerfile
FROM node:20-alpine AS base
```
**Location**: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/apps/manadeck/apps/backend/Dockerfile:1`
### 4. ❌ ManaDeck Dockerfile Anomalies
**Impact**: Medium - Build inconsistency
**File**: `apps/manadeck/apps/backend/Dockerfile`
**Issues**:
1. Uses `npm` instead of `pnpm` (lines 15, 33, 38)
2. Includes peer dependency workaround (`--legacy-peer-deps`)
3. Cloud Run specific configuration (port 8080 instead of 3009)
4. Missing proper workspace awareness
**Example Issue**:
```dockerfile
# Line 15 - Should use pnpm
RUN npm ci --omit=dev --legacy-peer-deps
```
**Solution**: Refactor to use pnpm like other services.
---
## Configuration Gaps
### 1. Missing Staging HTTPS/SSL Configuration
**Severity**: Medium
Staging environment (`docker-compose.staging.yml`) only has HTTP Nginx configuration. No SSL/TLS setup for testing HTTPS in staging.
**Recommendation**: Add Let's Encrypt staging certificates or self-signed certs.
### 2. Inconsistent Docker Compose at Service Level
**Severity**: Low
Only `chat` and `picture` have local `docker-compose.yml` files in their service directories. Other projects don't have service-specific compose files.
**Current**:
```
apps/chat/docker-compose.yml ✅ Exists
apps/picture/docker-compose.yml ✅ Exists
apps/manadeck/docker-compose.yml ❌ Missing
apps/zitare/docker-compose.yml ❌ Missing
apps/presi/docker-compose.yml ❌ Missing
```
### 3. Database Initialization Unclear
**Severity**: Medium
Database initialization script (`docker/init-db/01-create-databases.sql`) exists, but unclear if it covers all services beyond mana-core-auth.
**Services Requiring Databases**:
- mana-core-auth (PostgreSQL + Redis) ✅
- chat-backend (PostgreSQL) ?
- picture-backend (PostgreSQL) ?
- manadeck-backend (Supabase external) N/A
- zitare-backend (PostgreSQL) ?
- presi-backend (PostgreSQL) ?
### 4. No Resource Limits in Development
**Severity**: Low
Development environment (`docker-compose.dev.yml`) has no resource limits, which can lead to runaway containers consuming all system resources.
**Recommendation**: Add development-appropriate limits (e.g., 2GB RAM per service).
### 5. Entrypoint Scripts Not Universal
**Severity**: Low
Not all services have entrypoint scripts for handling migrations, health checks, and graceful shutdown.
**Have Entrypoints**:
- mana-core-auth ✅
- chat-backend ✅
- picture-backend ✅
**Missing Entrypoints**:
- manadeck-backend ❌
- zitare-backend ❌
- presi-backend ❌
---
## Best Practices Currently Followed
### ✅ Multi-Stage Dockerfile Builds
All Dockerfiles use multi-stage builds with separate `build` and `production` stages:
```dockerfile
FROM node:20-alpine AS base
# ... setup
FROM base AS build
# ... build artifacts
FROM node:20-alpine AS production
# ... copy only necessary files
```
**Benefit**: Smaller production images (~50% size reduction).
### ✅ Non-Root User Execution
All services run as non-root users:
```dockerfile
RUN addgroup -g 1001 -S nodejs && \
adduser -S nestjs -u 1001
USER nestjs
```
**Security Impact**: Prevents privilege escalation attacks.
### ✅ Alpine Base Images
Using Alpine Linux for minimal attack surface:
```dockerfile
FROM node:20-alpine
```
**Benefit**: ~40MB base image vs ~900MB for standard Node images.
### ✅ Health Checks on All Services
Comprehensive health checks with appropriate timeouts:
```yaml
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
### ✅ Service Dependencies with Health Conditions
Proper dependency orchestration:
```yaml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
```
### ✅ Named Volumes for Data Persistence
Explicit volume naming for easy backup/restore:
```yaml
volumes:
postgres-data:
driver: local
name: manacore-postgres-data
```
### ✅ Environment Variable Externalization
Secrets and configuration via environment files:
```yaml
env_file:
- .env.development
- .env.production
```
### ✅ Custom Bridge Networks
Service isolation with custom networks:
```yaml
networks:
manacore-network:
driver: bridge
name: manacore-network
```
### ✅ Restart Policies
Appropriate restart policies per environment:
```yaml
restart: unless-stopped # Staging/Production
restart: on-failure # Development
```
### ✅ Reverse Proxy with SSL
Traefik with automatic Let's Encrypt SSL:
```yaml
command:
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}"
```
### ✅ Database Connection Pooling
PgBouncer integration for efficient connection management.
### ✅ Redis Caching Layer
Centralized caching with Redis for session management and performance.
### ✅ Docker Compose Profiles
Selective service startup with profiles:
```yaml
services:
mana-core-auth:
profiles: ["auth", "all"]
chat-backend:
profiles: ["chat", "all"]
```
### ✅ pnpm Workspace Awareness
Dockerfiles properly handle pnpm workspaces:
```dockerfile
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
RUN pnpm fetch
RUN pnpm install --frozen-lockfile --offline
```
---
## Best Practice Gaps
### Missing: Docker Build Cache Optimization
**Issue**: No `.dockerignore` optimization strategy across services.
**Impact**: Slower builds, larger build contexts sent to Docker daemon.
**Recommendation**: Add comprehensive `.dockerignore` files per service.
### Missing: Multi-Architecture Build Support
**Issue**: No explicit multi-architecture builds (assumes AMD64 only).
**Impact**: M1/M2 Mac developers may face compatibility issues.
**Recommendation**: Use `docker buildx` for ARM64 + AMD64 builds.
### Missing: Container Security Scanning
**Issue**: No automated security scanning (Trivy, Hadolint, etc.).
**Impact**: Unknown vulnerabilities in production images.
**Recommendation**: Add CI/CD security scanning step.
### Missing: Consistent Logging
**Issue**: Logging configuration varies across environments.
**Recommendation**: Standardize JSON structured logging across all environments.
### Missing: Docker Deployment Documentation
**Issue**: No step-by-step Docker deployment guide.
**Impact**: Difficult onboarding for new developers.
**Recommendation**: Create `DOCKER_DEPLOYMENT.md` with runbooks.
---
## Environment Variable Handling
### Root-Level `.dockerignore` Excludes
```
node_modules/
dist/
.git/
.env*
*.log
coverage/
```
**Status**: ✅ Properly configured
### Variable Management Strategy
**Three-Tier Hierarchy**:
1. **Root `.env.development`**: Shared development variables (committed)
2. **Environment-specific** (`.env.production`): Secrets (gitignored)
3. **Service-specific**: Per-service overrides in compose files
**Key Secrets Required**:
- `POSTGRES_PASSWORD`
- `REDIS_PASSWORD`
- `JWT_PRIVATE_KEY`, `JWT_PUBLIC_KEY`
- `AZURE_OPENAI_API_KEY`
- `GOOGLE_GENAI_API_KEY`
- `SUPABASE_SERVICE_ROLE_KEY`
---
## Network & Volume Strategy
### Networks
**Development**: `manacore-network` (bridge)
**Staging**: `manacore-staging` (bridge)
**Production**: `manacore-production` (bridge)
**Service-to-Service Communication**: Via Docker DNS
- `postgres:5432`
- `redis:6379`
- `mana-core-auth:3001`
### Volumes
**Development**:
```yaml
volumes:
postgres-data: {}
redis-data: {}
```
**Staging**:
```yaml
volumes:
postgres_data:
name: manacore-staging-postgres
redis_data:
name: manacore-staging-redis
```
**Production**: No volumes (external services assumed)
**Full Stack**:
```yaml
volumes:
postgres-data: {}
redis-data: {}
traefik-letsencrypt: {}
prometheus-data: {}
grafana-data: {}
```
---
## Immediate Actions Required
### Priority 1: Critical Blockers (Must Fix Before Deployment)
1. **Create Prometheus Configuration**
```bash
mkdir -p docker/prometheus
# Create prometheus.yml (see issue #1)
```
2. **Create Grafana Provisioning**
```bash
mkdir -p docker/grafana/provisioning/{dashboards,datasources}
# Create provisioning files (see issue #2)
```
3. **Update ManaDeck Node Version**
```bash
# Edit apps/manadeck/apps/backend/Dockerfile
# Change FROM node:18-alpine to node:20-alpine
```
4. **Fix ManaDeck Dockerfile**
```bash
# Refactor to use pnpm instead of npm
# Remove --legacy-peer-deps
# Fix port configuration (3009 instead of 8080)
```
### Priority 2: Configuration Improvements
5. **Add Staging SSL Configuration**
- Add Let's Encrypt staging environment
- Or configure self-signed certificates
6. **Standardize Service Compose Files**
- Add `docker-compose.yml` to all projects
- Follow chat/picture pattern
7. **Document Database Initialization**
- Clarify which databases are created
- Add initialization for all services
8. **Add Development Resource Limits**
- Prevent runaway containers
- Set reasonable limits (e.g., 2GB RAM)
9. **Add Entrypoint Scripts**
- Create for manadeck, zitare, presi
- Standardize migration handling
### Priority 3: Best Practice Enhancements
10. **Optimize Docker Build Cache**
- Add comprehensive `.dockerignore` files
- Optimize layer ordering
11. **Add Multi-Architecture Support**
- Use `docker buildx`
- Build for AMD64 + ARM64
12. **Implement Security Scanning**
- Add Trivy to CI/CD
- Scan images before push
13. **Standardize Logging**
- JSON structured logging
- Consistent across environments
14. **Create Deployment Documentation**
- Step-by-step runbooks
- Troubleshooting guides
---
## Estimated Time to Production Ready
| Phase | Tasks | Time Estimate |
|-------|-------|---------------|
| **Phase 1: Critical Fixes** | Issues #1-4 | 2-4 hours |
| **Phase 2: Configuration** | Issues #5-9 | 4-6 hours |
| **Phase 3: Best Practices** | Issues #10-14 | 6-8 hours |
| **Total** | 14 tasks | **12-18 hours** |
---
## Conclusion
The Docker setup demonstrates **strong architectural foundations** with:
- Multi-environment support ✅
- Service isolation ✅
- Health-driven orchestration ✅
- Security best practices ✅
However, **4 critical blockers** prevent immediate production deployment to Hetzner. Addressing these issues should take **2-4 hours** and will unblock staging and production deployments.
**Recommendation**: Fix Priority 1 items immediately, then incrementally address Priority 2 and 3 for production hardening.
---
**Related Documentation**:
- `HETZNER_PRODUCTION_GUIDE.md` - Comprehensive Hetzner deployment guide
- `DOCKER_COMPOSE_PRODUCTION_ARCHITECTURE.md` - Detailed architecture design
- `DOCKER_GUIDE.md` - Docker usage and best practices
- `DEPLOYMENT_HETZNER.md` - Deployment options comparison

View file

@ -0,0 +1,625 @@
# Hetzner Deployment Summary - Quick Reference
**Date**: 2025-12-01
**Status**: Complete Analysis & Documentation
**Action Required**: Fix 4 critical blockers before deployment
---
## Executive Summary
Your monorepo has **solid Docker foundations** but needs **4 critical fixes** (2-4 hours of work) before production deployment to Hetzner.
### Current State: ⚠️ Not Production Ready
**What's Working**:
- Multi-environment Docker Compose setups ✅
- 4 containerized backends (auth, chat, picture, manadeck) ✅
- Health checks and dependency management ✅
- Security best practices (non-root, Alpine, network isolation) ✅
**What Needs Fixing**:
1. ❌ Missing Prometheus configuration (`docker/prometheus/prometheus.yml`)
2. ❌ Missing Grafana provisioning (`docker/grafana/provisioning/`)
3. ❌ ManaDeck uses Node 18 (should be Node 20)
4. ❌ ManaDeck uses npm instead of pnpm
---
## Quick Start: Get Production Ready in 2-4 Hours
### Step 1: Fix Critical Blockers (1 hour)
```bash
# 1. Create monitoring infrastructure
mkdir -p docker/prometheus
mkdir -p docker/grafana/provisioning/{dashboards,datasources}
# 2. Create Prometheus config
cat > docker/prometheus/prometheus.yml <<'EOF'
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'docker'
static_configs:
- targets: ['172.17.0.1:9323']
EOF
# 3. Create Grafana datasource
cat > docker/grafana/provisioning/datasources/prometheus.yml <<'EOF'
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus:9090
isDefault: true
EOF
# 4. Fix ManaDeck Dockerfile
# Edit apps/manadeck/apps/backend/Dockerfile
# - Change: FROM node:18-alpine → FROM node:20-alpine
# - Replace all "npm" commands with "pnpm"
# - Remove --legacy-peer-deps flag
# 5. Test locally
pnpm docker:up
```
### Step 2: Deploy to Hetzner (1-2 hours)
```bash
# On Hetzner server (use "Docker CE" app during creation)
# 1. Run production setup script (see HETZNER_PRODUCTION_GUIDE.md)
curl -o setup.sh https://your-repo/scripts/hetzner-setup.sh
chmod +x setup.sh
./setup.sh
# 2. Configure environment variables
cd /app
cp .env.production.example .env.production
nano .env.production # Add your secrets
# 3. Deploy application
docker compose -f docker-compose.production.yml up -d
# 4. Verify health
curl http://localhost:3001/api/v1/health # mana-core-auth
curl http://localhost:3002/api/health # chat-backend
```
### Step 3: Setup Monitoring & Backups (1 hour)
```bash
# Deploy monitoring stack
docker compose -f docker-compose.monitoring.yml up -d
# Setup automated backups
apt install borgbackup
./scripts/setup-backups.sh
# Configure backup cron (daily at 2 AM)
echo "0 2 * * * /usr/local/bin/docker-backup.sh" | crontab -
```
---
## Recommended Hetzner Setup
### For Your Monorepo Size (10 backends, 10 web apps)
**Option 1: Single Server (Development/Staging)** - €28/month
```
Server: Hetzner CX33 (4 vCPU, 8GB RAM)
- All services on one server
- Good for staging environment
- ~5-7 concurrent services
```
**Option 2: Production HA Setup** - €37/month
```
2x Hetzner CPX21 (3 vCPU, 4GB RAM) - €14/month
+ Load Balancer - €5.39/month
+ Volumes (3x 50GB) - €7.50/month
+ Storage Box (500GB) - €10.11/month
```
**Option 3: Full Monorepo (All Services)** - €166/month
```
3x App Servers (CX33) - €84/month
1x DB Server (CX31) - €28/month
Load Balancer - €10/month
Volumes + Storage Box - €44/month
vs AWS equivalent: $400-600/month
Savings: 60-75%
```
**Recommendation**: Start with Option 1 (staging), scale to Option 2 (production)
---
## Cost Breakdown: What You'll Pay Monthly
### Minimal Production (5 services)
```
Server (CPX21): €7.00/month
Volume (50GB): €2.50/month
Storage Box (100GB): €3.81/month
─────────────────────────────────────────
Total: €13.81/month
```
### Your Current Setup (Full Monorepo)
```
3x Servers (CX33): €84.00/month
1x Database Server: €28.00/month
Load Balancer: €10.00/month
Volumes (5x 100GB): €25.00/month
Storage Box (1TB): €19.00/month
─────────────────────────────────────────
Total: €166.00/month
```
**vs AWS/GCP**: Saves 60-75% on infrastructure costs
---
## Architecture Overview
### Network Isolation (3-Tier)
```
┌─────────────────────────────────────────┐
│ FRONTEND NETWORK │
│ - Traefik (reverse proxy) │
│ - Web apps (SvelteKit) │
│ - Landing pages (Astro) │
└─────────────────┬───────────────────────┘
┌─────────────────▼───────────────────────┐
│ BACKEND NETWORK │
│ - NestJS backends │
│ - mana-core-auth │
│ - API services │
└─────────────────┬───────────────────────┘
┌─────────────────▼───────────────────────┐
│ DATABASE NETWORK (Internal) │
│ - PostgreSQL │
│ - Redis │
│ - No internet access │
└─────────────────────────────────────────┘
```
### Service Dependency Flow
```
PostgreSQL + Redis
mana-core-auth (Central Authentication)
Backend Services (chat, picture, zitare, presi, manadeck)
Web Apps (SvelteKit)
Landing Pages (Astro)
Traefik (SSL + Reverse Proxy)
```
---
## Key Files & Locations
### Documentation (Created Today)
- `docs/DOCKER_SETUP_ANALYSIS.md` - Complete current state analysis
- `docs/HETZNER_PRODUCTION_GUIDE.md` - Comprehensive deployment guide
- `docs/HETZNER_DEPLOYMENT_SUMMARY.md` - This quick reference
### Existing Documentation
- `docs/DEPLOYMENT_HETZNER.md` - Deployment options comparison (German)
- `docs/DOCKER_GUIDE.md` - Docker usage guide
- `docs/DEPLOYMENT_ARCHITECTURE.md` - Architecture details
### Docker Configuration Files
- `docker-compose.yml` - Full stack with monitoring
- `docker-compose.dev.yml` - Development environment
- `docker-compose.staging.yml` - Staging deployment
- `docker-compose.production.yml` - Production deployment
### Docker Templates
- `docker/templates/Dockerfile.nestjs` - NestJS backend template
- `docker/templates/Dockerfile.sveltekit` - SvelteKit web template
- `docker/templates/Dockerfile.astro` - Astro landing page template
### Active Service Dockerfiles
- `services/mana-core-auth/Dockerfile`
- `apps/chat/apps/backend/Dockerfile`
- `apps/picture/apps/backend/Dockerfile`
- `apps/manadeck/apps/backend/Dockerfile` ⚠️ Needs fixes
---
## Security Checklist
### Critical Security Items
- [ ] **SSH Configuration**
- Disable root login
- Disable password authentication
- SSH keys only
- [ ] **Firewall Setup**
- Hetzner Cloud Firewall (primary layer)
- UFW on server (secondary layer)
- Allow only ports 22, 80, 443
- [ ] **Docker Security**
- Non-root containers
- Docker secrets for production
- Read-only filesystems where possible
- Security updates automated
- [ ] **Backup Strategy**
- Automated daily backups with Borg
- 7 daily, 4 weekly, 6 monthly retention
- Test restore procedure
---
## Monitoring Stack Components
### What You Get
**Metrics Collection**:
- Prometheus - Time-series metrics database
- cAdvisor - Container resource usage
- Node Exporter - Host system metrics
**Visualization**:
- Grafana - Dashboards and alerts
- Pre-built dashboards for Docker, PostgreSQL, Redis
**Logging**:
- Loki - Log aggregation
- Promtail - Log collection from containers
**Access**:
- Grafana UI: `http://your-server:3000`
- Prometheus UI: `http://your-server:9090`
---
## CI/CD Integration
### GitHub Actions Workflow (Recommended)
```yaml
# .github/workflows/deploy-hetzner.yml
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Build and push to GitHub Container Registry
- name: Build and push
run: |
docker build -t ghcr.io/your-org/service:latest .
docker push ghcr.io/your-org/service:latest
# Deploy to Hetzner via SSH
- name: Deploy
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HETZNER_HOST }}
username: deploy
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /app
docker compose pull
docker compose up -d --remove-orphans
```
---
## Common Commands
### Local Development
```bash
# Start all services
pnpm docker:up
# Start specific project
docker compose --profile chat up -d
# View logs
docker compose logs -f chat-backend
# Stop everything
docker compose down
```
### Production Deployment
```bash
# Deploy to production
docker compose -f docker-compose.production.yml up -d
# Check service health
docker compose ps
# View logs
docker compose logs -f --tail=100
# Restart single service
docker compose restart chat-backend
# Update single service (zero downtime)
docker compose up -d --no-deps chat-backend
```
### Monitoring
```bash
# Check resource usage
docker stats
# View container health
docker inspect --format='{{.State.Health.Status}}' container-name
# Access Prometheus
http://localhost:9090
# Access Grafana
http://localhost:3000
```
### Backup & Restore
```bash
# Manual backup
/usr/local/bin/docker-backup.sh
# List backups
borg list ssh://u123456@u123456.your-storagebox.de:23/./backups
# Restore from backup
borg extract ssh://u123456@u123456.your-storagebox.de:23/./backups::20251201-020000
```
---
## Troubleshooting Quick Reference
### Container Won't Start
```bash
# View logs
docker logs container-name
# Check exit code
docker inspect --format='{{.State.ExitCode}}' container-name
# Run interactively
docker run -it --rm image-name sh
```
### High Resource Usage
```bash
# Check stats
docker stats
# Check disk usage
docker system df
# Clean up
docker system prune -a
```
### Network Issues
```bash
# Test connectivity
docker exec container1 ping container2
# Check network
docker network inspect manacore-network
# Restart Docker
systemctl restart docker
```
### Health Check Failing
```bash
# Check health status
docker inspect --format='{{.State.Health}}' container-name
# View health logs
docker inspect --format='{{range .State.Health.Log}}{{.Output}}{{end}}' container-name
# Test health endpoint manually
curl http://localhost:3000/health
```
---
## Next Steps: Priority Order
### Immediate (Today - 2 hours)
1. **Fix Critical Blockers** (See Step 1 above)
- Create monitoring configs
- Fix ManaDeck Dockerfile
2. **Test Locally**
```bash
pnpm docker:up
docker compose ps # All should be healthy
```
### Short Term (This Week - 4 hours)
3. **Provision Hetzner Server**
- Choose server type (CX33 recommended for start)
- Select "Docker CE" app during creation
- Configure private network
4. **Initial Deployment**
- Run production setup script
- Deploy application
- Configure monitoring
5. **Setup Backups**
- Configure Storage Box
- Initialize Borg repository
- Test restore procedure
### Medium Term (Next Week - 8 hours)
6. **CI/CD Pipeline**
- Setup GitHub Actions workflow
- Configure secrets
- Test automated deployment
7. **Security Hardening**
- Configure Hetzner Cloud Firewall
- Setup fail2ban
- Enable automatic security updates
8. **Load Testing**
- Test with expected load
- Tune resource limits
- Optimize performance
### Long Term (Ongoing)
9. **Documentation**
- Create runbooks for common tasks
- Document incident response
- Team training
10. **Optimization**
- Monitor costs
- Right-size resources
- Implement auto-scaling if needed
---
## Success Metrics
### How to Know You're Production Ready
✅ **Infrastructure**
- [ ] Server accessible via SSH with key authentication
- [ ] Docker and docker-compose installed and working
- [ ] Firewall configured (Hetzner + UFW)
- [ ] Private network configured (if multi-server)
✅ **Application**
- [ ] All services start and pass health checks
- [ ] Environment variables properly configured
- [ ] SSL/TLS working (Let's Encrypt)
- [ ] Database migrations run successfully
✅ **Monitoring**
- [ ] Prometheus collecting metrics
- [ ] Grafana dashboards accessible
- [ ] Alerts configured and tested
- [ ] Logs centralized in Loki
✅ **Backups**
- [ ] Automated daily backups running
- [ ] Storage Box configured
- [ ] Restore procedure tested
- [ ] Retention policy configured
✅ **CI/CD**
- [ ] GitHub Actions workflow working
- [ ] Automated deployments successful
- [ ] Rollback procedure tested
---
## Getting Help
### Documentation References
- **Current State**: `docs/DOCKER_SETUP_ANALYSIS.md`
- **Complete Guide**: `docs/HETZNER_PRODUCTION_GUIDE.md`
- **Docker Usage**: `docs/DOCKER_GUIDE.md`
- **Options Comparison**: `docs/DEPLOYMENT_HETZNER.md`
### External Resources
- [Hetzner Cloud Docs](https://docs.hetzner.com/cloud/)
- [Docker Compose Reference](https://docs.docker.com/compose/)
- [Traefik Documentation](https://doc.traefik.io/traefik/)
- [Prometheus Documentation](https://prometheus.io/docs/)
### Support Channels
- Hetzner Support: https://console.hetzner.cloud/
- Docker Community: https://forums.docker.com/
- Your Team Documentation: `docs/` directory
---
## Summary
You have:
- ✅ **Solid foundation** with multi-environment Docker setup
- ✅ **4 containerized services** ready to deploy
- ✅ **Complete documentation** for production deployment
- ⚠️ **4 critical fixes** needed (2-4 hours of work)
After fixes:
- 🚀 **2-4 hours** to deploy to Hetzner
- 💰 **€14-166/month** depending on scale (60-75% cheaper than AWS)
- 📊 **Complete monitoring** with Prometheus + Grafana
- 🔒 **Production-grade security** with firewalls and automated backups
- 🔄 **Automated deployments** with GitHub Actions
**Total time to production**: ~10-15 hours from current state
---
**Document Version**: 1.0
**Last Updated**: 2025-12-01
**Next Review**: After first deployment

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,127 @@
# Documentation Restructure - December 16, 2025
## Summary
Restructured documentation based on industry best practices from HackerNews discussion and HumanLayer blog post on writing effective CLAUDE.md files.
## Changes Made
### Root CLAUDE.md
- **Before:** 678 lines, 22 KB
- **After:** 176 lines, 5.7 KB
- **Reduction:** 74% smaller
#### What Was Removed
- Detailed project tables (moved conceptually to docs/)
- Extensive authentication code examples (kept brief examples, reference .claude/guidelines/)
- Object storage implementation details
- Landing page deployment procedures
- Detailed environment variable setup
- Archived projects list (13 projects)
- Code quality infrastructure TODO section
#### What Was Added
- **Critical Gotchas** section (5 key issues Claude frequently gets wrong)
- **Verification signature** (🏗️ ManaCore Monorepo) to confirm Claude read the file
- Clearer signposting to detailed documentation
- Focus on universally applicable patterns only
### Documentation Organization
#### New Structure
```
docs/
├── README.md # Navigation index (NEW)
├── getting-started/ # (NEW - empty for now)
├── architecture/ # (NEW - empty for now)
├── development/ # (NEW - empty for now)
├── deployment/ # (NEW - empty for now)
├── operations/ # (NEW - empty for now)
├── reference/ # (NEW - empty for now)
└── archive/ # (NEW)
```
#### Files Deleted
- `ENV_AUDIT_SUMMARY.md` - Outdated audit (Dec 1, 2024)
- `ENV_BACKEND_MATRIX.md` - Outdated audit
- `ENV_CONFIGURATION_AUDIT.md` - Outdated audit
- `README_ENV_AUDIT.md` - Outdated audit
- `DEPENDENCY_ALIGNMENT.md` - Point-in-time snapshot
#### Files Archived
Moved to `docs/archive/`:
- `DOCKER_SETUP_ANALYSIS.md` - Analysis document
- `BACKEND_ARCHITECTURE.md` - Possibly outdated (25 KB)
- `PROJECT_OVERVIEW.md` - Possibly outdated (41 KB)
- `TESTING_SUMMARY.md` - Outdated test count
- `TESTING_IMPLEMENTATION_GUIDE.md` - Superseded
- `CHANGELOG_2025-11-24.md` - Historical
- `HETZNER_DEPLOYMENT_SUMMARY.md` - Redundant with other deployment docs
### Best Practices Applied
1. **Instruction Budget Management**
- Kept only high-signal, universally applicable information
- Reduced from 678 lines to 176 lines
- AI instruction budget is ~150-200 total; we now use ~176
2. **Progressive Disclosure**
- Main CLAUDE.md is concise entry point
- Links to detailed .claude/guidelines/ for code patterns
- Links to docs/ for operational procedures
3. **Critical Gotchas**
- Turborepo infinite loops
- Svelte 5 runes only
- Auth integration requirements
- Go-style error handling
- Environment variable prefixes
4. **Verification Mechanism**
- Added project signature requirement (🏗️ ManaCore Monorepo)
- Helps detect when Claude stops following instructions
## Backup
Original CLAUDE.md saved as `CLAUDE.md.backup` (22 KB, 678 lines).
## Metrics
| Metric | Before | After | Change |
|--------|--------|-------|--------|
| CLAUDE.md lines | 678 | 176 | -74% |
| CLAUDE.md size | 22 KB | 5.7 KB | -74% |
| docs/ files | 50+ | 43 | -7 deleted, -7 archived |
| Documented projects | 18 (active + archived) | 6 (active only) | -67% |
## Next Steps (Phase 2)
Future improvements to consider:
1. **Consolidate Environment Docs**
- Merge remaining env docs into single `docs/reference/environment-matrix.md`
2. **Split DEPLOYMENT_ARCHITECTURE.md**
- Currently 2,814 lines (81 KB)
- Should be 6-8 separate documents
3. **Reorganize docs/**
- Move files into logical subdirectories
- Create topic-based navigation
4. **Consolidate Authentication Docs**
- Keep `.claude/guidelines/authentication.md` (code patterns)
- Keep separate (already exists in .claude/guidelines/)
## References
- [HN Discussion on CLAUDE.md](https://news.ycombinator.com/item?id=46098838)
- [HumanLayer: Writing a Good CLAUDE.md](https://www.humanlayer.dev/blog/writing-a-good-claude-md)
## Key Insights
1. **Length matters** - Shorter files = better AI performance
2. **Universal over specific** - Only include broadly applicable patterns
3. **Verification is critical** - Add canary instructions to detect compliance
4. **Progressive disclosure** - Link to details rather than inline everything
5. **Information density** - Every line should justify its inclusion

View file

@ -0,0 +1,646 @@
# Testing Implementation Guide
**Quick Start Guide for Adding Tests to the Manacore Monorepo**
## Table of Contents
- [Quick Start](#quick-start)
- [Adding Tests to NestJS Backend](#adding-tests-to-nestjs-backend)
- [Adding Tests to React Native Mobile](#adding-tests-to-react-native-mobile)
- [Adding Tests to SvelteKit Web](#adding-tests-to-sveltekit-web)
- [Adding Tests to Shared Packages](#adding-tests-to-shared-packages)
- [Running Tests Locally](#running-tests-locally)
- [Coverage Reports](#coverage-reports)
- [Troubleshooting](#troubleshooting)
## Quick Start
### Prerequisites
```bash
# Ensure you have the correct versions
node --version # Should be 20+
pnpm --version # Should be 9.15.0
```
### Install Dependencies
```bash
# From monorepo root
pnpm install
```
### Run All Tests
```bash
# Run tests for all projects
pnpm test
# Run tests for specific project
pnpm --filter @maerchenzauber/backend test
pnpm --filter @memoro/mobile test
pnpm --filter @uload/web test:unit
```
## Adding Tests to NestJS Backend
### 1. Install Testing Dependencies (if not already installed)
```bash
cd apps/YOUR_PROJECT/apps/backend
pnpm add -D @nestjs/testing jest ts-jest @types/jest supertest @types/supertest
```
### 2. Create Jest Configuration
Create `jest.config.js` in your backend directory:
```javascript
const baseConfig = require('@manacore/test-config/jest-backend');
module.exports = {
...baseConfig,
// Project-specific overrides if needed
};
```
Or inline in `package.json`:
```json
{
"jest": {
"preset": "@manacore/test-config/jest-backend"
}
}
```
### 3. Add Test Scripts to package.json
```json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand"
}
}
```
### 4. Create Your First Test
```typescript
// src/example/__tests__/example.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { ExampleService } from '../example.service';
describe('ExampleService', () => {
let service: ExampleService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ExampleService],
}).compile();
service = module.get<ExampleService>(ExampleService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
```
### 5. Run Tests
```bash
pnpm test
pnpm test:cov # With coverage
```
## Adding Tests to React Native Mobile
### 1. Install Testing Dependencies
```bash
cd apps/YOUR_PROJECT/apps/mobile
pnpm add -D jest jest-expo @testing-library/react-native @testing-library/jest-native
```
### 2. Create Jest Configuration
Create `jest.config.js`:
```javascript
module.exports = {
preset: '@manacore/test-config/jest-mobile',
// Project-specific overrides
};
```
### 3. Create Setup File
Create `jest.setup.js`:
```javascript
import '@testing-library/jest-native/extend-expect';
// Mock Expo modules
jest.mock('expo-secure-store', () => ({
getItemAsync: jest.fn(),
setItemAsync: jest.fn(),
deleteItemAsync: jest.fn(),
}));
jest.mock('expo-font', () => ({
loadAsync: jest.fn(),
isLoaded: jest.fn(() => true),
}));
// Global test setup
global.fetch = jest.fn();
```
### 4. Add Test Scripts to package.json
```json
{
"scripts": {
"test": "jest --watchAll",
"test:ci": "jest --ci --coverage --watchAll=false",
"test:cov": "jest --coverage --watchAll=false"
}
}
```
### 5. Create Your First Component Test
```typescript
// src/components/Button/__tests__/Button.test.tsx
import React from 'react';
import { render, fireEvent } from '@testing-library/react-native';
import { Button } from '../Button';
describe('Button', () => {
it('should render', () => {
const { getByText } = render(<Button>Click Me</Button>);
expect(getByText('Click Me')).toBeTruthy();
});
it('should call onPress', () => {
const onPress = jest.fn();
const { getByText } = render(<Button onPress={onPress}>Click</Button>);
fireEvent.press(getByText('Click'));
expect(onPress).toHaveBeenCalled();
});
});
```
### 6. Run Tests
```bash
pnpm test
```
## Adding Tests to SvelteKit Web
### 1. Install Testing Dependencies
```bash
cd apps/YOUR_PROJECT/apps/web
pnpm add -D vitest @vitest/coverage-v8 @testing-library/svelte jsdom
pnpm add -D @playwright/test # For E2E tests
```
### 2. Create Vitest Configuration
Create `vitest.config.ts`:
```typescript
import { defineConfig, mergeConfig } from 'vitest/config';
import svelteConfig from '@manacore/test-config/vitest-svelte';
import { sveltekit } from '@sveltejs/kit/vite';
export default mergeConfig(
svelteConfig,
defineConfig({
plugins: [sveltekit()],
test: {
// Project-specific overrides
},
})
);
```
### 3. Create Vitest Setup File
Create `vitest.setup.ts`:
```typescript
import { expect, afterEach } from 'vitest';
import { cleanup } from '@testing-library/svelte';
// Cleanup after each test
afterEach(() => {
cleanup();
});
```
### 4. Create Playwright Configuration (E2E)
Create `playwright.config.ts`:
```typescript
import { defineConfig } from '@playwright/test';
import baseConfig from '@manacore/test-config/playwright';
export default defineConfig({
...baseConfig,
use: {
...baseConfig.use,
baseURL: 'http://localhost:5173',
},
webServer: {
command: 'pnpm run build && pnpm run preview',
port: 5173,
},
});
```
### 5. Add Test Scripts to package.json
```json
{
"scripts": {
"test": "pnpm run test:unit && pnpm run test:e2e",
"test:unit": "vitest run",
"test:unit:watch": "vitest",
"test:unit:cov": "vitest run --coverage",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui"
}
}
```
### 6. Create Your First Component Test
```typescript
// src/lib/components/Button/__tests__/Button.test.ts
import { render, screen } from '@testing-library/svelte';
import { describe, it, expect, vi } from 'vitest';
import Button from '../Button.svelte';
describe('Button', () => {
it('should render', () => {
render(Button, { props: { children: 'Click Me' } });
expect(screen.getByText('Click Me')).toBeTruthy();
});
it('should call onclick', async () => {
const onclick = vi.fn();
render(Button, { props: { onclick, children: 'Click' } });
await screen.getByText('Click').click();
expect(onclick).toHaveBeenCalled();
});
});
```
### 7. Create Your First E2E Test
```typescript
// e2e/homepage.spec.ts
import { test, expect } from '@playwright/test';
test('homepage loads successfully', async ({ page }) => {
await page.goto('/');
await expect(page.locator('h1')).toBeVisible();
});
```
### 8. Run Tests
```bash
pnpm test:unit # Unit tests
pnpm test:e2e # E2E tests
pnpm test:unit:cov # With coverage
```
## Adding Tests to Shared Packages
### 1. Install Vitest
```bash
cd packages/YOUR_PACKAGE
pnpm add -D vitest @vitest/coverage-v8
```
### 2. Create Vitest Configuration
Create `vitest.config.ts`:
```typescript
import { defineConfig, mergeConfig } from 'vitest/config';
import baseConfig from '@manacore/test-config/vitest-base';
export default mergeConfig(
baseConfig,
defineConfig({
test: {
// Package-specific config
},
})
);
```
### 3. Add Test Scripts to package.json
```json
{
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"test:cov": "vitest run --coverage"
}
}
```
### 4. Create Your First Utility Test
```typescript
// src/__tests__/format.test.ts
import { describe, it, expect } from 'vitest';
import { formatDate, truncate } from '../format';
describe('formatDate', () => {
it('should format date correctly', () => {
const date = new Date('2024-01-15T12:00:00Z');
expect(formatDate(date, 'yyyy-MM-dd')).toBe('2024-01-15');
});
});
describe('truncate', () => {
it('should truncate long strings', () => {
expect(truncate('Very long text', 10)).toBe('Very long…');
});
});
```
### 5. Run Tests
```bash
pnpm test
pnpm test:cov
```
## Running Tests Locally
### Individual Project Tests
```bash
# Backend
pnpm --filter @maerchenzauber/backend test
# Mobile
pnpm --filter @memoro/mobile test
# Web (unit tests)
pnpm --filter @uload/web test:unit
# Web (E2E tests)
pnpm --filter @uload/web test:e2e
# Shared package
pnpm --filter @manacore/shared-utils test
```
### All Tests for a Project
```bash
# Run all tests for maerchenzauber
pnpm --filter maerchenzauber... test
```
### Watch Mode
```bash
# Backend (Jest)
pnpm --filter @maerchenzauber/backend test:watch
# Mobile (Jest)
pnpm --filter @memoro/mobile test
# Web (Vitest)
pnpm --filter @uload/web test:unit:watch
```
### With Coverage
```bash
# Backend
pnpm --filter @maerchenzauber/backend test:cov
# Mobile
pnpm --filter @memoro/mobile test:cov
# Web
pnpm --filter @uload/web test:unit:cov
# View HTML report
open apps/YOUR_PROJECT/apps/backend/coverage/index.html
```
## Coverage Reports
### View Coverage Locally
```bash
# Generate coverage
pnpm test:cov
# Open HTML report
open coverage/index.html
```
### Coverage Thresholds
All projects have these default thresholds:
- **Lines**: 80%
- **Functions**: 80%
- **Branches**: 80%
- **Statements**: 80%
To override for your project:
**Jest (Backend/Mobile)**:
```javascript
module.exports = {
preset: '@manacore/test-config/jest-backend',
coverageThresholds: {
global: {
lines: 90, // Higher threshold
},
},
};
```
**Vitest (Web/Shared)**:
```typescript
export default defineConfig({
test: {
coverage: {
thresholds: {
lines: 90,
},
},
},
});
```
### CI/CD Coverage
- Coverage reports are automatically uploaded to Codecov on PR/push to main
- Coverage badges available at `https://codecov.io/gh/YOUR_ORG/YOUR_REPO`
- PR comments show coverage diff
## Troubleshooting
### Common Issues
#### "Cannot find module" errors
```bash
# Clear caches
pnpm store prune
pnpm install --force
# Backend: Clear Jest cache
pnpm --filter @YOUR_PROJECT/backend test --clearCache
# Mobile: Clear Metro cache
cd apps/YOUR_PROJECT/apps/mobile
rm -rf node_modules/.cache
```
#### Transform errors in React Native
Make sure `transformIgnorePatterns` in `jest.config.js` includes all necessary packages:
```javascript
transformIgnorePatterns: [
'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@manacore/.*)',
];
```
#### Svelte component tests fail
Ensure you have the correct Vite plugin:
```typescript
import { sveltekit } from '@sveltejs/kit/vite';
export default defineConfig({
plugins: [sveltekit()],
});
```
#### Playwright browser not installed
```bash
pnpm --filter @YOUR_PROJECT/web exec playwright install chromium
```
#### Tests timeout
Increase timeout in config:
```typescript
// Vitest
export default defineConfig({
test: {
testTimeout: 30000, // 30 seconds
},
});
// Jest
module.exports = {
testTimeout: 30000,
};
```
#### Coverage not generating
```bash
# Jest: Ensure collectCoverageFrom is set
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!**/*.d.ts',
],
# Vitest: Ensure include is set
coverage: {
include: ['src/**/*.{js,ts,svelte}'],
}
```
### Getting Help
1. Check existing tests in the project for patterns
2. Review [docs/TESTING.md](./TESTING.md) for detailed strategies
3. Check example tests in [docs/test-examples/](./test-examples/)
4. Review CI logs for failure details
5. Ask in team chat for project-specific guidance
## Next Steps
1. **Start with critical paths**: Auth, payments, data integrity
2. **Add tests incrementally**: Don't try to test everything at once
3. **Follow TDD when possible**: Write tests before code
4. **Review coverage**: Aim for 80% minimum, 100% for critical code
5. **Keep tests fast**: Unit tests < 100ms, integration < 1s
6. **Update this guide**: Add project-specific tips as you learn
## Resources
- [Full Testing Strategy](./TESTING.md)
- [Test Examples](./test-examples/)
- [Jest Documentation](https://jestjs.io/)
- [Vitest Documentation](https://vitest.dev/)
- [Playwright Documentation](https://playwright.dev/)
- [Testing Library](https://testing-library.com/)
---
**Quick Reference Commands**
```bash
# Run all tests
pnpm test
# Run specific project tests
pnpm --filter @PROJECT/APP test
# Run with coverage
pnpm --filter @PROJECT/APP test:cov
# Run in watch mode
pnpm --filter @PROJECT/APP test:watch
# Run E2E tests
pnpm --filter @PROJECT/web test:e2e
# Type check
pnpm type-check
# Lint
pnpm lint
# Format
pnpm format
```

View file

@ -0,0 +1,477 @@
# Testing Strategy Summary
**Created by**: Hive Mind - Tester Agent
**Date**: 2025-11-27
**Status**: Ready for Implementation
## Executive Summary
This document provides a comprehensive automated testing strategy for the Manacore monorepo, designed to achieve **80% test coverage** for new code while maintaining development velocity. The strategy includes test frameworks, configurations, examples, and CI/CD integration for all app types in the monorepo.
## Current State
### Test Coverage Analysis
- **Total Test Files**: 25 (across entire monorepo)
- **Current Coverage**: Sparse (~5% estimated)
- **Target Coverage**: 80% for new code, 100% for critical paths
### Existing Tests by Project
| Project | Backend | Mobile | Web | Total |
| -------------- | ------- | ------ | ----- | ------ |
| Maerchenzauber | 8 | 5 | 0 | 13 |
| Memoro | 0 | 3 | 0 | 3 |
| Uload | 0 | 0 | 9 | 9 |
| **Total** | **8** | **8** | **9** | **25** |
### Strengths
✅ Maerchenzauber mobile has excellent auth test patterns
✅ Uload web demonstrates good Vitest + Playwright setup
✅ NestJS backends have Jest configured
### Gaps
❌ No shared test utilities across projects
❌ No coverage thresholds enforced
❌ No CI/CD test automation
❌ No shared package tests
❌ No E2E testing for mobile apps
## Deliverables
### 1. Documentation (docs/)
#### [TESTING.md](./TESTING.md) - 35,000+ words
Comprehensive testing strategy covering:
- Testing infrastructure by app type
- Test organization patterns
- Coverage strategy (80% minimum, 100% for critical paths)
- Testing scenarios with code examples
- CI/CD integration guide
- Implementation roadmap (14-week plan)
- Best practices and FAQs
#### [TESTING_IMPLEMENTATION_GUIDE.md](./TESTING_IMPLEMENTATION_GUIDE.md) - 8,000+ words
Quick start guide for developers:
- Step-by-step setup for each app type
- Running tests locally
- Coverage reports
- Troubleshooting common issues
- Quick reference commands
#### [TESTING_SUMMARY.md](./TESTING_SUMMARY.md) - This file
High-level overview and index of all testing resources.
### 2. Shared Test Configuration (packages/test-config/)
Created reusable test configurations for all app types:
```
packages/test-config/
├── jest.config.backend.js # NestJS backends
├── jest.config.mobile.js # React Native mobile
├── vitest.config.base.ts # Shared packages
├── vitest.config.svelte.ts # SvelteKit web
├── playwright.config.base.ts # E2E tests
├── package.json
├── tsconfig.json
└── README.md
```
**Features**:
- 80% coverage thresholds enforced
- Auto-clear mocks between tests
- Platform-specific ignore patterns
- Coverage reporting configured
- TypeScript support
### 3. Example Test Files (docs/test-examples/)
Created comprehensive examples for each app type:
```
test-examples/
├── backend/
│ ├── example.controller.spec.ts # Controller testing
│ └── example.service.spec.ts # Service testing
├── mobile/
│ ├── ExampleComponent.test.tsx # Component testing
│ └── authService.test.ts # Service testing
├── web/
│ ├── Button.test.ts # Svelte 5 components
│ └── page.server.test.ts # Server functions
├── shared/
│ └── format.test.ts # Utility functions
└── README.md
```
**Total Example Code**: ~3,500 lines of production-quality test examples
### 4. CI/CD Integration (.github/workflows/)
#### [test.yml](./.github/workflows/test.yml)
Automated testing workflow with:
- Parallel test execution across all projects
- Coverage reporting to Codecov
- Automated PR comments with results
- 8 job types:
1. Backend tests (5 projects)
2. Mobile tests (7 projects)
3. Web tests (9 projects)
4. E2E tests (web)
5. Shared package tests
6. Lint & format checks
7. Coverage aggregation
8. Status reporting
**Features**:
- Matrix strategy for parallel execution
- Automatic coverage uploads
- PR status checks
- Failure notifications
- Codecov integration
## Testing Framework Matrix
| App Type | Framework | Config Location | Coverage Tool |
| ----------------------- | ---------------- | ------------------------------------- | ------------- |
| **NestJS Backend** | Jest | `@manacore/test-config/jest-backend` | Jest |
| **React Native Mobile** | Jest + jest-expo | `@manacore/test-config/jest-mobile` | Jest |
| **SvelteKit Web** | Vitest | `@manacore/test-config/vitest-svelte` | v8 |
| **Astro Landing** | Vitest | `@manacore/test-config/vitest-base` | v8 |
| **Shared Packages** | Vitest | `@manacore/test-config/vitest-base` | v8 |
| **E2E (Web)** | Playwright | `@manacore/test-config/playwright` | N/A |
| **E2E (Mobile)** | Detox/Maestro | TBD | N/A |
## Coverage Strategy
### Global Thresholds
- **Default**: 80% (lines, functions, branches, statements)
- **Critical Paths**: 100% (auth, payments, data integrity)
- **New Code**: Must meet 80% minimum
- **Pull Requests**: Cannot decrease overall coverage
### Critical Paths Requiring 100% Coverage
1. **Authentication**:
- `@manacore/shared-auth` package
- Token management and JWT verification
- All auth services across apps
2. **Payment/Credit System**:
- Credit consumption logic
- Stripe integration
- Transaction recording
3. **Data Integrity**:
- Database migrations
- RLS policy validation
- User data validation
### Coverage Reporting
- **Local**: HTML reports in `coverage/` directory
- **CI/CD**: Uploaded to Codecov
- **PR Comments**: Coverage diff displayed
- **Badges**: Available for README files
## Implementation Roadmap
### Phase 1: Foundation (Week 1-2) ✅ COMPLETE
- [x] Create shared test configurations
- [x] Install testing dependencies
- [x] Create shared test utilities package
- [x] Set up coverage reporting
- [x] Document testing patterns
### Phase 2: Critical Path Coverage (Week 3-4)
- [ ] `@manacore/shared-auth` package (100% coverage)
- [ ] Token manager tests
- [ ] JWT validation tests
- [ ] Credit consumption logic
- [ ] Stripe integration mocks
### Phase 3: Backend Coverage (Week 5-6)
- [ ] Maerchenzauber backend (80%)
- [ ] Chat backend (80%)
- [ ] Manadeck backend (80%)
- [ ] Nutriphi backend (80%)
### Phase 4: Mobile Coverage (Week 7-8)
- [ ] Maerchenzauber mobile (expand from 5 tests to 80%)
- [ ] Memoro mobile (expand from 3 tests to 80%)
- [ ] Picture mobile (80%)
- [ ] Chat mobile (80%)
### Phase 5: Web Coverage (Week 9-10)
- [ ] Uload web (expand from 9 tests to 80%)
- [ ] Manacore web (80%)
- [ ] SvelteKit apps (80%)
### Phase 6: Shared Packages (Week 11)
- [ ] All `@manacore/*` packages (90%)
### Phase 7: CI/CD Integration (Week 12) ✅ COMPLETE
- [x] GitHub Actions workflows
- [x] Codecov integration
- [x] PR checks
- [x] Coverage gates
### Phase 8: E2E Testing (Week 13-14)
- [ ] Playwright for all web apps
- [ ] Detox/Maestro for mobile apps
- [ ] Critical user flows
## Quick Start Commands
```bash
# Install dependencies
pnpm install
# Run all tests
pnpm test
# Run tests for specific project
pnpm --filter @maerchenzauber/backend test
pnpm --filter @memoro/mobile test
pnpm --filter @uload/web test:unit
# Run with coverage
pnpm --filter @PROJECT/APP test:cov
# Run E2E tests
pnpm --filter @PROJECT/web test:e2e
# Run in watch mode
pnpm --filter @PROJECT/APP test:watch
```
## File Structure
```
manacore-monorepo/
├── .github/
│ └── workflows/
│ └── test.yml # CI/CD test workflow ✅
├── docs/
│ ├── TESTING.md # Full strategy (35k words) ✅
│ ├── TESTING_IMPLEMENTATION_GUIDE.md # Quick start (8k words) ✅
│ ├── TESTING_SUMMARY.md # This file ✅
│ └── test-examples/ # Example tests ✅
│ ├── backend/
│ ├── mobile/
│ ├── web/
│ ├── shared/
│ └── README.md
├── packages/
│ └── test-config/ # Shared configs ✅
│ ├── jest.config.backend.js
│ ├── jest.config.mobile.js
│ ├── vitest.config.base.ts
│ ├── vitest.config.svelte.ts
│ ├── playwright.config.base.ts
│ └── README.md
└── apps/
└── */apps/*/ # Individual app tests
├── __tests__/
├── jest.config.js
└── vitest.config.ts
```
## Key Metrics
### Documentation
- **Total Words**: ~45,000+
- **Code Examples**: ~3,500 lines
- **Test Scenarios**: 100+ examples
- **Configuration Files**: 6
### Coverage
- **Current**: ~5% (25 test files)
- **Target**: 80% (new code), 100% (critical paths)
- **Projects with Tests**: 3 of 9
- **Projects Without Tests**: 6 of 9
### Implementation Effort
- **Estimated Time**: 14 weeks (phased approach)
- **Critical Path**: 2 weeks (auth, payments)
- **Backend Coverage**: 2 weeks
- **Mobile Coverage**: 2 weeks
- **Web Coverage**: 2 weeks
- **Shared Packages**: 1 week
- **E2E Testing**: 2 weeks
## Testing Best Practices
### 1. AAA Pattern
```typescript
it('should create item successfully', async () => {
// Arrange
const input = { title: 'Test' };
// Act
const result = await service.create(input);
// Assert
expect(result).toBeDefined();
});
```
### 2. Descriptive Test Names
```typescript
// ✅ Good
it('should reject sign in with invalid email format');
// ❌ Bad
it('test sign in');
```
### 3. Test Behavior, Not Implementation
```typescript
// ✅ Good - Testing user-facing behavior
expect(screen.getByText('Error message')).toBeVisible();
// ❌ Bad - Testing internal state
expect(component.state.hasError).toBe(true);
```
### 4. Mock External Dependencies
```typescript
// Mock API calls
global.fetch = jest.fn();
// Mock database
jest.mock('@/lib/db');
// Mock storage
jest.mock('expo-secure-store');
```
### 5. Clean Up After Tests
```typescript
beforeEach(() => {
jest.clearAllMocks();
});
afterEach(() => {
cleanup();
});
```
## Technology Stack
### Testing Libraries
- **Jest**: NestJS backends, React Native mobile
- **Vitest**: SvelteKit web, Astro landing, shared packages
- **Playwright**: E2E tests for web
- **React Native Testing Library**: Mobile component tests
- **Testing Library Svelte**: Web component tests
- **Supertest**: Backend E2E tests
- **MSW**: API mocking
### Coverage Tools
- **Jest Coverage**: Built-in for Jest
- **Vitest Coverage (v8)**: Fast coverage for Vitest
- **Codecov**: CI/CD coverage reporting
- **Istanbul/NYC**: Backup coverage tool
## Next Steps
### For Developers
1. **Read** [TESTING_IMPLEMENTATION_GUIDE.md](./TESTING_IMPLEMENTATION_GUIDE.md)
2. **Review** example tests in [test-examples/](./test-examples/)
3. **Start** with critical path tests (auth, payments)
4. **Follow** existing patterns from examples
5. **Run** `pnpm test:cov` to check coverage
6. **Iterate** until 80% threshold is met
### For Project Managers
1. **Review** implementation roadmap (14 weeks)
2. **Prioritize** critical path coverage (weeks 3-4)
3. **Allocate** time for test writing in sprints
4. **Monitor** coverage reports in PRs
5. **Enforce** 80% threshold for new code
### For DevOps
1. **Enable** Codecov integration
2. **Configure** GitHub branch protection rules
3. **Set up** PR status checks
4. **Monitor** CI/CD performance
5. **Optimize** test execution time
## Resources
### Documentation
- [Full Testing Strategy](./TESTING.md) - Comprehensive guide
- [Implementation Guide](./TESTING_IMPLEMENTATION_GUIDE.md) - Quick start
- [Test Examples](./test-examples/) - Production-quality examples
- [Shared Configs](../packages/test-config/) - Reusable configurations
### External Resources
- [Jest Documentation](https://jestjs.io/)
- [Vitest Documentation](https://vitest.dev/)
- [Playwright Documentation](https://playwright.dev/)
- [Testing Library](https://testing-library.com/)
- [React Native Testing Library](https://callstack.github.io/react-native-testing-library/)
- [NestJS Testing](https://docs.nestjs.com/fundamentals/testing)
## Success Criteria
- ✅ All documentation created
- ✅ Shared configurations available
- ✅ Example tests for all app types
- ✅ CI/CD workflow configured
- ⏳ 80% coverage for new code (ongoing)
- ⏳ 100% coverage for critical paths (ongoing)
- ⏳ All PRs require passing tests (to be enforced)
- ⏳ Coverage reports on all PRs (to be configured)
## Conclusion
This testing strategy provides a complete foundation for achieving 80% test coverage across the Manacore monorepo. All documentation, configurations, examples, and CI/CD integration are ready for implementation. The next step is to begin writing tests following the patterns and guidelines provided.
**Estimated Impact**:
- **Quality**: 80%+ reduction in bugs
- **Confidence**: 100% confidence in deployments
- **Velocity**: Faster feature development with safety net
- **Maintenance**: Easier refactoring with test coverage
---
**Ready to Start Testing?** → Read [TESTING_IMPLEMENTATION_GUIDE.md](./TESTING_IMPLEMENTATION_GUIDE.md)