From 67a181bb0498a526813154c89c12917d1426106e Mon Sep 17 00:00:00 2001 From: Till JS Date: Mon, 23 Mar 2026 10:43:11 +0100 Subject: [PATCH] chore: major cleanup of legacy docs, reports, and unused configs Deleted 50 files (~26,000 lines): Root-level legacy reports: - AUTH_*.md (5 files) - auth architecture reports, now in CLAUDE.md - TESTING_STRATEGY_*.md, QA_*, TEST_CASES_*.md - old testing plans - BACKEND_DESIGN_PATTERN_AUDIT.md, COMPATIBILITY_MATRIX_AND_REMEDIATION.md - HISTORICAL-ANALYSIS.md, MERGE-FIX-SUMMARY.md, RELEASE-PLAN.md - MANACORE-TODOS.md, APP-IDEAS.md, COMMANDS.md docs/ cleanup: - 6 testing docs (duplicates/superseded by .claude/guidelines/testing.md) - 3 env audit files (canonical: ENVIRONMENT_VARIABLES.md) - 3 Mac Mini setup docs (canonical: MAC_MINI_SERVER.md) - 5 daily reports (historical, no ongoing value) - SELF-HOSTING-GUIDE.md (Coolify/Hetzner based, obsolete) - CHANGELOG, CONSISTENCY_REPORT, CONSOLIDATION_OPPORTUNITIES, pr-reviews/ .claude/ cleanup: - audit/ directory (Dec 2025 audit, outdated) - Speculative plans (MacBook Pro server, Windows GPU server) Other: - docker-compose.yml (Traefik-based, replaced by docker-compose.macmini.yml) - TROUBLESHOOTING.md trimmed (removed 730-line staging deployment section) Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/audit/ACTION_PLAN_WEEK_1.md | 631 ------ .claude/audit/AUDIT_SUMMARY.md | 145 -- .claude/audit/FIXES_CHECKLIST.md | 317 --- .claude/audit/HIVE_MIND_EXECUTIVE_SUMMARY.md | 458 ----- .claude/audit/README.md | 155 -- .../audit/documentation-audit-2025-12-07.md | 583 ------ .claude/plans/macbook-pro-server-setup.md | 487 ----- .claude/plans/windows-gpu-server-setup.md | 500 ----- APP-IDEAS.md | 119 -- AUTH_ANALYSIS_SUMMARY.md | 443 ----- AUTH_ARCHITECTURE_REPORT.md | 969 ---------- AUTH_DOCUMENTATION_INDEX.md | 460 ----- AUTH_QUICK_REFERENCE.md | 335 ---- AUTH_VALIDATION_CHECKLIST.md | 434 ----- BACKEND_DESIGN_PATTERN_AUDIT.md | 1066 ---------- COMMANDS.md | 492 ----- COMPATIBILITY_MATRIX_AND_REMEDIATION.md | 1144 ----------- HISTORICAL-ANALYSIS.md | 373 ---- JWT_VALIDATION_REPORT.md | 526 ----- MANACORE-TODOS.md | 423 ---- MERGE-FIX-SUMMARY.md | 357 ---- QA_TESTING_CHECKLIST.md | 477 ----- RELEASE-PLAN.md | 491 ----- TESTING_STRATEGY_AUTH_CREDITS.md | 1710 ----------------- TESTING_STRATEGY_EXECUTIVE_SUMMARY.md | 513 ----- TEST_CASES_SAMPLES.md | 1093 ----------- TROUBLESHOOTING.md | 734 ------- docker-compose.yml | 190 -- docs/CHANGELOG_2025-11-24.md | 356 ---- docs/CONSISTENCY_REPORT.md | 316 --- docs/CONSOLIDATION_OPPORTUNITIES.md | 583 ------ docs/DAILY_REPORT_2026-01-23.md | 289 --- docs/DAILY_REPORT_2026-01-25.md | 299 --- docs/DAILY_REPORT_2026-01-30.md | 397 ---- docs/DAILY_REPORT_2026-02-01.md | 574 ------ docs/DAILY_REPORT_2026-02-02.md | 1081 ----------- docs/ENV_AUDIT_SUMMARY.md | 184 -- docs/ENV_BACKEND_MATRIX.md | 236 --- docs/ENV_CONFIGURATION_AUDIT.md | 423 ---- docs/MAC_MINI_DEPLOYMENT.md | 234 --- docs/MAC_MINI_RUNNER_SETUP.md | 165 -- docs/MAC_MINI_SETUP_CHECKLIST.md | 180 -- docs/SELF-HOSTING-GUIDE.md | 709 ------- docs/TESTING.md | 1644 ---------------- docs/TESTING_GUIDE.md | 641 ------ docs/TESTING_IMPLEMENTATION_GUIDE.md | 646 ------- docs/TESTING_QUICK_REFERENCE.md | 245 --- docs/TESTING_SUMMARY.md | 477 ----- docs/daily-reports/2025-12-10.md | 347 ---- docs/pr-reviews/PR-014-major-update.md | 272 --- 50 files changed, 25923 deletions(-) delete mode 100644 .claude/audit/ACTION_PLAN_WEEK_1.md delete mode 100644 .claude/audit/AUDIT_SUMMARY.md delete mode 100644 .claude/audit/FIXES_CHECKLIST.md delete mode 100644 .claude/audit/HIVE_MIND_EXECUTIVE_SUMMARY.md delete mode 100644 .claude/audit/README.md delete mode 100644 .claude/audit/documentation-audit-2025-12-07.md delete mode 100644 .claude/plans/macbook-pro-server-setup.md delete mode 100644 .claude/plans/windows-gpu-server-setup.md delete mode 100644 APP-IDEAS.md delete mode 100644 AUTH_ANALYSIS_SUMMARY.md delete mode 100644 AUTH_ARCHITECTURE_REPORT.md delete mode 100644 AUTH_DOCUMENTATION_INDEX.md delete mode 100644 AUTH_QUICK_REFERENCE.md delete mode 100644 AUTH_VALIDATION_CHECKLIST.md delete mode 100644 BACKEND_DESIGN_PATTERN_AUDIT.md delete mode 100644 COMMANDS.md delete mode 100644 COMPATIBILITY_MATRIX_AND_REMEDIATION.md delete mode 100644 HISTORICAL-ANALYSIS.md delete mode 100644 JWT_VALIDATION_REPORT.md delete mode 100644 MANACORE-TODOS.md delete mode 100644 MERGE-FIX-SUMMARY.md delete mode 100644 QA_TESTING_CHECKLIST.md delete mode 100644 RELEASE-PLAN.md delete mode 100644 TESTING_STRATEGY_AUTH_CREDITS.md delete mode 100644 TESTING_STRATEGY_EXECUTIVE_SUMMARY.md delete mode 100644 TEST_CASES_SAMPLES.md delete mode 100644 docker-compose.yml delete mode 100644 docs/CHANGELOG_2025-11-24.md delete mode 100644 docs/CONSISTENCY_REPORT.md delete mode 100644 docs/CONSOLIDATION_OPPORTUNITIES.md delete mode 100644 docs/DAILY_REPORT_2026-01-23.md delete mode 100644 docs/DAILY_REPORT_2026-01-25.md delete mode 100644 docs/DAILY_REPORT_2026-01-30.md delete mode 100644 docs/DAILY_REPORT_2026-02-01.md delete mode 100644 docs/DAILY_REPORT_2026-02-02.md delete mode 100644 docs/ENV_AUDIT_SUMMARY.md delete mode 100644 docs/ENV_BACKEND_MATRIX.md delete mode 100644 docs/ENV_CONFIGURATION_AUDIT.md delete mode 100644 docs/MAC_MINI_DEPLOYMENT.md delete mode 100644 docs/MAC_MINI_RUNNER_SETUP.md delete mode 100644 docs/MAC_MINI_SETUP_CHECKLIST.md delete mode 100644 docs/SELF-HOSTING-GUIDE.md delete mode 100644 docs/TESTING.md delete mode 100644 docs/TESTING_GUIDE.md delete mode 100644 docs/TESTING_IMPLEMENTATION_GUIDE.md delete mode 100644 docs/TESTING_QUICK_REFERENCE.md delete mode 100644 docs/TESTING_SUMMARY.md delete mode 100644 docs/daily-reports/2025-12-10.md delete mode 100644 docs/pr-reviews/PR-014-major-update.md diff --git a/.claude/audit/ACTION_PLAN_WEEK_1.md b/.claude/audit/ACTION_PLAN_WEEK_1.md deleted file mode 100644 index 034c20b5e..000000000 --- a/.claude/audit/ACTION_PLAN_WEEK_1.md +++ /dev/null @@ -1,631 +0,0 @@ -# ⚑ WEEK 1 ACTION PLAN - CRITICAL FIXES -## ManaCore Monorepo Emergency Response - -**Timeline:** Days 1-7 -**Total Effort:** 17 hours -**Priority:** CRITICAL -**Owner:** DevOps + Backend Team - ---- - -## 🎯 OBJECTIVE - -Resolve the 5 most critical issues that pose immediate security, operational, or productivity risks to the monorepo. - -**Success Criteria:** -- βœ… No API keys or secrets committed to git -- βœ… PR validation workflow active and blocking broken code -- βœ… Local development setup works for all projects -- βœ… Pre-commit hooks don't take 10+ minutes -- βœ… Database initialization complete and tested - ---- - -## πŸ“‹ TASK BREAKDOWN - -### TASK 1: REVOKE EXPOSED API KEYS (CRITICAL SECURITY) - -**Priority:** πŸ”΄ P0 (DO FIRST) -**Effort:** 2 hours -**Owner:** DevOps Lead -**Risk:** Active API keys exposed in `.env.development` commit history - -#### Steps - -1. **Immediately revoke these keys** (30 minutes): - ```bash - # Google Gemini API - Key: AIzaSyApsYQXxN6PuXpF8-7j6MonCACwS0ZxNRc - Action: Go to https://console.cloud.google.com/apis/credentials - Revoke and generate new key - - # Azure OpenAI API - Key: 3082103c9b0d4270a795686ccaa89921 - Action: Go to Azure Portal β†’ Cognitive Services β†’ Regenerate key - - # WorldDream OpenAI - Key: sk-proj-qdYUVUqNv... - Action: Go to OpenAI Platform β†’ API Keys β†’ Revoke - - # WorldDream Gemini - Key: AIzaSyB74aUj1KmJlcjNyT5uUiyDODQ6iYoAOjQ - Action: Revoke via Google Cloud Console - - # Replicate API - Key: r8_QlvkstNhIc6NBX1ktpQ6ibvzOE2d2UQ1Emamd - Action: Go to https://replicate.com/account β†’ Revoke - ``` - -2. **Audit API usage logs** (30 minutes): - - Check for unauthorized usage in the last 30 days - - Document any suspicious activity - - Calculate potential exposure cost - -3. **Generate new keys** (30 minutes): - - Create new keys for all services - - Store in password manager (1Password/LastPass) - - Document key rotation process - -4. **Update local environments** (30 minutes): - - Create `.env.development.local` with new keys - - Share securely with team (encrypted) - - Test all services with new keys - -#### Verification - -```bash -# Ensure no secrets in tracked files -git grep "AIza" -- '*.env*' '!*.local' # Should return nothing -git grep "sk-proj" -- '*.env*' '!*.local' # Should return nothing - -# Verify local setup works -pnpm docker:up -pnpm setup:env -pnpm run chat:dev # Test with new keys -``` - -#### Files Changed -- `.env.development` - Remove all real keys, add placeholders -- `.env.development.local` - Create with new keys (gitignored) -- `.env.development.example` - Create template for onboarding - ---- - -### TASK 2: IMPLEMENT SECRETS MANAGEMENT - -**Priority:** πŸ”΄ P0 -**Effort:** 8 hours -**Owner:** DevOps Lead -**Goal:** Never commit secrets to git again - -#### Steps - -1. **Update `.gitignore`** (15 minutes): - ```bash - # Add to root .gitignore - .env.development.local - .env.production.local - .env.staging.local - .env*.local - ``` - -2. **Update `scripts/generate-env.mjs`** (2 hours): - ```javascript - // Read from .local files if they exist, otherwise use .env.development - import fs from 'fs'; - import path from 'path'; - - function loadEnvFile(filename) { - const localPath = filename.replace('.development', '.development.local'); - if (fs.existsSync(localPath)) { - console.log(`Using ${localPath} (secrets file)`); - return dotenv.parse(fs.readFileSync(localPath)); - } - console.log(`Using ${filename} (template file)`); - return dotenv.parse(fs.readFileSync(filename)); - } - - const sourceEnv = { - ...loadEnvFile('.env.development'), - ...loadEnvFile('.env.development.local'), // Override with secrets - }; - ``` - -3. **Add environment variable validation** (3 hours): - ```bash - pnpm add -D zod - ``` - - ```javascript - // scripts/validate-env.mjs - import { z } from 'zod'; - - const envSchema = z.object({ - MANA_CORE_AUTH_URL: z.string().url(), - POSTGRES_PASSWORD: z.string().min(8), - GOOGLE_GENAI_API_KEY: z.string().startsWith('AIza').optional(), - AZURE_OPENAI_API_KEY: z.string().min(20).optional(), - // ... all required vars - }); - - export function validateEnv(env) { - const result = envSchema.safeParse(env); - if (!result.success) { - console.error('❌ Invalid environment variables:'); - console.error(result.error.format()); - process.exit(1); - } - console.log('βœ… Environment variables validated'); - } - ``` - -4. **Create setup script** (1 hour): - ```bash - # scripts/setup-secrets.sh - #!/bin/bash - - echo "πŸ” Setting up secrets for manacore-monorepo" - - if [ ! -f .env.development.local ]; then - echo "Creating .env.development.local from example..." - cp .env.development.example .env.development.local - echo "⚠️ Please fill in your API keys in .env.development.local" - exit 1 - fi - - echo "βœ… Secrets file exists" - node scripts/generate-env.mjs - ``` - -5. **Update documentation** (1 hour): - ```markdown - # docs/SECRETS_MANAGEMENT.md - - ## Never Commit Secrets - - 1. All API keys go in `.env.development.local` (gitignored) - 2. Template values in `.env.development.example` - 3. Production secrets in GitHub Secrets or Vault - - ## First-Time Setup - - bash - cp .env.development.example .env.development.local - # Edit .env.development.local with your keys - pnpm setup:env - - ``` - -6. **Test setup** (1 hour): - ```bash - # Fresh clone simulation - rm -rf node_modules .env* - cp .env.development.example .env.development.local - # Add test keys - pnpm install - pnpm setup:env - pnpm docker:up - pnpm run chat:dev - ``` - -#### Files Changed -- `.gitignore` - Add `.env*.local` -- `scripts/generate-env.mjs` - Support `.local` files -- `scripts/validate-env.mjs` - NEW (validation) -- `scripts/setup-secrets.sh` - NEW (onboarding) -- `.env.development.example` - NEW (template) -- `.env.development.local` - NEW (gitignored secrets) -- `docs/SECRETS_MANAGEMENT.md` - NEW (documentation) - ---- - -### TASK 3: FIX DATABASE INITIALIZATION - -**Priority:** πŸ”΄ P0 -**Effort:** 2 hours -**Owner:** Backend Lead -**Goal:** Complete local dev setup with one command - -#### Steps - -1. **Audit required databases** (30 minutes): - ```bash - # Extract all DATABASE_URL from .env.development - grep "DATABASE_URL" .env.development | grep -o "localhost:5432/[^\"]*" | cut -d'/' -f2 | sort -u - ``` - -2. **Update initialization script** (1 hour): - ```sql - -- docker/init-db/01-create-databases.sql - - -- Existing (keep these) - CREATE DATABASE chat; - CREATE DATABASE voxel_lava; - CREATE DATABASE storage; - CREATE DATABASE todo; - - -- Add missing databases - CREATE DATABASE manacore; - CREATE DATABASE zitare; - CREATE DATABASE presi; - CREATE DATABASE contacts; - CREATE DATABASE calendar; - CREATE DATABASE manadeck; - CREATE DATABASE finance; - CREATE DATABASE moodlit; - CREATE DATABASE moods; - CREATE DATABASE picture; - CREATE DATABASE nutriphi; - CREATE DATABASE quote; - CREATE DATABASE clock; - CREATE DATABASE context; - - -- Grant privileges to all databases - DO $$ - DECLARE - db_name TEXT; - BEGIN - FOR db_name IN - SELECT datname FROM pg_database - WHERE datname NOT IN ('postgres', 'template0', 'template1') - LOOP - EXECUTE format('GRANT ALL PRIVILEGES ON DATABASE %I TO manacore', db_name); - END LOOP; - END $$; - ``` - -3. **Test fresh setup** (30 minutes): - ```bash - # Teardown existing - pnpm docker:down - docker volume rm manacore-monorepo_postgres_data - - # Fresh start - pnpm docker:up - - # Verify all databases exist - docker exec -it manacore-postgres psql -U manacore -c "\l" | grep manacore - - # Should show all 17+ databases - ``` - -#### Files Changed -- `docker/init-db/01-create-databases.sql` - Add all missing databases - -#### Verification Checklist -- [ ] All databases from `.env.development` are created -- [ ] `manacore` user has access to all databases -- [ ] Fresh `pnpm docker:up` creates all databases -- [ ] `pnpm run chat:dev` connects successfully -- [ ] No manual database creation needed - ---- - -### TASK 4: ENABLE CI PR VALIDATION - -**Priority:** πŸ”΄ P0 -**Effort:** 4 hours -**Owner:** DevOps Lead -**Goal:** Block broken code from merging to main - -#### Steps - -1. **Restore PR workflow** (30 minutes): - ```bash - mv .github/workflows/ci-pull-request.yml.bak .github/workflows/ci-pull-request.yml - ``` - -2. **Update workflow** (2 hours): - ```yaml - # .github/workflows/ci-pull-request.yml - name: CI - Pull Request Validation - - on: - pull_request: - branches: [main, dev] - - jobs: - validate: - name: Code Quality Checks - runs-on: ubuntu-latest - timeout-minutes: 20 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 9.15.0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Format check - run: pnpm format:check - - - name: Lint - run: pnpm lint - - - name: Type check - run: pnpm type-check - timeout-minutes: 10 - - # Uncomment when tests exist - # - name: Test - # run: pnpm test - # timeout-minutes: 15 - - # - name: Upload coverage - # uses: codecov/codecov-action@v3 - # with: - # files: ./coverage/lcov.info - - security: - name: Security Scan - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Run npm audit - run: | - pnpm audit --prod --audit-level=high - # Don't fail on audit issues yet (too many) - continue-on-error: true - ``` - -3. **Add branch protection rules** (1 hour): - - Go to GitHub repo β†’ Settings β†’ Branches - - Add rule for `main` and `dev`: - - βœ… Require status checks to pass - - βœ… Require `validate` job to pass - - βœ… Require up-to-date branches - - βœ… Include administrators - -4. **Test workflow** (30 minutes): - ```bash - # Create test PR - git checkout -b test/ci-validation - echo "test" >> README.md - git add README.md - git commit -m "test: CI validation" - git push origin test/ci-validation - - # Create PR on GitHub - # Verify workflow runs - # Verify PR blocked if checks fail - ``` - -#### Files Changed -- `.github/workflows/ci-pull-request.yml` - Restored and updated -- GitHub branch protection rules (via UI) - -#### Verification Checklist -- [ ] PR workflow runs on new PRs -- [ ] Format check fails on bad formatting -- [ ] Lint check fails on linting errors -- [ ] Type check completes in <10 minutes -- [ ] PR cannot be merged if checks fail - ---- - -### TASK 5: FIX PRE-COMMIT HOOK PERFORMANCE - -**Priority:** 🟑 P1 -**Effort:** 1 hour -**Owner:** DevOps Lead -**Goal:** Pre-commit takes <30 seconds (not 10+ minutes) - -#### Steps - -1. **Update pre-commit hook** (30 minutes): - ```bash - # .husky/pre-commit - #!/usr/bin/env sh - . "$(dirname -- "$0")/_/husky.sh" - - # Run lint-staged (only on changed files) - pnpm exec lint-staged - - # REMOVED: pnpm run type-check (too slow, move to CI) - ``` - -2. **Update lint-staged config** (30 minutes): - ```json - // package.json - { - "lint-staged": { - "*.{ts,tsx,js,jsx}": [ - "eslint --fix --max-warnings=0", - "prettier --write" - ], - "*.{json,md,yml,yaml}": [ - "prettier --write" - ], - "*.{svelte}": [ - "eslint --fix --max-warnings=0", - "prettier --plugin prettier-plugin-svelte --write" - ], - "*.{astro}": [ - "prettier --plugin prettier-plugin-astro --write" - ] - } - } - ``` - -#### Files Changed -- `.husky/pre-commit` - Remove global type-check -- `package.json` - Update lint-staged config - -#### Verification -```bash -# Make a small change -echo "// test" >> apps/chat/apps/backend/src/main.ts - -# Stage and commit -git add apps/chat/apps/backend/src/main.ts -time git commit -m "test: pre-commit performance" - -# Should complete in <30 seconds -``` - ---- - -## πŸ“Š PROGRESS TRACKING - -### Daily Standup Template - -**Day 1 (Security Crisis Day):** -- [ ] TASK 1: Revoke exposed API keys (2h) -- [ ] TASK 2: Start secrets management (4h/8h) - -**Day 2 (Security Completion):** -- [ ] TASK 2: Finish secrets management (4h/8h) -- [ ] TASK 3: Fix database initialization (2h) - -**Day 3 (CI/CD Setup):** -- [ ] TASK 4: Enable CI PR validation (4h) -- [ ] TASK 5: Fix pre-commit performance (1h) - -**Day 4 (Testing & Verification):** -- [ ] Test all fixes -- [ ] Update documentation -- [ ] Team demo - -### Verification Commands - -```bash -# Security verification -git log --all --full-history -- .env.development | grep -i "api.*key" # Should be empty in new commits -grep -r "AIza\|sk-proj" .env* --exclude="*.local" --exclude="*.example" # Should be empty - -# Database verification -docker exec -it manacore-postgres psql -U manacore -c "\l" | wc -l # Should show 17+ databases - -# CI verification -gh pr checks # All checks should pass - -# Pre-commit verification -time git commit --allow-empty -m "test" # Should be <30s -``` - ---- - -## 🎯 SUCCESS METRICS - -### Week 1 Goals - -| Metric | Before | Target | Actual | -|--------|--------|--------|--------| -| Secrets in git | βœ… Yes (CRITICAL) | ❌ No | ___ | -| PR validation | ❌ Disabled | βœ… Active | ___ | -| Database setup time | 2+ hours (manual) | 5 minutes (automated) | ___ | -| Pre-commit duration | 10+ minutes | <30 seconds | ___ | -| Local dev setup | Broken for new devs | One-command setup | ___ | - -### Definition of Done - -- [ ] βœ… All API keys revoked and rotated -- [ ] βœ… Secrets in `.env.development.local` (gitignored) -- [ ] βœ… Environment validation script works -- [ ] βœ… Fresh `git clone` + `pnpm install` sets up everything -- [ ] βœ… All 17+ databases created on `pnpm docker:up` -- [ ] βœ… PR workflow active and blocking broken code -- [ ] βœ… Pre-commit hook completes in <30s -- [ ] βœ… Documentation updated -- [ ] βœ… Team trained on new workflow - ---- - -## πŸ“š DOCUMENTATION UPDATES - -### Files to Update - -1. **ROOT README.md:** - ```markdown - ## First-Time Setup - - 1. Clone the repository - 2. Copy `.env.development.example` to `.env.development.local` - 3. Fill in your API keys in `.env.development.local` - 4. Run `pnpm install` - 5. Run `pnpm docker:up` - 6. Start developing: `pnpm run chat:dev` - - **IMPORTANT:** Never commit `.env.development.local` - it contains secrets! - ``` - -2. **docs/ENVIRONMENT_VARIABLES.md:** - - Add section on secrets management - - Explain `.local` file pattern - - Document validation process - -3. **CLAUDE.md:** - - Update environment variables section - - Add security best practices - - Document CI/CD workflow - ---- - -## 🚨 ROLLBACK PLAN - -If anything goes wrong: - -1. **API Keys Broken:** - ```bash - # Restore from password manager - # Update .env.development.local - pnpm setup:env - ``` - -2. **Database Init Broken:** - ```bash - # Restore old SQL file from git - git checkout HEAD~1 docker/init-db/01-create-databases.sql - pnpm docker:down - pnpm docker:up - ``` - -3. **CI Workflow Broken:** - ```bash - # Disable workflow temporarily - mv .github/workflows/ci-pull-request.yml .github/workflows/ci-pull-request.yml.bak - git add .github/workflows/ci-pull-request.yml.bak - git commit -m "fix: disable CI temporarily" - ``` - ---- - -## πŸŽ“ POST-WEEK 1 RETROSPECTIVE - -### Questions to Answer - -1. What went well? -2. What took longer than expected? -3. What did we learn about our system? -4. What should we prioritize next? -5. How can we prevent similar issues? - -### Next Steps Planning - -- Review Week 2-4 action plan (testing foundation) -- Allocate resources for testing sprint -- Set up coverage tracking -- Schedule daily standups for testing work - ---- - -**END OF WEEK 1 ACTION PLAN** - -*Priority: CRITICAL* -*Total Effort: 17 hours* -*Timeline: Days 1-7* -*Success Criteria: All tasks completed and verified* diff --git a/.claude/audit/AUDIT_SUMMARY.md b/.claude/audit/AUDIT_SUMMARY.md deleted file mode 100644 index 05230c1fc..000000000 --- a/.claude/audit/AUDIT_SUMMARY.md +++ /dev/null @@ -1,145 +0,0 @@ -# Documentation Audit Summary -**Date:** 2025-12-07 -**Full Report:** [documentation-audit-2025-12-07.md](./documentation-audit-2025-12-07.md) - -## Quick Stats - -- **Active Projects:** 17 (apps/) + 5 (games/) + 1 (service) -- **Documentation Coverage:** 11/17 active projects have CLAUDE.md -- **Critical Issues:** 3 -- **Overall Score:** 7/10 - -## Top 3 Critical Issues - -### 1. 🚨 Active vs Archived Confusion -**5 projects exist in BOTH `apps/` and `apps-archived/`:** -- maerchenzauber -- memoro -- wisekeep -- reader -- nutriphi - -Root CLAUDE.md lists them as archived, but they're in the active workspace. - -### 2. ❌ Missing Major Project Documentation -**No CLAUDE.md files for:** -- **manadeck** (major project with full stack) -- **picture** (AI image generation) -- **quote** (backend + web + mobile) -- Several other active projects - -### 3. πŸ“ Incomplete Root Documentation -**Root CLAUDE.md only documents 6/17 active projects:** -- Missing: calendar, clock, context, todo, quote, and 6+ others -- Outdated commands (presi:dev, mail:dev for archived projects) - -## Immediate Action Items - -1. βœ… **Resolve duplicates** - Decide on maerchenzauber, memoro, wisekeep, reader, nutriphi status -2. βœ… **Create CLAUDE.md** for manadeck and picture (high priority) -3. βœ… **Update root CLAUDE.md** with complete project list (17 projects) -4. βœ… **Fix commands** - Remove presi:dev, mail:dev; add calendar:dev, clock:dev, todo:dev -5. βœ… **Backend ports table** - Document all 12 backends with port numbers - -## Documentation Quality by Project - -### Excellent (10/10) -- βœ… calendar (German, comprehensive) -- βœ… clock (German, comprehensive) -- βœ… todo (German, comprehensive) - -### Good (8-9/10) -- βœ… chat -- βœ… contacts -- βœ… context -- βœ… zitare - -### Missing -- ❌ manadeck -- ❌ picture -- ❌ quote -- ❌ 8+ other projects - -## Key Findings - -### Projects Not in Root Docs -Missing from root CLAUDE.md but active: -- calendar (port 3014) -- clock (port 3017) -- context (mobile only) -- todo (port 3018) -- quote (full stack) -- maerchenzauber* (duplicate) -- memoro* (duplicate) -- nutriphi* (duplicate) -- reader* (duplicate) -- wisekeep* (duplicate) - -### Landing Pages Mismatch -- **Actual:** 7 landing pages (chat, picture, manacore, manadeck, zitare, calendar, clock) -- **Documented:** 5 (missing calendar, clock) -- **Deploy scripts:** 10 (includes non-existent: presi, mail, moodlit) - -### Shared Packages Gap -- **Actual:** 34 packages -- **Documented:** 10 packages -- **Missing:** 24 packages undocumented - -## Priority Matrix - -| Issue | Priority | Impact | Effort | -|-------|----------|--------|--------| -| Resolve active/archived confusion | πŸ”΄ HIGH | Critical | Medium | -| Create manadeck CLAUDE.md | πŸ”΄ HIGH | High | Low | -| Create picture CLAUDE.md | πŸ”΄ HIGH | High | Low | -| Update root projects table | πŸ”΄ HIGH | High | Low | -| Backend ports reference | 🟑 MEDIUM | Medium | Low | -| Landing pages docs fix | 🟑 MEDIUM | Medium | Low | -| Shared packages docs | 🟑 MEDIUM | Medium | High | -| Games section | 🟒 LOW | Low | Low | - -## Recommendations - -### Week 1 -- Resolve duplicate projects (remove from apps/ OR apps-archived/) -- Create CLAUDE.md for manadeck, picture -- Update root CLAUDE.md with all 17 active projects - -### Week 2-4 -- Document all backend ports -- Fix landing pages section -- Update environment variables docs -- Add games overview - -### Ongoing -- Create CLAUDE.md for all remaining projects -- Automated documentation validation -- Version compatibility matrix - -## Files to Review/Update - -1. `/CLAUDE.md` - Add missing projects, fix commands -2. `/apps/manadeck/CLAUDE.md` - CREATE -3. `/apps/picture/CLAUDE.md` - CREATE -4. `/docs/ENVIRONMENT_VARIABLES.md` - Add missing projects -5. `/package.json` - Clean up commands for archived projects - -## Success Metrics - -**Target Documentation Coverage:** -- βœ… 100% of active projects in root CLAUDE.md -- βœ… 100% of active projects have project CLAUDE.md -- βœ… All backend ports documented -- βœ… Landing pages list is accurate -- βœ… No duplicate projects between apps/ and apps-archived/ - -**Current Status:** -- ⚠️ 35% of active projects in root docs (6/17) -- ⚠️ 65% have project CLAUDE.md (11/17) -- ⚠️ 42% of backends documented (5/12) -- ⚠️ Landing pages 71% accurate (5/7) -- ❌ 5 duplicate projects - ---- - -**Next Steps:** Review full audit report and prioritize fixes based on your team's needs. diff --git a/.claude/audit/FIXES_CHECKLIST.md b/.claude/audit/FIXES_CHECKLIST.md deleted file mode 100644 index e0c539479..000000000 --- a/.claude/audit/FIXES_CHECKLIST.md +++ /dev/null @@ -1,317 +0,0 @@ -# Documentation Fixes Checklist -**Generated:** 2025-12-07 -**Status:** Ready for implementation - -Use this checklist to systematically fix all documentation issues identified in the audit. - ---- - -## Phase 1: Critical Fixes (Week 1) - -### 🚨 Issue 1: Resolve Active/Archived Confusion - -**5 projects in BOTH apps/ and apps-archived/:** - -- [ ] **maerchenzauber** - Decide: Keep in apps/ OR apps-archived/ - - [ ] If keeping in apps/: Delete from apps-archived/ - - [ ] If archiving: Delete from apps/ - - [ ] Update root CLAUDE.md archived projects list - - [ ] Update pnpm-workspace.yaml if needed - -- [ ] **memoro** - Decide: Keep in apps/ OR apps-archived/ - - [ ] If keeping in apps/: Delete from apps-archived/ - - [ ] If archiving: Delete from apps/ - - [ ] Update root CLAUDE.md archived projects list - -- [ ] **wisekeep** - Decide: Keep in apps/ OR apps-archived/ - - [ ] If keeping in apps/: Delete from apps-archived/ - - [ ] If archiving: Delete from apps/ - - [ ] Update root CLAUDE.md archived projects list - -- [ ] **reader** - Decide: Keep in apps/ OR apps-archived/ - - [ ] If keeping in apps/: Delete from apps-archived/ - - [ ] If archiving: Delete from apps/ - - [ ] Update root CLAUDE.md archived projects list - -- [ ] **nutriphi** - Decide: Keep in apps/ OR apps-archived/ - - [ ] If keeping in apps/: Delete from apps-archived/ - - [ ] If archiving: Delete from apps/ - - [ ] Update root CLAUDE.md archived projects list - -### ❌ Issue 2: Create Missing Major Project Docs - -- [ ] **Create `/apps/manadeck/CLAUDE.md`** - - [ ] Document backend (port 3009) - - [ ] Document web app - - [ ] Document mobile app - - [ ] Document landing page - - [ ] Add API endpoints - - [ ] Add database schema - - [ ] Add development commands - - [ ] Add environment variables - -- [ ] **Create `/apps/picture/CLAUDE.md`** - - [ ] Document backend (port 3006) - - [ ] Document web app - - [ ] Document mobile app - - [ ] Document landing page - - [ ] Add AI image generation details - - [ ] Add API endpoints - - [ ] Add development commands - - [ ] Add environment variables - -- [ ] **Create `/apps/quote/CLAUDE.md`** - - [ ] Document backend - - [ ] Document web app - - [ ] Document mobile app - - [ ] Add API endpoints - - [ ] Add development commands - -### πŸ“ Issue 3: Update Root CLAUDE.md - -**File:** `/CLAUDE.md` - -- [ ] **Update Projects Table (lines 31-40)** - ```markdown - | Project | Description | Apps | - | ------------ | ---------------------------- | --------------------------------------------------------- | - | **manacore** | Multi-app ecosystem platform | Expo mobile, SvelteKit web, Astro landing | - | **manadeck** | Card/deck management | NestJS backend, Expo mobile, SvelteKit web, Astro landing| - | **picture** | AI image generation | NestJS backend, Expo mobile, SvelteKit web, Astro landing| - | **chat** | AI chat application | NestJS backend, Expo mobile, SvelteKit web, Astro landing| - | **zitare** | Daily inspiration quotes | NestJS backend, Expo mobile, SvelteKit web, Astro landing| - | **contacts** | Contact management | NestJS backend, SvelteKit web | - | **calendar** | Calendar & scheduling | NestJS backend, SvelteKit web, Astro landing | - | **clock** | World clock & timers | NestJS backend, SvelteKit web, Astro landing | - | **todo** | Task management | NestJS backend, SvelteKit web | - | **context** | AI document management | Expo mobile | - | **quote** | Quote management | NestJS backend, SvelteKit web, Expo mobile | - ``` - -- [ ] **Add missing projects** to table (after resolving duplicates) - -- [ ] **Update Development Commands (lines 61-76)** - ```bash - # Start specific project (runs all apps in project) - pnpm run manacore:dev - pnpm run manadeck:dev - pnpm run picture:dev - pnpm run chat:dev - pnpm run zitare:dev - pnpm run contacts:dev - pnpm run calendar:dev # ADD - pnpm run clock:dev # ADD - pnpm run todo:dev # ADD - pnpm run context:dev # ADD - # REMOVE: pnpm run presi:dev - # REMOVE: pnpm run mail:dev - ``` - -- [ ] **Update Integrated Backends Table (lines 334-342)** - ```markdown - | Backend | Package | Port | - | -------- | ------------------------------- | ---- | - | Chat | `@mana-core/nestjs-integration` | 3002 | - | Picture | `@manacore/shared-nestjs-auth` | 3006 | - | Zitare | `@manacore/shared-nestjs-auth` | 3007 | - | ManaDeck | `@mana-core/nestjs-integration` | 3009 | - | Calendar | `@manacore/shared-nestjs-auth` | 3014 | # ADD - | Contacts | `@manacore/shared-nestjs-auth` | 3015 | # ADD - | Clock | `@manacore/shared-nestjs-auth` | 3017 | # ADD - | Todo | `@manacore/shared-nestjs-auth` | 3018 | # ADD - # REMOVE: | Presi | Custom (same pattern) | 3008 | - ``` - -- [ ] **Update Landing Pages Table (lines 470-476)** - ```markdown - | Project | Package | Cloudflare Project | URL | - |---------|---------|-------------------|-----| - | Chat | `@chat/landing` | `chat-landing` | https://chat-landing.pages.dev | - | Picture | `@picture/landing` | `picture-landing` | https://picture-landing.pages.dev | - | ManaCore | `@manacore/landing` | `manacore-landing` | https://manacore-landing.pages.dev | - | ManaDeck | `@manadeck/landing` | `manadeck-landing` | https://manadeck-landing.pages.dev | - | Zitare | `@zitare/landing` | `zitare-landing` | https://zitare-landing.pages.dev | - | Calendar | `@calendar/landing` | `calendar-landing` | https://calendar-landing.pages.dev | # ADD - | Clock | `@clock/landing` | `clock-landing` | https://clock-landing.pages.dev | # ADD - ``` - -- [ ] **Update Archived Projects List (lines 42-59)** - - [ ] Add/remove based on Phase 1 duplicate resolution - - [ ] Add missing: finance, mail, moodlit - - [ ] Remove duplicates that were moved to active - -- [ ] **Add Games Section** (new section after Projects) - ```markdown - ### Game Projects (`games/`) - - | Project | Description | Status | - | ------------ | ------------------------ | ------ | - | **figgos** | [Description] | Active | - | **mana-games** | [Description] | Active | - | **voxelava** | [Description] | Active | - | **whopixels** | [Description] | Active | - | **worldream** | [Description] | Active | - ``` - ---- - -## Phase 2: High Priority Fixes (Week 2) - -### Update Root CLAUDE.md (continued) - -- [ ] **Expand Shared Packages Section (lines 361-381)** - - [ ] Add missing packages (24 undocumented) - - [ ] OR: Add note: "See `/packages/README.md` for complete list" - - [ ] OR: Create table with all 34 packages - -### Update Environment Variables Documentation - -**File:** `/docs/ENVIRONMENT_VARIABLES.md` - -- [ ] Add calendar environment variables -- [ ] Add clock environment variables -- [ ] Add contacts environment variables -- [ ] Add todo environment variables -- [ ] Add quote environment variables -- [ ] Add context environment variables -- [ ] Update table of contents -- [ ] Verify all variables match actual .env files - -### Clean Up package.json - -**File:** `/package.json` - -- [ ] **Remove invalid deploy scripts (lines 154-157)** - - [ ] Remove: `"deploy:landing:presi"` (landing doesn't exist) - - [ ] Remove: `"deploy:landing:mail"` (landing doesn't exist) - - [ ] Remove: `"deploy:landing:moodlit"` (landing doesn't exist) - -- [ ] **Update deploy:landing:all script (line 158)** - - [ ] Remove presi, mail, moodlit - - [ ] Add calendar, clock if not present - ---- - -## Phase 3: Medium Priority (Weeks 3-4) - -### Create Additional Project Documentation - -- [ ] **Create `/apps/context/README.md`** (expand beyond CLAUDE.md) -- [ ] **Review/update `/apps/manacore/CLAUDE.md`** -- [ ] **Review/update `/services/mana-core-auth/CLAUDE.md`** - -### Create Shared Packages Documentation - -- [ ] **Create `/packages/README.md`** - - [ ] List all 34 packages - - [ ] Describe purpose of each - - [ ] Show import patterns - - [ ] Document inter-package dependencies - -### Update .claude Guidelines - -**Files in `.claude/guidelines/`** - -- [ ] Review authentication.md for accuracy -- [ ] Review database.md - add missing projects -- [ ] Review nestjs-backend.md - add all backends -- [ ] Review expo-mobile.md - add all mobile apps -- [ ] Review sveltekit-web.md - add all web apps - -### Create Missing Documentation - -- [ ] **Create `/docs/BACKENDS.md`** - - [ ] Table of all backends - - [ ] Ports, technologies, database - - [ ] Dependencies - -- [ ] **Create `/docs/LANDING_PAGES.md`** - - [ ] Deployment workflow - - [ ] Cloudflare setup - - [ ] All landing pages - -- [ ] **Update `/docs/PROJECT_OVERVIEW.md`** - - [ ] Ensure all active projects listed - - [ ] Update statistics - ---- - -## Phase 4: Low Priority (Future) - -### Automation & Validation - -- [ ] **Create `/scripts/validate-docs.mjs`** - - [ ] Check all apps/ have CLAUDE.md - - [ ] Verify ports in docs match actual configs - - [ ] Check package.json commands exist for all projects - - [ ] Validate landing pages exist where documented - -- [ ] **Create `/scripts/generate-project-list.mjs`** - - [ ] Auto-generate projects table from filesystem - - [ ] Output markdown table - - [ ] Can be used to update root CLAUDE.md - -### Version Documentation - -- [ ] **Create `/docs/VERSIONS.md`** - - [ ] React Native version per mobile app - - [ ] Expo SDK version per mobile app - - [ ] NestJS version per backend - - [ ] SvelteKit version per web app - - [ ] Node.js compatibility - -### Testing Documentation - -- [ ] Verify all curl examples in CLAUDE.md files work -- [ ] Test all pnpm commands documented -- [ ] Validate all environment variables exist - ---- - -## Verification Checklist - -After completing fixes, verify: - -- [ ] All 17 active projects are in root CLAUDE.md -- [ ] All 17 active projects have CLAUDE.md files -- [ ] No projects exist in both apps/ and apps-archived/ -- [ ] All backend ports are documented -- [ ] All landing pages are accurately documented -- [ ] All pnpm commands work -- [ ] Landing deploy scripts match actual landing pages -- [ ] Archived projects list matches apps-archived/ -- [ ] Games section exists with all 5 games -- [ ] Environment variables docs cover all active projects - ---- - -## Progress Tracking - -**Started:** [DATE] -**Phase 1 Complete:** [DATE] -**Phase 2 Complete:** [DATE] -**Phase 3 Complete:** [DATE] -**Phase 4 Complete:** [DATE] - -**Issues Resolved:** 0/12 - -### Phase Completion - -- [ ] Phase 1: Critical Fixes (3 issues) -- [ ] Phase 2: High Priority (4 issues) -- [ ] Phase 3: Medium Priority (3 issues) -- [ ] Phase 4: Low Priority (2 issues) - ---- - -## Notes - -Add any notes about decisions made or blockers encountered: - -- -- -- - ---- - -**Tip:** Use this checklist with GitHub issues or a project management tool by converting each section to a separate issue/task. diff --git a/.claude/audit/HIVE_MIND_EXECUTIVE_SUMMARY.md b/.claude/audit/HIVE_MIND_EXECUTIVE_SUMMARY.md deleted file mode 100644 index 87127dab6..000000000 --- a/.claude/audit/HIVE_MIND_EXECUTIVE_SUMMARY.md +++ /dev/null @@ -1,458 +0,0 @@ -# 🧠 HIVE MIND COLLECTIVE INTELLIGENCE REPORT -## ManaCore Monorepo - Comprehensive Audit & Improvement Plan - -**Swarm ID:** swarm-1765095736318-q124en9du -**Swarm Name:** hive-1765095736313 -**Audit Date:** 2025-12-07 -**Queen Coordinator:** Strategic Analysis Agent -**Worker Agents:** 4 (Researcher, Coder, Analyst, Tester) - ---- - -## 🎯 EXECUTIVE SUMMARY - -The hive mind collective has completed a comprehensive audit of the manacore-monorepo across four critical dimensions: **Documentation, Code Quality, Architecture, and Testing**. The consensus assessment reveals a project with **strong architectural foundations** but **critical gaps in quality assurance, testing, and operational readiness**. - -### Overall Assessment Matrix - -| Dimension | Score | Status | Priority | -|-----------|-------|--------|----------| -| **Architecture & Design** | 90/100 | βœ… Excellent | Maintain | -| **Documentation** | 70/100 | 🟑 Good | Improve | -| **Code Quality** | 70/100 | 🟑 Good | Improve | -| **Testing Coverage** | 10/100 | πŸ”΄ Critical | **URGENT** | -| **CI/CD & DevOps** | 40/100 | πŸ”΄ Poor | **URGENT** | -| **Security** | 50/100 | πŸ”΄ Poor | **URGENT** | - -**Overall Monorepo Health:** **60/100** (C grade - Functional but High Risk) - ---- - -## 🚨 CRITICAL FINDINGS (Requires Immediate Action) - -### 1. **SECURITY BREACH: API Keys Exposed in Git** πŸ”΄ -**Severity:** CRITICAL -**Impact:** Active API keys committed to `.env.development` -**Risk:** Unauthorized usage, data breach, financial loss - -**Exposed Keys:** -- Google Gemini API Key -- Azure OpenAI API Key -- Replicate API Token -- WorldDream API Keys (OpenAI, Gemini) - -**IMMEDIATE ACTIONS REQUIRED:** -1. βœ… Revoke all exposed keys within 24 hours -2. βœ… Move to `.env.development.local` (gitignored) -3. βœ… Rotate all production secrets -4. βœ… Audit API usage for unauthorized access -5. βœ… Implement secrets management (Doppler/Vault) - -**Files to Fix:** -- `.env.development` - Remove all real keys -- Create `.env.development.example` with placeholders -- Update `scripts/generate-env.mjs` to read from `.local` files - ---- - -### 2. **TESTING CATASTROPHE: <1% Coverage** πŸ”΄ -**Severity:** CRITICAL -**Impact:** No automated quality assurance for 99% of codebase -**Risk:** Production bugs, regression failures, customer impact - -**Key Metrics:** -- **Total Test Files:** 23 (only in mana-core-auth) -- **Backends Tested:** 1/12 (8% coverage) -- **Mobile Apps Tested:** 0/7 (0% coverage) -- **Web Apps Tested:** 0/7 (0% coverage) -- **Shared Packages Tested:** 0/37 (0% coverage) - -**Critical Untested Areas:** -- πŸ”΄ **Authentication integration** - All backends use mana-core-auth but none test it -- πŸ”΄ **Credit consumption** - Billing logic has zero tests (double-charging risk!) -- πŸ”΄ **Storage operations** - S3 uploads/downloads untested (data loss risk) -- πŸ”΄ **API endpoints** - 100+ endpoints have no tests - -**IMMEDIATE ACTIONS REQUIRED:** -1. βœ… Test `@manacore/shared-nestjs-auth` (security critical) -2. βœ… Test `@manacore/shared-storage` (data integrity) -3. βœ… Test credit consumption flows (billing accuracy) -4. βœ… Add tests to chat, picture, zitare backends -5. βœ… Enable CI test validation on PRs - -**Estimated Effort:** 460-660 hours (3-4 months full-time) - ---- - -### 3. **BUILD PERFORMANCE: 10x Slower Than Expected** πŸ”΄ -**Severity:** HIGH -**Impact:** Type-check takes 10+ minutes (should be 1-2 minutes) -**Risk:** Developer productivity loss, CI timeouts - -**Root Cause:** ~~Recursive turbo calls in parent packages~~ - -**UPDATE:** βœ… **FALSE ALARM** - After analysis, parent packages only contain `dev` scripts, which is acceptable per guidelines. The actual cause of slow builds needs further investigation (likely high concurrency limit or other factors). - -**ACTIONS:** -1. βœ… Investigate actual slow build cause (not turbo recursion) -2. βœ… Test with higher concurrency (`"concurrency": "10"`) -3. βœ… Enable Turborepo remote caching -4. βœ… Profile build performance - ---- - -### 4. **DATABASE INITIALIZATION INCOMPLETE** πŸ”΄ -**Severity:** HIGH -**Impact:** Developers cannot set up local environment -**Risk:** Onboarding friction, inconsistent dev environments - -**Current State:** `docker/init-db/01-create-databases.sql` only creates 5 databases -**Missing:** 12+ databases (zitare, presi, contacts, calendar, manadeck, finance, moodlit, etc.) - -**IMMEDIATE ACTIONS REQUIRED:** -1. βœ… Update `01-create-databases.sql` with all databases from `.env.development` -2. βœ… Add grant statements for all databases -3. βœ… Test fresh Docker setup - -**File to Fix:** -- `docker/init-db/01-create-databases.sql` - ---- - -### 5. **NO CI/CD QUALITY GATES** πŸ”΄ -**Severity:** HIGH -**Impact:** Broken code can be merged to main -**Risk:** Production outages, customer impact - -**Current State:** -- ❌ No PR validation workflow (disabled - `.bak` file) -- ❌ No lint checks in CI -- ❌ No type-check in CI -- ❌ No test validation in CI -- βœ… Only Docker builds run (minimal validation) - -**IMMEDIATE ACTIONS REQUIRED:** -1. βœ… Restore `.github/workflows/ci-pull-request.yml` -2. βœ… Add `pnpm lint` to PR checks -3. βœ… Add `pnpm type-check` to PR checks -4. βœ… Add `pnpm test` to PR checks (when tests exist) -5. βœ… Add coverage reporting (Codecov) - ---- - -## πŸ“Š DETAILED FINDINGS BY DIMENSION - -### DOCUMENTATION (70/100 - Good) - -**Strengths:** -- βœ… Excellent root `CLAUDE.md` structure -- βœ… Comprehensive authentication documentation -- βœ… Detailed guidelines in `.claude/guidelines/` -- βœ… Well-documented centralized env var system - -**Issues:** -- 🟑 35% of projects missing from root docs (6/17 documented) -- 🟑 3 major projects lack CLAUDE.md (manadeck, picture, quote) -- 🟑 5 projects in both `apps/` and `apps-archived/` (confusion) -- 🟑 34 shared packages exist, only 10 documented -- 🟑 Backend port numbers incomplete (5/12 documented) - -**Detailed Report:** `.claude/audit/documentation-audit-2025-12-07.md` - ---- - -### CODE QUALITY (70/100 - Good) - -**Strengths:** -- βœ… Full Svelte 5 runes adoption (0 old syntax files!) -- βœ… Result type error handling (48 service methods) -- βœ… Consistent auth integration (80 guard usages) -- βœ… Well-organized shared packages (37 packages) - -**Issues:** -- πŸ”΄ TypeScript `any` usage: 124 occurrences (type safety compromised) -- 🟑 Throwing exceptions in services: 27 violations (should use Result types) -- 🟑 Console statements in production: 13 occurrences -- 🟑 Default exports: 15 files (should use named exports) - -**Code Duplication Opportunities:** -- Error handling pattern (~200 lines could be shared) -- API client boilerplate (~500 lines duplicate) -- Loading/error/empty states (30+ components) - -**Technical Debt Score:** 6.5/10 (Moderate-High) - -**Detailed Report:** See Coder Agent output above - ---- - -### ARCHITECTURE & INFRASTRUCTURE (90/100 - Excellent) - -**Strengths:** -- βœ… Centralized auth with Better Auth (EdDSA, JWKS) -- βœ… S3-compatible storage abstraction (MinIO β†’ Hetzner) -- βœ… Clean monorepo structure (pnpm + turborepo) -- βœ… Automated environment generation -- βœ… Docker-based local development - -**Issues:** -- πŸ”΄ Auth service is single point of failure (no HA) -- 🟑 JWT validation requires network call (should use JWKS locally) -- 🟑 No database backup strategy documented -- 🟑 Inconsistent database connection patterns (3 different approaches) -- 🟑 Only 3/12 backends have Docker images - -**Scalability Concerns:** -- Single PostgreSQL instance for 17+ databases -- No CDN for static assets -- No rate limiting in apps -- No real-time/WebSocket architecture - -**Detailed Report:** See Analyst Agent output above - ---- - -### TESTING (10/100 - Critical Failure) - -**Strengths:** -- βœ… Excellent test patterns in mana-core-auth (80% coverage, mock factories, integration tests) -- βœ… Jest/Vitest infrastructure configured -- βœ… Playwright config exists - -**Issues:** -- πŸ”΄ Backend coverage: 8% (1/12 tested) -- πŸ”΄ Mobile coverage: 0% (0/7 tested) -- πŸ”΄ Web coverage: 0% (0/7 tested) -- πŸ”΄ Shared packages: 0% (0/37 tested) -- πŸ”΄ E2E tests: 0 scenarios - -**Critical Gaps:** -- Authentication integration tests (security risk!) -- Credit consumption tests (billing risk!) -- Storage operation tests (data loss risk!) -- API endpoint tests (stability risk!) - -**Detailed Report:** See Tester Agent output above - ---- - -## 🎯 CONSENSUS RECOMMENDATIONS - -The hive mind has achieved consensus on the following prioritized action plan: - -### WEEK 1: SECURITY & CRITICAL FIXES - -| Priority | Action | Owner | Effort | -|----------|--------|-------|--------| -| 1 | Revoke exposed API keys | DevOps | 2h | -| 2 | Implement secrets management | DevOps | 8h | -| 3 | Fix database initialization script | Backend | 2h | -| 4 | Enable CI PR validation | DevOps | 4h | -| 5 | Remove pre-commit global type-check | DevOps | 1h | - -**Total Effort:** 17 hours -**Success Criteria:** No secrets in git, PR validation active, local dev setup works - ---- - -### WEEK 2-4: TESTING FOUNDATION - -| Priority | Action | Owner | Effort | -|----------|--------|-------|--------| -| 6 | Test shared-nestjs-auth package | Backend | 16h | -| 7 | Test shared-storage package | Backend | 12h | -| 8 | Test shared-errors package | Backend | 8h | -| 9 | Test chat backend (auth + credits + API) | Backend | 40h | -| 10 | Test picture backend | Backend | 32h | -| 11 | Test zitare backend | Backend | 24h | - -**Total Effort:** 132 hours -**Success Criteria:** Critical packages at 80%+ coverage, top 3 backends at 70%+ - ---- - -### MONTH 2: INFRASTRUCTURE & AUTOMATION - -| Priority | Action | Owner | Effort | -|----------|--------|-------|--------| -| 12 | Add Docker images for all backends | DevOps | 40h | -| 13 | Implement JWKS-based JWT validation | Backend | 16h | -| 14 | Set up HA for mana-core-auth | DevOps | 24h | -| 15 | Configure Turborepo remote caching | DevOps | 8h | -| 16 | Add database backup automation | DevOps | 12h | -| 17 | Add deployment monitoring | DevOps | 16h | - -**Total Effort:** 116 hours -**Success Criteria:** All services deployable, HA auth, monitoring active - ---- - -### MONTH 3: COVERAGE EXPANSION - -| Priority | Action | Owner | Effort | -|----------|--------|-------|--------| -| 18 | Test remaining backends | Backend | 80h | -| 19 | Test mobile apps (chat, picture, manadeck) | Mobile | 180h | -| 20 | Test web apps (chat, picture) | Frontend | 80h | -| 21 | Create E2E test suite (10 scenarios) | QA | 60h | -| 22 | Update documentation (all missing) | Tech Writer | 24h | - -**Total Effort:** 424 hours -**Success Criteria:** 70%+ coverage across all active projects - ---- - -## πŸ“ˆ SUCCESS METRICS & TRACKING - -### Coverage Targets - -| Metric | Current | 1 Month | 3 Months | 6 Months | -|--------|---------|---------|----------|----------| -| **Security Score** | 50/100 | 80/100 | 90/100 | 95/100 | -| **Test Coverage** | <1% | 40% | 70% | 80% | -| **CI/CD Automation** | 20% | 70% | 90% | 95% | -| **Documentation Coverage** | 70% | 85% | 95% | 100% | -| **Build Performance** | Poor | Good | Excellent | Excellent | - -### Key Performance Indicators (KPIs) - -- **Mean Time to Deploy (MTTD):** Target <15 minutes -- **Test Execution Time:** Target <5 minutes (unit), <15 minutes (full) -- **CI Success Rate:** Target >99% -- **Code Coverage:** Target 80% for new code -- **Documentation Completeness:** Target 100% of active projects - ---- - -## πŸ—ΊοΈ COMPREHENSIVE IMPROVEMENT ROADMAP - -### Phase 1: Stabilization (Month 1) -**Focus:** Security, testing foundation, CI/CD - -**Deliverables:** -- βœ… No secrets in git -- βœ… Shared packages at 80%+ coverage -- βœ… Top 3 backends at 70%+ coverage -- βœ… PR validation active -- βœ… Database setup automated - -**Exit Criteria:** Can deploy with confidence, critical paths tested - ---- - -### Phase 2: Expansion (Months 2-3) -**Focus:** Full test coverage, infrastructure hardening - -**Deliverables:** -- βœ… All backends tested (70%+) -- βœ… Mobile apps tested (60%+) -- βœ… Web apps tested (60%+) -- βœ… E2E test suite (10 scenarios) -- βœ… HA authentication -- βœ… All services deployable - -**Exit Criteria:** Production-ready infrastructure, comprehensive testing - ---- - -### Phase 3: Optimization (Months 4-6) -**Focus:** Performance, monitoring, scalability - -**Deliverables:** -- βœ… Remote caching enabled -- βœ… CDN for static assets -- βœ… Rate limiting everywhere -- βœ… APM/logging/metrics -- βœ… Disaster recovery tested -- βœ… 80%+ coverage maintained - -**Exit Criteria:** Scalable, observable, resilient system - ---- - -## πŸ“ AUDIT DELIVERABLES - -All detailed reports and checklists are available in `.claude/audit/`: - -1. **README.md** - Navigation guide -2. **AUDIT_SUMMARY.md** - Quick reference (from Researcher) -3. **documentation-audit-2025-12-07.md** - Full documentation findings -4. **FIXES_CHECKLIST.md** - Step-by-step implementation guide -5. **HIVE_MIND_EXECUTIVE_SUMMARY.md** - This document -6. **CODE_QUALITY_REPORT.md** - Detailed code analysis (from Coder) -7. **ARCHITECTURE_REPORT.md** - Infrastructure analysis (from Analyst) -8. **TESTING_REPORT.md** - Test coverage assessment (from Tester) - ---- - -## πŸŽ“ LESSONS LEARNED - -### What's Working Well - -1. **Architectural Vision** - Centralized auth, shared packages, monorepo structure -2. **Developer Experience** - Automated env generation, Docker setup, clear guidelines -3. **Code Patterns** - Svelte 5 runes, Result types, auth integration -4. **Documentation Quality** - Where it exists, it's excellent (mana-core-auth, root CLAUDE.md) - -### What Needs Improvement - -1. **Quality Assurance** - Testing is virtually absent -2. **Security Practices** - Secrets management, vulnerability scanning -3. **Operational Readiness** - Deployment automation, monitoring, backups -4. **Documentation Coverage** - Many projects undocumented - -### Strategic Insights - -The monorepo demonstrates **excellent engineering judgment in architecture** but **insufficient investment in quality assurance**. This pattern is common in early-stage products prioritizing features over robustness. The foundation is solid - the missing piece is **automated validation** to maintain quality at scale. - -**Key Recommendation:** Shift focus from feature development to **testing infrastructure** for the next 1-3 months. The ROI will be massive: faster feature development, fewer production bugs, and confident deployments. - ---- - -## πŸš€ NEXT STEPS - -### Immediate Actions (Today) - -1. βœ… Review this executive summary -2. βœ… Prioritize Week 1 critical fixes -3. βœ… Assign owners to tasks -4. βœ… Set up project tracking (GitHub Projects/Jira) - -### Week 1 Kickoff - -1. βœ… Security sprint: Revoke keys, implement secrets management -2. βœ… Database sprint: Fix initialization, test fresh setup -3. βœ… CI/CD sprint: Enable PR validation, remove slow type-check - -### Month 1 Planning - -1. βœ… Allocate resources for testing foundation (132 hours) -2. βœ… Set up coverage tracking (Codecov) -3. βœ… Weekly progress reviews - -### Quarterly Review - -1. βœ… Assess progress against roadmap -2. βœ… Adjust priorities based on learnings -3. βœ… Celebrate wins (coverage milestones!) - ---- - -## 🀝 HIVE MIND CONSENSUS - -All four specialized agents (Researcher, Coder, Analyst, Tester) have reached consensus on the following assessment: - -**The manacore-monorepo is a well-architected system with critical gaps in quality assurance and operational readiness. With focused effort over the next 3 months on testing, security, and CI/CD, it can become a production-grade platform supporting 18+ applications.** - -**Consensus Vote:** 4/4 agents agree -**Confidence Level:** High (based on comprehensive analysis) -**Recommended Action:** Proceed with Week 1 critical fixes immediately - ---- - -**End of Executive Summary** - -*Generated by Hive Mind Swarm: swarm-1765095736318-q124en9du* -*Queen Coordinator: Strategic Analysis Agent* -*Worker Agents: Researcher, Coder, Analyst, Tester* -*Audit Date: 2025-12-07* diff --git a/.claude/audit/README.md b/.claude/audit/README.md deleted file mode 100644 index dc72baf56..000000000 --- a/.claude/audit/README.md +++ /dev/null @@ -1,155 +0,0 @@ -# 🧠 Hive Mind Collective Intelligence Audit -## ManaCore Monorepo Comprehensive Analysis - -**Audit Date:** 2025-12-07 -**Swarm ID:** swarm-1765095736318-q124en9du -**Status:** βœ… Complete - ---- - -## πŸ“„ Core Documents - -### [HIVE_MIND_EXECUTIVE_SUMMARY.md](./HIVE_MIND_EXECUTIVE_SUMMARY.md) ⭐ START HERE -**Overall assessment** - High-level overview from all four agents -- Overall health score: 60/100 (C grade) -- Top 5 critical findings -- Consensus recommendations -- 3-month roadmap - -### [ACTION_PLAN_WEEK_1.md](./ACTION_PLAN_WEEK_1.md) 🚨 URGENT -**Immediate actions** - What to do RIGHT NOW -- 5 critical tasks (17 hours total) -- Security fixes (API keys exposed!) -- Database initialization -- CI/CD activation -- Pre-commit optimization - -### [AUDIT_SUMMARY.md](./AUDIT_SUMMARY.md) -**Documentation quick reference** - From Researcher Agent -- Key statistics -- Top 3 critical issues -- Quick action items -- Priority matrix - -### [documentation-audit-2025-12-07.md](./documentation-audit-2025-12-07.md) -**Full documentation audit** - Complete analysis from Researcher Agent -- Executive summary -- 12 documented findings with examples -- File references and line numbers -- Appendices with complete data -- Recommendations by priority - -### [FIXES_CHECKLIST.md](./FIXES_CHECKLIST.md) -**Implementation guide** - Step-by-step fixes for documentation -- Phased approach (4 phases) -- Checkbox format for progress tracking -- Specific file paths and line numbers -- Verification checklist - -## 🎯 Quick Start - -1. **Read the summary:** [AUDIT_SUMMARY.md](./AUDIT_SUMMARY.md) (5 minutes) -2. **Review critical issues:** Top 3 in summary -3. **Start fixing:** Use [FIXES_CHECKLIST.md](./FIXES_CHECKLIST.md) -4. **Deep dive:** Reference [full report](./documentation-audit-2025-12-07.md) as needed - -## πŸ“Š Key Findings Summary - -| Metric | Status | -|--------|--------| -| **Overall Documentation Quality** | 7/10 | -| **Projects with Docs** | 11/17 (65%) | -| **Critical Issues** | 3 | -| **High Priority Issues** | 4 | -| **Medium Priority Issues** | 3 | -| **Low Priority Issues** | 2 | - -## 🚨 Top 3 Critical Issues - -1. **Active vs Archived Confusion** - 5 projects in both `apps/` and `apps-archived/` -2. **Missing Major Documentation** - manadeck, picture have no CLAUDE.md -3. **Incomplete Root Docs** - Only 6/17 active projects documented - -## βœ… What to Fix First - -**Week 1 Priority:** -1. Resolve duplicate projects (apps/ vs apps-archived/) -2. Create CLAUDE.md for manadeck and picture -3. Update root CLAUDE.md with all 17 active projects -4. Clean up invalid commands in package.json - -## πŸ“ˆ Success Metrics - -**Target:** -- βœ… 100% active projects in root docs -- βœ… 100% active projects have CLAUDE.md -- βœ… All backend ports documented -- βœ… Zero duplicate projects - -**Current:** -- ⚠️ 35% in root docs (6/17) -- ⚠️ 65% have CLAUDE.md (11/17) -- ⚠️ 42% backends documented (5/12) -- ❌ 5 duplicate projects - -## πŸ” Audit Methodology - -This audit was conducted by: -1. Scanning all CLAUDE.md files across the monorepo -2. Comparing documented structure vs actual filesystem -3. Verifying package.json commands -4. Checking consistency across documentation -5. Identifying gaps and inconsistencies -6. Prioritizing findings by impact - -## πŸ“ Contributing to Fixes - -When fixing documentation issues: - -1. βœ… **Follow the checklist** - Use FIXES_CHECKLIST.md -2. βœ… **Update this README** - Mark issues as resolved -3. βœ… **Cross-reference** - Note which fixes address which findings -4. βœ… **Validate** - Test commands and verify accuracy -5. βœ… **Commit properly** - Reference audit findings in commits - -Example commit: -``` -docs: create manadeck CLAUDE.md - -Addresses audit finding #2 (Missing Major Documentation) -See: .claude/audit/FIXES_CHECKLIST.md Phase 1 -``` - -## πŸ“… Timeline - -- **Audit Completed:** 2025-12-07 -- **Phase 1 Target:** Week 1 (Critical fixes) -- **Phase 2 Target:** Week 2 (High priority) -- **Phase 3 Target:** Weeks 3-4 (Medium priority) -- **Phase 4 Target:** Future (Low priority) - -## πŸ”— Related Documentation - -- [Root CLAUDE.md](../../CLAUDE.md) - Main project documentation -- [Guidelines Directory](../) - Code and architecture guidelines -- [Project Overview](../../docs/PROJECT_OVERVIEW.md) - High-level overview -- [Environment Variables](../../docs/ENVIRONMENT_VARIABLES.md) - Env setup - -## πŸ’‘ Tips - -- **For Quick Fixes:** Use AUDIT_SUMMARY.md for the immediate action items -- **For Deep Work:** Read the full report to understand context -- **For Tracking:** Check off items in FIXES_CHECKLIST.md as you complete them -- **For Context:** Reference the full report for examples and rationale - -## πŸ“§ Questions? - -If you have questions about: -- **Why something is an issue:** See the full report -- **How to fix it:** See FIXES_CHECKLIST.md -- **What to prioritize:** See AUDIT_SUMMARY.md priority matrix - ---- - -**Last Updated:** 2025-12-07 -**Next Review:** After Phase 1 completion diff --git a/.claude/audit/documentation-audit-2025-12-07.md b/.claude/audit/documentation-audit-2025-12-07.md deleted file mode 100644 index c888e07b3..000000000 --- a/.claude/audit/documentation-audit-2025-12-07.md +++ /dev/null @@ -1,583 +0,0 @@ -# Documentation Audit Report -**Date:** 2025-12-07 -**Auditor:** Claude Code (Swarm Research Agent) -**Scope:** Complete documentation review of manacore-monorepo - ---- - -## Executive Summary - -This audit reviewed all CLAUDE.md files, guideline documents, and cross-referenced them with actual codebase structure. The monorepo has **17 active projects** in `apps/`, **5 game projects** in `games/`, **16 archived projects** in `apps-archived/`, and **1 service** (`mana-core-auth`). - -**Overall Documentation Quality:** 7/10 -- βœ… Root CLAUDE.md is comprehensive and well-structured -- βœ… Most active projects have detailed CLAUDE.md files -- ⚠️ Several projects missing from root documentation -- ⚠️ Some inconsistencies between docs and actual structure -- ❌ Several projects completely undocumented - ---- - -## Critical Findings (Priority: HIGH) - -### 1. **Missing Project Documentation in Root CLAUDE.md** - -The root `/CLAUDE.md` only documents 6 projects, but there are **17 active projects** in `apps/`: - -**Documented (6):** -- manacore -- manadeck -- picture -- chat -- zitare -- contacts - -**Missing from Documentation (11):** -- **calendar** - Full calendar app (backend, web, landing) - Port 3014 -- **clock** - World clock/timer app (backend, web, landing) - Port 3017 -- **context** - AI document management (mobile only) -- **todo** - Task management app (backend, web, landing) - Port 3018 -- **maerchenzauber** - AI story generation (backend, mobile) - ACTIVE in `apps/` but also listed as archived -- **memoro** - Voice memo app (mobile only) - ACTIVE in `apps/` but also listed as archived -- **nutriphi** - Nutrition tracking (backend, mobile) - ACTIVE in `apps/` but also listed as archived -- **quote** - Quote app (backend, web, mobile) -- **reader** - Reading app (mobile only) - ACTIVE in `apps/` but also listed as archived -- **wisekeep** - AI wisdom extraction (backend, mobile) - ACTIVE in `apps/` but also listed as archived -- **finance** - Finance app (documented in archived but exists in apps-archived) -- **moodlit** - Mood tracking (documented in archived but exists in apps-archived) - -**Impact:** Developers/AI working on these projects have no guidance in the main documentation. - -**Recommendation:** Add a comprehensive project table to root CLAUDE.md that lists ALL active projects with their status, apps (backend/web/mobile/landing), and ports. - ---- - -### 2. **Projects Listed as "Archived" But Actually Active** - -**CRITICAL CONFUSION:** The root CLAUDE.md lists these as archived in `apps-archived/`: -- maerchenzauber -- memoro -- wisekeep -- reader -- nutriphi - -**BUT:** These projects actually exist in `apps/` (active workspace): -- `/apps/maerchenzauber/` βœ… EXISTS (backend + mobile) -- `/apps/memoro/` βœ… EXISTS (mobile only) -- `/apps/wisekeep/` βœ… EXISTS (backend + mobile) -- `/apps/reader/` βœ… EXISTS (mobile only) -- `/apps/nutriphi/` βœ… EXISTS (backend + mobile) - -**Also in apps-archived/:** -- `/apps-archived/maerchenzauber/` βœ… EXISTS -- `/apps-archived/memoro/` βœ… EXISTS -- `/apps-archived/wisekeep/` βœ… EXISTS -- `/apps-archived/reader/` βœ… EXISTS -- `/apps-archived/nutriphi/` βœ… EXISTS - -**Impact:** This creates severe confusion. It appears these projects were copied to `apps/` from `apps-archived/` but the documentation was not updated. Developers don't know if these are active or archived. - -**Recommendation:** -1. Determine which version is canonical (apps/ or apps-archived/) -2. Remove duplicates -3. Update documentation to reflect actual status -4. If both versions should exist, explain why in documentation - ---- - -### 3. **Missing Project-Level CLAUDE.md Files** - -**Projects WITH CLAUDE.md (11):** -- βœ… calendar (detailed, German) -- βœ… chat (comprehensive) -- βœ… clock (detailed, German) -- βœ… contacts (comprehensive) -- βœ… context (concise but complete) -- βœ… manacore (exists, need to verify) -- βœ… todo (detailed, German) -- βœ… zitare (comprehensive) -- βœ… mana-core-auth (service) -- βœ… Several archived projects (maerchenzauber, reader, uload) -- βœ… Game projects (figgos, mana-games, voxelava, worldream) - -**Projects MISSING CLAUDE.md (6+):** -- ❌ **manadeck** - Major project with backend/web/mobile/landing -- ❌ **picture** - AI image generation project -- ❌ **quote** - Quote management app -- ❌ **maerchenzauber** (active version in apps/) -- ❌ **memoro** (active version in apps/) -- ❌ **nutriphi** (active version in apps/) -- ❌ **wisekeep** (active version in apps/) -- ❌ **reader** (active version in apps/) -- ❌ All projects in `apps-archived/` that don't have CLAUDE.md - -**Impact:** No project-specific guidance for important projects like manadeck and picture, which are prominently featured in root docs. - -**Recommendation:** Create CLAUDE.md files for all active projects, especially manadeck and picture. - ---- - -## Medium Priority Findings - -### 4. **Inconsistent Landing Page Documentation** - -**Root CLAUDE.md** lists landing pages for: -- Chat βœ… -- Picture βœ… -- ManaCore βœ… -- ManaDeck βœ… -- Zitare βœ… - -**BUT actual landing pages exist for (7 total):** -- βœ… chat -- βœ… picture -- βœ… manacore -- βœ… manadeck -- βœ… zitare -- βœ… **calendar** (NOT documented in root) -- βœ… **clock** (NOT documented in root) - -**Deploy scripts exist for (10):** -```json -"deploy:landing:chat" -"deploy:landing:picture" -"deploy:landing:manacore" -"deploy:landing:manadeck" -"deploy:landing:zitare" -"deploy:landing:presi" // Landing doesn't exist -"deploy:landing:clock" -"deploy:landing:mail" // Landing doesn't exist -"deploy:landing:moodlit" // Landing doesn't exist -"deploy:landing:all" -``` - -**Impact:** Documentation doesn't reflect which projects actually have landing pages vs which have deploy scripts. - -**Recommendation:** -1. Remove deploy scripts for non-existent landing pages (presi, mail, moodlit) -2. Document calendar and clock landing pages in root CLAUDE.md -3. Update "Landing Pages" section to be accurate - ---- - -### 5. **Backend Port Documentation Inconsistencies** - -**Root CLAUDE.md** documents these backend ports: -- Chat: 3002 βœ… -- Picture: 3006 βœ… -- Zitare: 3007 βœ… -- Presi: 3008 (⚠️ presi backend doesn't exist in apps/) -- ManaDeck: 3009 βœ… - -**Missing from root docs:** -- **Calendar backend:** Port 3014 (from calendar/CLAUDE.md) -- **Contacts backend:** Port 3015 (from contacts/CLAUDE.md) -- **Clock backend:** Port 3017 (from clock/CLAUDE.md) -- **Todo backend:** Port 3018 (from todo/CLAUDE.md) -- **mana-core-auth:** Port 3001 (documented in auth section) - -**Recommendation:** Create a complete backend port reference table in root CLAUDE.md. - ---- - -### 6. **Games Projects Not Documented** - -**Games directory exists with 5 projects:** -- figgos (with CLAUDE.md βœ…) -- mana-games (with CLAUDE.md βœ…) -- voxelava -- whopixels -- worldream (with CLAUDE.md βœ…) - -**Root CLAUDE.md mentions:** -``` -β”œβ”€β”€ games/ # Game projects -β”‚ └── {game-name}/ # Individual games -``` - -But provides NO details about which games exist or their status. - -**Recommendation:** Add a "Game Projects" section listing all games with brief descriptions. - ---- - -### 7. **Shared Packages Documentation Gaps** - -**Root CLAUDE.md lists 10 shared packages:** -- @manacore/shared-nestjs-auth βœ… -- @mana-core/nestjs-integration βœ… -- @manacore/shared-auth βœ… -- @manacore/shared-storage βœ… -- @manacore/shared-supabase βœ… -- @manacore/shared-types βœ… -- @manacore/shared-utils βœ… -- @manacore/shared-ui βœ… -- @manacore/shared-theme βœ… -- @manacore/shared-i18n βœ… - -**Actual packages/ directory has 34 packages:** -``` -eslint-config -mana-core-nestjs-integration -manadeck-database -news-database -nutriphi-database -shared-api-client -shared-auth -shared-auth-stores -shared-auth-ui -shared-branding -shared-config -shared-credit-service -shared-errors -shared-feedback-service -shared-feedback-types -shared-feedback-ui -shared-i18n -shared-icons -shared-landing-ui -shared-nestjs-auth -shared-profile-ui -shared-storage -shared-stores -shared-subscription-types -shared-subscription-ui -shared-supabase -shared-tailwind -shared-theme -shared-theme-ui -shared-types -shared-ui -shared-utils -shared-vite-config -test-config -uload-database -``` - -**Missing from documentation:** -- @manacore/shared-errors -- @manacore/shared-api-client -- @manacore/shared-auth-stores -- @manacore/shared-auth-ui -- @manacore/shared-branding -- @manacore/shared-config -- @manacore/shared-credit-service -- @manacore/shared-feedback-service -- @manacore/shared-feedback-types -- @manacore/shared-feedback-ui -- @manacore/shared-icons -- @manacore/shared-landing-ui -- @manacore/shared-profile-ui -- @manacore/shared-stores -- @manacore/shared-subscription-types -- @manacore/shared-subscription-ui -- @manacore/shared-tailwind -- @manacore/shared-theme-ui -- @manacore/shared-vite-config -- @manacore/test-config -- @manacore/eslint-config -- Project-specific DB packages (manadeck-database, news-database, nutriphi-database, uload-database) - -**Recommendation:** Add a complete packages reference or link to a dedicated packages documentation file. - ---- - -## Low Priority Findings - -### 8. **Development Commands Missing for Some Projects** - -**Root CLAUDE.md** provides dev commands for: -- manacore:dev βœ… -- manadeck:dev βœ… -- picture:dev βœ… -- chat:dev βœ… -- zitare:dev βœ… -- presi:dev ⚠️ (presi doesn't exist in apps/, only in apps-archived/) -- contacts:dev βœ… -- mail:dev ⚠️ (mail exists in apps-archived/, not apps/) - -**Missing commands for active projects:** -- calendar:dev (exists in package.json βœ…) -- clock:dev (exists in package.json βœ…) -- todo:dev (exists in package.json βœ…) -- moodlit:dev (exists in package.json βœ…) -- finance:dev (exists in package.json βœ…) -- context:dev (exists in package.json βœ…) -- worldream:dev (exists in package.json βœ…) -- figgos:dev (exists in package.json βœ…) -- mana-games:dev (exists in package.json βœ…) -- voxel-lava:dev (exists in package.json βœ…) - -**Recommendation:** Update command examples to include all active projects or use a pattern like "pnpm {project}:dev". - ---- - -### 9. **Environment Variables Documentation Inconsistencies** - -**Root CLAUDE.md** references: -- `/docs/ENVIRONMENT_VARIABLES.md` βœ… (file exists and is comprehensive) - -**But ENVIRONMENT_VARIABLES.md documents these projects:** -- Mana Core Auth βœ… -- Chat βœ… -- Maerchenzauber βœ… -- Memoro βœ… -- Manacore βœ… -- Manadeck βœ… - -**Missing from ENVIRONMENT_VARIABLES.md:** -- calendar -- clock -- contacts -- todo -- zitare -- picture -- All games -- All other active projects - -**Recommendation:** Update docs/ENVIRONMENT_VARIABLES.md to include all active projects or clearly state it's only for select projects. - ---- - -### 10. **Archived Projects Documentation Confusion** - -**Root CLAUDE.md** lists 12 archived projects: -- bauntown βœ… (in apps-archived/) -- maerchenzauber ⚠️ (in BOTH apps/ and apps-archived/) -- memoro ⚠️ (in BOTH apps/ and apps-archived/) -- news βœ… (in apps-archived/) -- nutriphi ⚠️ (in BOTH apps/ and apps-archived/) -- reader ⚠️ (in BOTH apps/ and apps-archived/) -- uload βœ… (in apps-archived/) -- wisekeep ⚠️ (in BOTH apps/ and apps-archived/) -- techbase βœ… (in apps-archived/) -- inventory βœ… (in apps-archived/) -- presi βœ… (in apps-archived/) -- storage βœ… (in apps-archived/) - -**Actually in apps-archived/ (16):** -- bauntown βœ… -- finance ❌ (not listed as archived) -- inventory βœ… -- maerchenzauber ⚠️ -- mail ❌ (not listed as archived) -- memoro ⚠️ -- moodlit ❌ (not listed as archived) -- news βœ… -- nutriphi ⚠️ -- presi βœ… -- reader ⚠️ -- storage βœ… -- techbase βœ… -- uload βœ… -- wisekeep ⚠️ - -**Missing from archived list:** -- finance -- mail -- moodlit - -**Recommendation:** Create accurate archived projects list and remove duplicates between apps/ and apps-archived/. - ---- - -### 11. **S3 Buckets Documentation** - -**Root CLAUDE.md** lists these pre-configured buckets: -- picture-storage (Picture) -- chat-storage (Chat) -- manadeck-storage (ManaDeck) -- nutriphi-storage (NutriPhi) -- presi-storage (Presi) -- calendar-storage (Calendar) -- contacts-storage (Contacts) -- storage-storage (Storage) - -**Issues:** -- "storage-storage" is confusing naming -- Missing buckets for: clock, todo, zitare, etc. -- NutriPhi, Presi, Storage are archived - should they have buckets? - -**Recommendation:** Verify which buckets actually exist in MinIO/Hetzner and update docs accordingly. - ---- - -### 12. **Technology Stack Version Ranges Too Wide** - -Root CLAUDE.md states: -- "React Native 0.76-0.81 + Expo SDK 52-54" -- "NestJS 10-11" - -**Issue:** Version ranges should be more specific. Different projects may use different versions, causing confusion. - -**Recommendation:** Either: -1. Specify exact versions used across monorepo -2. Link to a version compatibility matrix -3. State "varies by project, see project CLAUDE.md" - ---- - -## Positive Findings - -### What's Working Well βœ… - -1. **Root CLAUDE.md Structure** - Very well organized with clear sections -2. **Authentication Documentation** - Excellent detail on mana-core-auth integration -3. **Turborepo Configuration** - Critical recursive call warning is prominently documented -4. **Environment Setup** - Centralized .env.development system is well explained -5. **Shared Packages Philosophy** - Good explanation of import patterns -6. **Code Quality Section** - Good forward-looking documentation of planned infrastructure -7. **Project-Level Docs** - Where they exist (calendar, clock, contacts, todo, zitare), they're comprehensive -8. **Svelte 5 Runes** - Clear examples of correct vs incorrect usage -9. **Guidelines Directory** - Excellent `.claude/GUIDELINES.md` with links to detailed guides -10. **Landing Page Deployment** - Clear Cloudflare Pages workflow documented - ---- - -## Recommendations by Priority - -### Immediate Actions (This Week) - -1. **Resolve Active vs Archived Confusion** - - Determine status of: maerchenzauber, memoro, wisekeep, reader, nutriphi - - Remove duplicates - - Update root CLAUDE.md - -2. **Create Missing Project CLAUDE.md Files** - - manadeck - - picture - - All active projects without docs - -3. **Update Root Projects Table** - - Add all 17 active projects - - Include: name, description, apps (backend/web/mobile/landing), port numbers - -4. **Fix Landing Pages Section** - - Remove non-existent landing deploy scripts - - Add calendar, clock to landing pages list - -### Short-term Actions (This Month) - -5. **Backend Ports Reference Table** - - Complete table of all backends with ports in root CLAUDE.md - -6. **Update Shared Packages List** - - Document all 34 packages or create dedicated packages.md - -7. **Environment Variables Audit** - - Update docs/ENVIRONMENT_VARIABLES.md for all active projects - -8. **Games Projects Section** - - Add games overview to root CLAUDE.md - -### Long-term Improvements - -9. **Version Compatibility Matrix** - - Document exact versions per project - -10. **Automated Documentation Checks** - - Script to verify CLAUDE.md exists for all projects - - Script to check root docs match actual structure - -11. **Documentation Generation** - - Auto-generate project list from filesystem - - Auto-generate port assignments from backend configs - ---- - -## Statistics - -| Metric | Count | -|--------|-------| -| **Active Projects (apps/)** | 17 | -| **Game Projects (games/)** | 5 | -| **Archived Projects (apps-archived/)** | 16 | -| **Services (services/)** | 1 (mana-core-auth) | -| **Projects with CLAUDE.md** | ~11 active + several archived | -| **Projects without CLAUDE.md** | ~6 major projects | -| **Backends in active apps/** | 12 | -| **Documented backends in root** | 5 | -| **Landing pages (actual)** | 7 | -| **Landing pages (documented)** | 5 | -| **Deploy scripts for landing** | 10 | -| **Shared packages (actual)** | 34 | -| **Shared packages (documented)** | 10 | - ---- - -## Appendix A: Complete Active Projects List - -| Project | Backend | Web | Mobile | Landing | Port | Status | -|---------|---------|-----|--------|---------|------|--------| -| calendar | βœ… | βœ… | ❌ | βœ… | 3014 | Active, documented | -| chat | βœ… | βœ… | βœ… | βœ… | 3002 | Active, documented | -| clock | βœ… | βœ… | ❌ | βœ… | 3017 | Active, documented | -| contacts | βœ… | βœ… | ❌ | ❌ | 3015 | Active, documented | -| context | ❌ | ❌ | βœ… | ❌ | - | Active, documented | -| maerchenzauber | βœ… | ❌ | βœ… | ❌ | ? | ⚠️ Duplicate in archived | -| manacore | ❌ | βœ… | βœ… | βœ… | - | Active, documented | -| manadeck | βœ… | βœ… | βœ… | βœ… | 3009 | Active, NO docs | -| memoro | ❌ | ❌ | βœ… | ❌ | - | ⚠️ Duplicate in archived | -| nutriphi | βœ… | ❌ | βœ… | ❌ | ? | ⚠️ Duplicate in archived | -| picture | βœ… | βœ… | βœ… | βœ… | 3006 | Active, NO docs | -| quote | βœ… | βœ… | βœ… | ❌ | ? | Active, NO docs | -| reader | ❌ | ❌ | βœ… | ❌ | - | ⚠️ Duplicate in archived | -| todo | βœ… | βœ… | ❌ | ❌ | 3018 | Active, documented | -| wisekeep | βœ… | ❌ | βœ… | ❌ | ? | ⚠️ Duplicate in archived | -| zitare | βœ… | βœ… | βœ… | βœ… | 3007 | Active, documented | - ---- - -## Appendix B: Documentation Coverage Matrix - -| Document | Exists | Accuracy | Completeness | Notes | -|----------|--------|----------|--------------|-------| -| `/CLAUDE.md` | βœ… | 7/10 | 6/10 | Missing many projects | -| `.claude/GUIDELINES.md` | βœ… | 9/10 | 9/10 | Excellent | -| `.claude/guidelines/*.md` | βœ… | 9/10 | 9/10 | Comprehensive | -| `docs/ENVIRONMENT_VARIABLES.md` | βœ… | 8/10 | 5/10 | Incomplete project coverage | -| `apps/calendar/CLAUDE.md` | βœ… | 10/10 | 10/10 | Excellent, German | -| `apps/chat/CLAUDE.md` | βœ… | 9/10 | 9/10 | Comprehensive | -| `apps/clock/CLAUDE.md` | βœ… | 10/10 | 10/10 | Excellent, German | -| `apps/contacts/CLAUDE.md` | βœ… | 9/10 | 9/10 | Comprehensive | -| `apps/context/CLAUDE.md` | βœ… | 8/10 | 8/10 | Concise but complete | -| `apps/manadeck/CLAUDE.md` | ❌ | - | - | **MISSING** | -| `apps/manacore/CLAUDE.md` | βœ… | ? | ? | Not reviewed in detail | -| `apps/picture/CLAUDE.md` | ❌ | - | - | **MISSING** | -| `apps/todo/CLAUDE.md` | βœ… | 10/10 | 10/10 | Excellent, German | -| `apps/zitare/CLAUDE.md` | βœ… | 9/10 | 9/10 | Comprehensive | -| `services/mana-core-auth/CLAUDE.md` | βœ… | ? | ? | Not reviewed in detail | - ---- - -## Appendix C: Recommended Actions Checklist - -### Critical (Do First) -- [ ] Resolve maerchenzauber, memoro, wisekeep, reader, nutriphi duplicate status -- [ ] Create manadeck/CLAUDE.md -- [ ] Create picture/CLAUDE.md -- [ ] Update root CLAUDE.md projects table with all 17 active projects -- [ ] Remove presi:dev and mail:dev from root commands (they're archived) -- [ ] Add calendar, clock, todo to root CLAUDE.md - -### High Priority -- [ ] Create backend ports reference table in root CLAUDE.md -- [ ] Fix landing pages documentation (remove presi, mail, moodlit deploy scripts) -- [ ] Add games section to root CLAUDE.md -- [ ] Update archived projects list to match apps-archived/ - -### Medium Priority -- [ ] Expand shared packages documentation -- [ ] Update docs/ENVIRONMENT_VARIABLES.md for all active projects -- [ ] Add CLAUDE.md for quote, and other undocumented active projects -- [ ] Document S3 buckets accurately - -### Low Priority -- [ ] Create version compatibility matrix -- [ ] Verify all commands in package.json match documentation -- [ ] Add automated documentation validation scripts -- [ ] Consider auto-generating parts of documentation from filesystem - ---- - -**End of Report** diff --git a/.claude/plans/macbook-pro-server-setup.md b/.claude/plans/macbook-pro-server-setup.md deleted file mode 100644 index c3b06b6c5..000000000 --- a/.claude/plans/macbook-pro-server-setup.md +++ /dev/null @@ -1,487 +0,0 @@ -# Implementierungsplan: MacBook Pro M1 Max als zweiter Server - -## Übersicht - -**Ziel:** MacBook Pro M1 Max (64GB RAM) als AI/ML-Server einrichten, der parallel zum Mac Mini lΓ€uft. - -**ZeitschΓ€tzung:** 4-6 Stunden fΓΌr komplette Implementierung - ---- - -## Phase 1: Hardware-Vorbereitung (30 Min) - -### 1.1 MacBook Pro physisch vorbereiten - -- [ ] Daten sichern (falls noch nicht geschehen) -- [ ] Vertikalen Laptop-StΓ€nder besorgen (~25€) -- [ ] USB-C zu Ethernet Adapter besorgen (~30€) -- [ ] Stromleiste mit Überspannungsschutz (~30€) -- [ ] Position neben Mac Mini festlegen - -### 1.2 Netzwerk-Konfiguration planen - -``` -Mac Mini: 192.168.x.10 (bestehend) -MacBook Pro: 192.168.x.11 (neu) -``` - ---- - -## Phase 2: macOS Setup auf MacBook Pro (1-2 Std) - -### 2.1 Optionaler Clean Install - -```bash -# Falls gewΓΌnscht: macOS neu installieren -# Recovery Mode: Cmd+R beim Start -# Festplattendienstprogramm β†’ LΓΆschen β†’ APFS -# macOS neu installieren -``` - -### 2.2 Grundlegende Konfiguration - -```bash -# Systemeinstellungen -# 1. Computername setzen -sudo scutil --set ComputerName "mana-server-ai" -sudo scutil --set HostName "mana-server-ai" -sudo scutil --set LocalHostName "mana-server-ai" - -# 2. SSH aktivieren -# System Settings β†’ General β†’ Sharing β†’ Remote Login β†’ ON - -# 3. Clamshell-Modus ermΓΆglichen -# System Settings β†’ Battery β†’ Power Adapter: -# - "Prevent automatic sleeping when the display is off" β†’ ON -# - "Wake for network access" β†’ ON - -# 4. Auto-Login (optional, fΓΌr Server-Betrieb) -# System Settings β†’ Users & Groups β†’ Automatic Login - -# 5. Autostart nach Stromausfall -sudo systemsetup -setrestartfreeze on -sudo systemsetup -setrestartpowerfailure on -``` - -### 2.3 Statische IP konfigurieren - -```bash -# System Settings β†’ Network β†’ Ethernet β†’ Details β†’ TCP/IP -# Configure IPv4: Manually -# IP Address: 192.168.x.11 -# Subnet Mask: 255.255.255.0 -# Router: 192.168.x.1 -# DNS: 1.1.1.1, 8.8.8.8 -``` - -### 2.4 Development Tools installieren - -```bash -# Xcode Command Line Tools -xcode-select --install - -# Homebrew -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - -# Essentials -brew install git node pnpm python@3.11 cloudflared - -# Docker Desktop -brew install --cask docker -# Nach Installation: Docker Desktop ΓΆffnen und starten -``` - ---- - -## Phase 3: Externe SSD einrichten (30 Min) - -### 3.1 Verzeichnisstruktur erstellen - -```bash -# SSD mounten (falls nicht automatisch) -# Erwarteter Mount-Punkt: /Volumes/ManaData-AI oder Γ€hnlich - -# Verzeichnisse erstellen -sudo mkdir -p /Volumes/ManaData-AI/{ - ollama, - flux2, - stt-models, - tts-models, - postgres-replica, - backups -} - -# Berechtigungen setzen -sudo chown -R $(whoami):staff /Volumes/ManaData-AI -``` - -### 3.2 Symlinks einrichten - -```bash -# Ollama Modelle -ln -sf /Volumes/ManaData-AI/ollama ~/.ollama - -# STT Modelle -ln -sf /Volumes/ManaData-AI/stt-models ~/stt-models - -# TTS Modelle -ln -sf /Volumes/ManaData-AI/tts-models ~/tts-models - -# FLUX.2 Modelle -ln -sf /Volumes/ManaData-AI/flux2 ~/flux2 -``` - ---- - -## Phase 4: Cloudflare Tunnel einrichten (30 Min) - -### 4.1 Neuen Tunnel erstellen - -```bash -# Bei Cloudflare anmelden -cloudflared tunnel login - -# Neuen Tunnel fΓΌr MacBook Pro erstellen -cloudflared tunnel create mana-server-ai - -# Tunnel-ID notieren (z.B. abc12345-xxxx-xxxx-xxxx-xxxxxxxxxxxx) -export TUNNEL_ID="" - -# DNS-Routen erstellen -cloudflared tunnel route dns mana-server-ai mbp.mana.how -cloudflared tunnel route dns mana-server-ai llm.mana.how -cloudflared tunnel route dns mana-server-ai tts-v2.mana.how -cloudflared tunnel route dns mana-server-ai stt-v2.mana.how -cloudflared tunnel route dns mana-server-ai img.mana.how -``` - -### 4.2 Dateien zu erstellen - -**Datei:** `cloudflared-config.macbookpro.yml` - -```yaml -tunnel: -credentials-file: /Users/mana/.cloudflared/.json - -ingress: - # SSH Access - - hostname: mbp.mana.how - service: ssh://localhost:22 - - # LLM Service (mana-llm mit Ollama) - - hostname: llm.mana.how - service: http://localhost:3025 - originRequest: - connectTimeout: 300s - - # TTS Service (Kokoro + F5) - - hostname: tts-v2.mana.how - service: http://localhost:3022 - - # STT Service (Whisper Large) - - hostname: stt-v2.mana.how - service: http://localhost:3021 - - # Image Generation (FLUX.2) - - hostname: img.mana.how - service: http://localhost:3023 - - # Catch-all - - service: http_status:404 -``` - ---- - -## Phase 5: AI/ML Services installieren (2 Std) - -### 5.1 Ollama mit großen Modellen - -```bash -# Ollama installieren -brew install ollama - -# Service starten -brew services start ollama - -# Große Modelle laden (dauert je nach Verbindung) -ollama pull gemma3:27b # 16 GB - Hauptmodell -ollama pull llama3.1:70b # ~40 GB 4-bit quant (optional) -ollama pull codestral:22b # ~14 GB - Code -ollama pull deepseek-coder:33b # ~20 GB - Code (optional) - -# Existierende kleinere Modelle auch laden fΓΌr KompatibilitΓ€t -ollama pull gemma3:4b -ollama pull gemma3:12b -``` - -### 5.2 mana-tts mit F5-TTS - -```bash -# Python Virtual Environment -python3.11 -m venv ~/venvs/mana-tts -source ~/venvs/mana-tts/bin/activate - -# TTS Dependencies (inkl. F5-TTS fΓΌr Voice Cloning) -pip install kokoro-onnx f5-tts torch torchaudio -pip install fastapi uvicorn python-multipart - -# Modelle herunterladen -# (Details in services/mana-tts/setup.py oder setup-tts.sh) -``` - -**LaunchAgent erstellen:** `com.manacore.mana-tts.plist` - -### 5.3 mana-stt mit Whisper Large - -```bash -# Python Virtual Environment -python3.11 -m venv ~/venvs/mana-stt -source ~/venvs/mana-stt/bin/activate - -# Whisper installieren -pip install openai-whisper faster-whisper -pip install fastapi uvicorn python-multipart - -# Large-v3 Modell herunterladen (wird automatisch geladen) -# ~3 GB Download -``` - -**LaunchAgent erstellen:** `com.manacore.mana-stt.plist` - -### 5.4 mana-image-gen mit FLUX.2 - -```bash -# Bestehende Setup-Skript verwenden (angepasst) -./scripts/mac-mini/setup-image-gen.sh - -# Oder manuell: -cd ~/ -git clone https://github.com/city96/flux2.c -cd flux2.c -make MPS=1 # Apple Metal Support - -# Modell herunterladen (~16 GB) -# Details in services/mana-image-gen/ -``` - -**LaunchAgent erstellen:** `com.manacore.image-gen.plist` - ---- - -## Phase 6: Docker Services (Optional, fΓΌr Replicas) (1 Std) - -### 6.1 docker-compose.macbookpro.yml erstellen - -Nur fΓΌr: -- PostgreSQL Replica (Hot Standby) -- Redis Replica -- mana-llm Container -- Backup Worker - -### 6.2 PostgreSQL Streaming Replication - -**Auf Mac Mini (Primary):** - -```bash -# postgresql.conf anpassen -wal_level = replica -max_wal_senders = 3 -wal_keep_size = 64MB - -# pg_hba.conf anpassen -host replication replicator 192.168.x.11/32 md5 -``` - -**Auf MacBook Pro (Replica):** - -```bash -# Base Backup vom Primary -pg_basebackup -h 192.168.x.10 -U replicator -D /Volumes/ManaData-AI/postgres-replica -P - -# standby.signal erstellen -touch /Volumes/ManaData-AI/postgres-replica/standby.signal - -# postgresql.auto.conf -primary_conninfo = 'host=192.168.x.10 port=5432 user=replicator password=xxx' -``` - ---- - -## Phase 7: Autostart & Health Checks (30 Min) - -### 7.1 Scripts zu erstellen - -``` -scripts/macbook-pro/ -β”œβ”€β”€ setup-autostart.sh # LaunchAgents einrichten -β”œβ”€β”€ startup.sh # Boot-Startup -β”œβ”€β”€ health-check.sh # Service-Monitoring -β”œβ”€β”€ status.sh # Übersicht -β”œβ”€β”€ restart.sh # Services neustarten -└── stop.sh # Services stoppen -``` - -### 7.2 LaunchAgents zu erstellen - -``` -~/Library/LaunchAgents/ -β”œβ”€β”€ com.cloudflare.cloudflared.plist # Tunnel -β”œβ”€β”€ com.manacore.mana-tts.plist # TTS Service -β”œβ”€β”€ com.manacore.mana-stt.plist # STT Service -β”œβ”€β”€ com.manacore.image-gen.plist # Image Gen -β”œβ”€β”€ com.manacore.health-check.plist # Health Checks -└── homebrew.mxcl.ollama.plist # Ollama (auto von brew) -``` - ---- - -## Phase 8: Dokumentation & Testing (30 Min) - -### 8.1 Dokumentation aktualisieren - -**Dateien zu erstellen/aktualisieren:** - -- `docs/MACBOOK_PRO_SERVER.md` - Neue Dokumentation -- `docs/MAC_MINI_SERVER.md` - Verweise auf MBP hinzufΓΌgen -- `docs/TWO_SERVER_ARCHITECTURE.md` - Architektur-Übersicht -- `CLAUDE.md` - SSH-Config fΓΌr mbp hinzufΓΌgen - -### 8.2 SSH-Config erweitern - -``` -# ~/.ssh/config -Host mana-server - HostName mac-mini.mana.how - User till - ProxyCommand /opt/homebrew/bin/cloudflared access ssh --hostname %h - -Host mana-server-ai - HostName mbp.mana.how - User till - ProxyCommand /opt/homebrew/bin/cloudflared access ssh --hostname %h -``` - -### 8.3 Testing Checklist - -- [ ] SSH zu MacBook Pro funktioniert: `ssh mana-server-ai` -- [ ] Ollama API erreichbar: `curl http://192.168.x.11:11434/api/version` -- [ ] TTS Service: `curl http://192.168.x.11:3022/health` -- [ ] STT Service: `curl http://192.168.x.11:3021/health` -- [ ] Image Gen: `curl http://192.168.x.11:3023/health` -- [ ] LLM Service: `curl https://llm.mana.how/health` -- [ ] PostgreSQL Replica synchronisiert -- [ ] Health Checks laufen alle 5 Min -- [ ] Notifications bei Fehlern - ---- - -## Dateien die erstellt werden mΓΌssen - -### Neue Dateien - -| Datei | Beschreibung | -|-------|--------------| -| `docker-compose.macbookpro.yml` | Docker Compose fΓΌr MBP (Replicas, mana-llm) | -| `cloudflared-config.macbookpro.yml` | Cloudflare Tunnel Config | -| `.env.macbookpro` | Environment Variables | -| `scripts/macbook-pro/setup-autostart.sh` | LaunchAgent Setup | -| `scripts/macbook-pro/startup.sh` | Boot Startup Script | -| `scripts/macbook-pro/health-check.sh` | Health Monitoring | -| `scripts/macbook-pro/status.sh` | Service Status | -| `scripts/macbook-pro/restart.sh` | Restart Services | -| `scripts/macbook-pro/stop.sh` | Stop Services | -| `scripts/macbook-pro/setup-ollama.sh` | Ollama Setup mit großen Modellen | -| `scripts/macbook-pro/setup-tts.sh` | TTS Setup mit F5 | -| `scripts/macbook-pro/setup-stt.sh` | STT Setup mit Whisper Large | -| `scripts/macbook-pro/backup-worker.sh` | Backup vom Mac Mini | -| `docker/postgres/replica-setup.sh` | PostgreSQL Replica Init | -| `docs/MACBOOK_PRO_SERVER.md` | Server Dokumentation | -| `docs/TWO_SERVER_ARCHITECTURE.md` | Architektur Übersicht | - -### Zu aktualisierende Dateien - -| Datei | Γ„nderung | -|-------|----------| -| `CLAUDE.md` | SSH-Config fΓΌr MBP | -| `docs/MAC_MINI_SERVER.md` | Verweise auf MBP | -| `.env.development` | MBP-spezifische Vars | - ---- - -## Architektur nach Implementierung - -``` - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Cloudflare Tunnel β”‚ - β”‚ *.mana.how β†’ Mac Mini (Primary) β”‚ - β”‚ llm/tts-v2/stt-v2/img.mana.how β”‚ - β”‚ β†’ MacBook Pro (AI/ML) β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ β”‚ - β–Ό β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ MAC MINI M4 (16GB) β”‚ β”‚ MACBOOK PRO M1 MAX (64GB) β”‚ -β”‚ "Docker Orchestrator" β”‚ β”‚ "AI/ML Powerhouse" β”‚ -β”‚ 192.168.x.10 β”‚ β”‚ 192.168.x.11 β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ β”‚ β”‚ β”‚ -β”‚ PostgreSQL PRIMARY ─────────┼────────▢│ PostgreSQL REPLICA β”‚ -β”‚ Redis PRIMARY ──────────────┼────────▢│ Redis REPLICA β”‚ -β”‚ MinIO S3 β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ Ollama (27B, 70B Modelle) β”‚ -β”‚ mana-core-auth (Primary) β”‚ β”‚ mana-llm (large models) β”‚ -β”‚ API Gateway β”‚ β”‚ β”‚ -β”‚ mana-search + SearXNG β”‚ β”‚ mana-tts (Kokoro + F5) β”‚ -β”‚ mana-media β”‚ β”‚ mana-stt (Whisper Large) β”‚ -β”‚ β”‚ β”‚ mana-image-gen (2048x2048) β”‚ -β”‚ Alle NestJS Backends β”‚ β”‚ β”‚ -β”‚ Alle SvelteKit Frontends β”‚ β”‚ Backup-Worker β”‚ -β”‚ Matrix Synapse + Bots β”‚ β”‚ β”‚ -β”‚ Monitoring Stack β”‚ β”‚ β”‚ -β”‚ n8n, Umami β”‚ β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - ssh.mana.how mbp.mana.how -``` - ---- - -## Risiken & Mitigationen - -| Risiko | Mitigation | -|--------|------------| -| MacBook-Akku blΓ€ht sich auf | Monatliche visuelle PrΓΌfung; Al Dente App fΓΌr Ladelimit bei 80% | -| Clamshell Überhitzung | Vertikaler StΓ€nder fΓΌr Konvektion; Monitoring der Temperatur | -| Replication Lag | Monitoring in Grafana; Alerts bei > 1 Minute Lag | -| KomplexitΓ€t | Gute Dokumentation; Health Checks mit Alerts | -| macOS Update bricht Services | Auto-Updates deaktivieren; manuelles Update nach Testing | - ---- - -## Implementierungs-Reihenfolge - -1. **Hardware vorbereiten** (Phase 1) -2. **macOS konfigurieren** (Phase 2) -3. **Externe SSD einrichten** (Phase 3) -4. **Cloudflare Tunnel** (Phase 4) -5. **Ollama + große Modelle** (Phase 5.1) -6. **mana-tts migrieren** (Phase 5.2) -7. **mana-stt migrieren** (Phase 5.3) -8. **mana-image-gen migrieren** (Phase 5.4) -9. **Autostart einrichten** (Phase 7) -10. **Testing** (Phase 8) -11. **PostgreSQL Replication** (Phase 6) - Optional, spΓ€ter -12. **Auth Redundanz** - Optional, spΓ€ter - ---- - -## NΓ€chste Schritte - -Wenn du bereit bist zu implementieren, sag mir welche Phase wir zuerst angehen sollen. Ich kann dann: - -1. Die entsprechenden Scripts erstellen -2. Die Config-Dateien generieren -3. Schritt-fΓΌr-Schritt Anleitung geben - -**Empfehlung:** Starte mit Phase 4 (Cloudflare Tunnel) und Phase 5.1 (Ollama), da diese den grâßten unmittelbaren Nutzen bringen. diff --git a/.claude/plans/windows-gpu-server-setup.md b/.claude/plans/windows-gpu-server-setup.md deleted file mode 100644 index 4c754b754..000000000 --- a/.claude/plans/windows-gpu-server-setup.md +++ /dev/null @@ -1,500 +0,0 @@ -# Implementierungsplan: Windows GPU-Server als AI/ML-Rechner (Stufe 1) - -## Übersicht - -**Ziel:** Windows-PC mit starker GPU als dedizierter AI/ML-Server einrichten. -Der Mac Mini bleibt Orchestrator fΓΌr Web-Apps, Backends und Datenbanken. -Der Windows-PC ΓΌbernimmt alle GPU-intensiven AI/ML-Workloads. - -**Architektur:** - -``` - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Cloudflare Tunnels β”‚ - β”‚ *.mana.how β†’ Mac Mini (Primary) β”‚ - β”‚ llm/tts/stt/img.mana.how β”‚ - β”‚ β†’ Windows PC (AI/ML) β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ β”‚ - β–Ό β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ MAC MINI M4 (16GB) β”‚ β”‚ WINDOWS GPU-SERVER β”‚ -β”‚ "Orchestrator" β”‚ LAN β”‚ "AI/ML Powerhouse" β”‚ -β”‚ 192.168.x.10 │◄───────►│ 192.168.x.11 β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ β”‚ β”‚ β”‚ -β”‚ PostgreSQL, Redis, MinIO β”‚ β”‚ Ollama + CUDA β”‚ -β”‚ mana-core-auth β”‚ β”‚ gemma3:27b, llama3.1:70b β”‚ -β”‚ Alle NestJS Backends β”‚ β”‚ codestral:22b β”‚ -β”‚ Alle SvelteKit Frontends β”‚ β”‚ β”‚ -β”‚ Matrix Synapse + Bots β”‚ β”‚ mana-stt (Whisper Large) β”‚ -β”‚ Monitoring Stack β”‚ β”‚ mana-tts (Kokoro + Piper) β”‚ -β”‚ n8n, Umami β”‚ β”‚ mana-image-gen (FLUX.2) β”‚ -β”‚ mana-llm (Gateway) β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ Cloudflare Tunnel β”‚ -β”‚ Ollama gemma3:4b (Fallback) β”‚ β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -**Was sich Γ€ndert:** Die AI-Services (Ollama, STT, TTS, Image Gen) laufen auf dem Windows-PC statt nativ auf dem Mac Mini. Der Mac Mini behΓ€lt Ollama mit kleinen Modellen als Fallback. `mana-llm` (der LLM-Gateway-Container) bleibt auf dem Mac Mini, zeigt aber auf den Windows-PC. - ---- - -## Phase 1: Windows-PC vorbereiten (1 Std) - -### 1.1 Voraussetzungen prΓΌfen - -- [ ] Windows 10/11 Pro (fΓΌr WSL2 + Hyper-V) -- [ ] NVIDIA GPU mit aktuellem Treiber (>= 535.x fΓΌr CUDA 12) -- [ ] Mindestens 32GB RAM empfohlen -- [ ] Mindestens 200GB freier Speicher fΓΌr Modelle -- [ ] Ethernet-Verbindung zum selben Netzwerk wie Mac Mini - -### 1.2 Statische IP konfigurieren - -``` -Einstellungen β†’ Netzwerk β†’ Ethernet β†’ IP-Einstellungen bearbeiten - IP-Adresse: 192.168.x.11 - Subnetzmaske: 255.255.255.0 - Gateway: 192.168.x.1 - DNS: 1.1.1.1, 8.8.8.8 -``` - -### 1.3 Computername setzen - -```powershell -# PowerShell als Admin -Rename-Computer -NewName "mana-server-gpu" -Restart-Computer -``` - -### 1.4 SSH aktivieren - -```powershell -# PowerShell als Admin -Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 -Start-Service sshd -Set-Service -Name sshd -StartupType Automatic -``` - -### 1.5 Windows Firewall β€” Ports freigeben - -```powershell -# PowerShell als Admin β€” nur interne Ports fΓΌrs LAN -New-NetFirewallRule -DisplayName "Ollama" -Direction Inbound -LocalPort 11434 -Protocol TCP -Action Allow -New-NetFirewallRule -DisplayName "Mana-STT" -Direction Inbound -LocalPort 3020 -Protocol TCP -Action Allow -New-NetFirewallRule -DisplayName "Mana-TTS" -Direction Inbound -LocalPort 3022 -Protocol TCP -Action Allow -New-NetFirewallRule -DisplayName "Mana-Image-Gen" -Direction Inbound -LocalPort 3023 -Protocol TCP -Action Allow -New-NetFirewallRule -DisplayName "Mana-LLM" -Direction Inbound -LocalPort 3025 -Protocol TCP -Action Allow -``` - ---- - -## Phase 2: NVIDIA CUDA Setup (30 Min) - -### 2.1 CUDA Toolkit installieren - -1. NVIDIA Treiber aktualisieren (GeForce Experience oder nvidia.com) -2. CUDA Toolkit 12.x installieren: https://developer.nvidia.com/cuda-downloads -3. cuDNN installieren: https://developer.nvidia.com/cudnn - -```powershell -# PrΓΌfen ob CUDA funktioniert -nvidia-smi -``` - ---- - -## Phase 3: Ollama mit CUDA (30 Min) - -### 3.1 Ollama installieren - -Download: https://ollama.com/download/windows - -Ollama erkennt CUDA automatisch und nutzt die GPU. - -### 3.2 Ollama als Netzwerk-Service konfigurieren - -StandardmÀßig bindet Ollama nur an `localhost`. FΓΌr LAN-Zugriff: - -```powershell -# Systemumgebungsvariable setzen (PowerShell als Admin) -[System.Environment]::SetEnvironmentVariable("OLLAMA_HOST", "0.0.0.0:11434", "Machine") -[System.Environment]::SetEnvironmentVariable("OLLAMA_ORIGINS", "*", "Machine") - -# Ollama neu starten -# Task Manager β†’ Ollama beenden β†’ Ollama App neu starten -``` - -### 3.3 Modelle herunterladen - -```powershell -# Große Modelle (nutzen GPU VRAM) -ollama pull gemma3:27b # ~16 GB β€” Hauptmodell -ollama pull codestral:22b # ~14 GB β€” Code-Modell -ollama pull llama3.1:70b # ~40 GB β€” nur wenn VRAM reicht (4-bit quant) - -# KompatibilitΓ€ts-Modelle (gleich wie Mac Mini) -ollama pull gemma3:4b # ~2.5 GB -ollama pull gemma3:12b # ~7 GB -``` - -### 3.4 GPU-Nutzung testen - -```powershell -# In einem Terminal -ollama run gemma3:27b "Sage Hallo in einem Satz" - -# In einem zweiten Terminal: GPU-Auslastung prΓΌfen -nvidia-smi -# β†’ Ollama sollte VRAM belegen -``` - -### 3.5 Ollama Autostart einrichten - -Ollama fΓΌr Windows startet normalerweise automatisch mit dem System (Tray-App). -Falls nicht: - -```powershell -# Startup-Ordner ΓΆffnen -shell:startup -# VerknΓΌpfung zu Ollama.exe dort ablegen -``` - ---- - -## Phase 4: Cloudflare Tunnel auf Windows-PC (30 Min) - -### 4.1 cloudflared installieren - -```powershell -# Option A: winget -winget install Cloudflare.cloudflared - -# Option B: Download -# https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/ -``` - -### 4.2 Tunnel erstellen - -```powershell -cloudflared tunnel login -cloudflared tunnel create mana-server-gpu - -# Tunnel-ID notieren! -# Credentials liegen in: C:\Users\\.cloudflared\.json -``` - -### 4.3 DNS-Routen erstellen - -```powershell -cloudflared tunnel route dns mana-server-gpu gpu.mana.how -cloudflared tunnel route dns mana-server-gpu llm.mana.how -cloudflared tunnel route dns mana-server-gpu stt-v2.mana.how -cloudflared tunnel route dns mana-server-gpu tts-v2.mana.how -cloudflared tunnel route dns mana-server-gpu img.mana.how -``` - -### 4.4 Tunnel-Config erstellen - -**Datei:** `C:\Users\\.cloudflared\config.yml` - -```yaml -tunnel: -credentials-file: C:\Users\\.cloudflared\.json - -ingress: - # SSH Access - - hostname: gpu.mana.how - service: ssh://localhost:22 - - # Ollama LLM direkt (fΓΌr mana-llm auf Mac Mini) - - hostname: llm.mana.how - service: http://localhost:11434 - originRequest: - connectTimeout: 300s - - # STT Service (Whisper Large) - - hostname: stt-v2.mana.how - service: http://localhost:3020 - - # TTS Service (Kokoro + Piper) - - hostname: tts-v2.mana.how - service: http://localhost:3022 - - # Image Generation (FLUX.2) - - hostname: img.mana.how - service: http://localhost:3023 - - # Catch-all - - service: http_status:404 -``` - -### 4.5 Tunnel als Windows-Service installieren - -```powershell -# PowerShell als Admin -cloudflared service install -# β†’ Startet automatisch mit Windows -``` - ---- - -## Phase 5: AI-Services installieren (1-2 Std) - -### 5.1 Python-Umgebung einrichten - -```powershell -# Python 3.11 installieren (python.org oder winget) -winget install Python.Python.3.11 - -# Virtuelle Umgebungen erstellen -python -m venv C:\mana\venvs\mana-stt -python -m venv C:\mana\venvs\mana-tts -python -m venv C:\mana\venvs\mana-image-gen -``` - -### 5.2 mana-stt (Speech-to-Text) β€” Port 3020 - -```powershell -C:\mana\venvs\mana-stt\Scripts\activate - -# CUDA-fΓ€higes PyTorch installieren -pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu121 - -# Whisper installieren -pip install faster-whisper -pip install fastapi uvicorn python-multipart - -# Service-Code klonen/kopieren -git clone C:\mana\services\mana-stt -# oder: scp vom Mac Mini -``` - -**Windows-Service erstellen (NSSM):** - -```powershell -# NSSM (Non-Sucking Service Manager) installieren -winget install NSSM - -# Service registrieren -nssm install mana-stt "C:\mana\venvs\mana-stt\Scripts\python.exe" "C:\mana\services\mana-stt\main.py" -nssm set mana-stt AppDirectory "C:\mana\services\mana-stt" -nssm set mana-stt AppEnvironmentExtra "CUDA_VISIBLE_DEVICES=0" "DEVICE=cuda" "PORT=3020" -nssm set mana-stt Start SERVICE_AUTO_START -nssm start mana-stt -``` - -### 5.3 mana-tts (Text-to-Speech) β€” Port 3022 - -```powershell -C:\mana\venvs\mana-tts\Scripts\activate - -pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu121 -pip install kokoro-onnx piper-tts -pip install fastapi uvicorn python-multipart - -# Service registrieren -nssm install mana-tts "C:\mana\venvs\mana-tts\Scripts\python.exe" "C:\mana\services\mana-tts\main.py" -nssm set mana-tts AppDirectory "C:\mana\services\mana-tts" -nssm set mana-tts AppEnvironmentExtra "DEVICE=cuda" "PORT=3022" -nssm set mana-tts Start SERVICE_AUTO_START -nssm start mana-tts -``` - -### 5.4 mana-image-gen (FLUX.2) β€” Port 3023 - -```powershell -C:\mana\venvs\mana-image-gen\Scripts\activate - -pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 -pip install diffusers transformers accelerate -pip install fastapi uvicorn python-multipart - -# FLUX.2 Modell herunterladen (~16 GB) -# Details je nach Implementation in services/mana-image-gen/ - -nssm install mana-image-gen "C:\mana\venvs\mana-image-gen\Scripts\python.exe" "C:\mana\services\mana-image-gen\main.py" -nssm set mana-image-gen AppDirectory "C:\mana\services\mana-image-gen" -nssm set mana-image-gen AppEnvironmentExtra "CUDA_VISIBLE_DEVICES=0" "DEVICE=cuda" "PORT=3023" -nssm set mana-image-gen Start SERVICE_AUTO_START -nssm start mana-image-gen -``` - ---- - -## Phase 6: Mac Mini umkonfigurieren (30 Min) - -### 6.1 docker-compose.macmini.yml anpassen - -Die AI-Service-URLs in den Docker-Containern auf dem Mac Mini mΓΌssen auf den Windows-PC zeigen. - -**Variante A β€” Über LAN-IP (einfach, schnell):** - -```yaml -# In docker-compose.macmini.yml Γ€ndern: - -# mana-llm Service -mana-llm: - environment: - OLLAMA_URL: http://192.168.x.11:11434 # War: http://host.docker.internal:11434 - OLLAMA_DEFAULT_MODEL: gemma3:27b # War: gemma3:4b (jetzt grâßeres Modell mΓΆglich) - -# chat-backend -chat-backend: - environment: - OLLAMA_URL: http://192.168.x.11:11434 # War: http://host.docker.internal:11434 - -# Matrix Bots -matrix-mana-bot: - environment: - OLLAMA_URL: http://192.168.x.11:11434 - STT_URL: http://192.168.x.11:3020 - TTS_URL: http://192.168.x.11:3022 - -matrix-ollama-bot: - environment: - OLLAMA_URL: http://192.168.x.11:11434 - -matrix-tts-bot: - environment: - TTS_URL: http://192.168.x.11:3022 - -matrix-stt-bot: - environment: - STT_URL: http://192.168.x.11:3020 -``` - -**Variante B β€” Über Cloudflare Tunnel (robuster, funktioniert auch remote):** - -```yaml -OLLAMA_URL: https://llm.mana.how -STT_URL: https://stt-v2.mana.how -TTS_URL: https://tts-v2.mana.how -``` - -β†’ Variante A ist schneller (LAN, keine Latenz durch Cloudflare), Variante B ist flexibler. - -**Empfehlung:** Variante A fΓΌr interne Services, Cloudflare-URLs nur fΓΌr externe Zugriffe. - -### 6.2 Ollama auf Mac Mini als Fallback behalten - -Mac Mini behΓ€lt Ollama mit kleinen Modellen (`gemma3:4b`). Falls der Windows-PC offline ist, kann `mana-llm` auf den lokalen Ollama zurΓΌckfallen. Das muss im mana-llm Service konfiguriert werden (Fallback-URL). - -### 6.3 Cloudflare Tunnel auf Mac Mini anpassen - -Alte STT/TTS-Routen auf dem Mac Mini entfernen oder beibehalten (als Fallback): - -```yaml -# ~/.cloudflared/config.yml auf Mac Mini -# Diese Routen zeigen weiterhin auf lokale Ports: -- hostname: stt-api.mana.how # bleibt als Fallback (Mac Mini Whisper) - service: http://localhost:3020 - -# Neue v2-Routen gehen ΓΌber den Windows-PC Tunnel -# stt-v2.mana.how β†’ Windows-PC (konfiguriert in Phase 4) -``` - ---- - -## Phase 7: SSH-Config & Testing (30 Min) - -### 7.1 SSH-Config auf Dev-Rechner erweitern - -``` -# ~/.ssh/config -Host mana-server-gpu - HostName gpu.mana.how - User - ProxyCommand /opt/homebrew/bin/cloudflared access ssh --hostname %h -``` - -### 7.2 Testing Checklist - -```bash -# Vom Dev-Rechner aus: - -# SSH -ssh mana-server-gpu - -# Ollama auf Windows-PC direkt (LAN) -curl http://192.168.x.11:11434/api/version - -# Ollama ΓΌber Cloudflare Tunnel -curl https://llm.mana.how/api/version - -# Großes Modell testen -curl http://192.168.x.11:11434/api/generate \ - -d '{"model":"gemma3:27b","prompt":"Hallo!","stream":false}' - -# STT Health -curl http://192.168.x.11:3020/health - -# TTS Health -curl http://192.168.x.11:3022/health - -# Image Gen Health -curl http://192.168.x.11:3023/health - -# GPU-Auslastung remote prΓΌfen -ssh mana-server-gpu "nvidia-smi" -``` - -### 7.3 Von Mac Mini aus testen - -```bash -ssh mana-server # Auf Mac Mini verbinden - -# Kann Mac Mini den Windows-PC erreichen? -curl http://192.168.x.11:11434/api/version - -# Docker-Container kΓΆnnen Windows-PC erreichen? -docker exec mana-service-llm curl http://192.168.x.11:11434/api/version -``` - ---- - -## Zusammenfassung: Was wo lΓ€uft - -### Mac Mini (192.168.x.10) β€” bleibt wie gehabt, minus AI-Last - -| Service | Port | Status | -|---------|------|--------| -| PostgreSQL | 5432 | Primary | -| Redis | 6379 | Primary | -| MinIO | 9000 | UnverΓ€ndert | -| mana-core-auth | 3001 | UnverΓ€ndert | -| Alle Backends | 3030-3040 | UnverΓ€ndert | -| Alle Frontends | 5000-5100 | UnverΓ€ndert | -| Matrix Stack | 4000-4090 | UnverΓ€ndert | -| Monitoring | 8000-8020 | UnverΓ€ndert | -| mana-llm (Gateway) | 3025 | Bleibt, zeigt auf Windows-PC | -| Ollama (Fallback) | 11434 | BehΓ€lt gemma3:4b | -| mana-stt | 3020 | Kann als Fallback bleiben | -| mana-tts | 3022 | Kann als Fallback bleiben | - -### Windows-PC (192.168.x.11) β€” nur AI/ML - -| Service | Port | GPU | Beschreibung | -|---------|------|-----|-------------| -| Ollama | 11434 | CUDA | gemma3:27b, codestral:22b, llama3.1:70b | -| mana-stt | 3020 | CUDA | Whisper Large V3 | -| mana-tts | 3022 | CUDA | Kokoro + Piper | -| mana-image-gen | 3023 | CUDA | FLUX.2 | -| cloudflared | β€” | β€” | Tunnel fΓΌr externe Erreichbarkeit | - ---- - -## Implementierungs-Reihenfolge - -1. **Phase 1:** Windows-PC vorbereiten (IP, SSH, Firewall) -2. **Phase 2:** CUDA Setup prΓΌfen -3. **Phase 3:** Ollama installieren + Modelle laden + testen -4. **Phase 4:** Cloudflare Tunnel einrichten -5. **Phase 5:** AI-Services installieren (STT, TTS, Image Gen) -6. **Phase 6:** Mac Mini umkonfigurieren (URLs auf Windows-PC) -7. **Phase 7:** End-to-End testen - -**Empfehlung:** Starte mit Phase 1-3 (Ollama mit GPU). Das bringt sofort den grâßten Nutzen β€” 27B-Modelle statt 4B. Die anderen AI-Services (Phase 5) kΓΆnnen danach einzeln migriert werden. diff --git a/APP-IDEAS.md b/APP-IDEAS.md deleted file mode 100644 index e0155380a..000000000 --- a/APP-IDEAS.md +++ /dev/null @@ -1,119 +0,0 @@ -# App-VorschlΓ€ge fΓΌr Manacore - -Ideen fΓΌr neue Apps im Manacore-Γ–kosystem, sortiert nach Kategorie und PrioritΓ€t. - -**Stand:** Dezember 2024 -**Aktuelle Apps:** 13 aktiv, 8 archiviert, 3 Games - ---- - -## Top-PrioritΓ€t (fΓΌllen wichtige LΓΌcken) - -| App | Beschreibung | Synergien | -| ------------- | ------------------------------------------------------------------------- | ------------------------------------ | -| **notes** | Notizen & Wiki mit Markdown, Verlinkung und KI-Zusammenfassungen | calendar, todo, contacts | -| **finance** | Budget-Tracker, Ausgaben-Kategorisierung, FinanzΓΌbersicht mit KI-Insights | calendar (Rechnungen), mail (Belege) | -| **habits** | Gewohnheits-Tracker mit Streaks, Statistiken und Erinnerungen | todo, calendar, clock | -| **passwords** | Passwort-Manager mit sicherer VerschlΓΌsselung und Autofill | Alle Apps (SSO) | - ---- - -## Lifestyle & Gesundheit - -| App | Beschreibung | Synergien | -| ------------ | --------------------------------------------------------------- | ---------------------------- | -| **fitness** | Workout-Tracking, TrainingsplΓ€ne, Fortschritts-Statistiken | calendar, habits, nutriphi | -| **sleep** | Schlaf-Tracking mit Smart-Alarm und Schlafanalyse | clock, habits, moods | -| **meditate** | Meditation & Achtsamkeit mit gefΓΌhrten Sessions und AtemΓΌbungen | clock (Timer), moods, habits | -| **water** | Wasser-Tracker mit Erinnerungen und Tageszielen | habits, clock | - ---- - -## Wissen & Lernen - -| App | Beschreibung | Synergien | -| ------------- | ----------------------------------------------------------------------- | ------------------------ | -| **bookmarks** | Lesezeichen & Read-Later mit KI-Tagging und Zusammenfassungen | chat (KI), wisekeep | -| **vocab** | Vokabel-Trainer mit Spaced Repetition (wie manadeck, aber fΓΌr Sprachen) | manadeck | -| **courses** | Online-Kurse verwalten, Fortschritt tracken | todo, calendar, manadeck | - ---- - -## ProduktivitΓ€t - -| App | Beschreibung | Synergien | -| ------------- | ------------------------------------------------------ | ---------------------------- | -| **timetrack** | Zeiterfassung fΓΌr Projekte, Kunden, Reporting | todo, calendar | -| **invoices** | Rechnungen erstellen & verwalten fΓΌr Freelancer | contacts, finance, timetrack | -| **snippets** | Code-Snippets Manager mit Syntax-Highlighting und Tags | Entwickler-Tools | -| **forms** | Formulare & Umfragen erstellen und auswerten | contacts, mail | - ---- - -## Kreativ & Media - -| App | Beschreibung | Synergien | -| ------------ | ------------------------------------------------- | ----------------- | -| **music** | Musik-Player mit Playlists und lokaler Bibliothek | moods | -| **podcasts** | Podcast-Player mit Transkription (via Whisper) | wisekeep, memoro | -| **draw** | Zeichen-App mit Layern und Export | picture | -| **video** | Video-Editor (einfach) mit KI-Untertitelung | picture, wisekeep | - ---- - -## Social & Kommunikation - -| App | Beschreibung | Synergien | -| ------------ | --------------------------------------------------------- | ------------------------ | -| **social** | Social Media Dashboard - alle Accounts an einem Ort | mail, contacts | -| **meetings** | Meeting-Scheduler mit VerfΓΌgbarkeits-Links (wie Calendly) | calendar, contacts | -| **crm** | Einfaches CRM fΓΌr Kontakt-Beziehungen und Follow-ups | contacts, mail, calendar | - ---- - -## Utility & Smart Home - -| App | Beschreibung | Synergien | -| ------------- | ------------------------------------------------- | ------------------------ | -| **weather** | Wetter-App mit Widgets und Warnungen | calendar, clock | -| **home** | Smart Home Dashboard fΓΌr IoT-GerΓ€te | moods (Licht), clock | -| **travel** | Reiseplanung mit Packlisten, Buchungen, Itinerary | calendar, todo, contacts | -| **inventory** | Inventar-/Besitz-Verwaltung mit Fotos und Wert | storage | - ---- - -## Empfehlung - Top 5 zum Starten - -1. **notes** - Fehlt komplett, jeder braucht Notizen -2. **habits** - Perfekte ErgΓ€nzung zu todo/calendar/clock -3. **finance** - Hoher Nutzwert, gut monetarisierbar -4. **timetrack** - FΓΌr Freelancer/ProduktivitΓ€t essentiell -5. **bookmarks** - Einfach umzusetzen, hoher Mehrwert mit KI - ---- - -## Übersicht nach Aufwand - -### Einfach (1-2 Wochen) - -- water -- habits -- bookmarks - -### Mittel (2-4 Wochen) - -- notes -- timetrack -- weather -- inventory -- vocab - -### Komplex (4+ Wochen) - -- finance -- passwords -- fitness -- invoices -- crm -- podcasts -- video diff --git a/AUTH_ANALYSIS_SUMMARY.md b/AUTH_ANALYSIS_SUMMARY.md deleted file mode 100644 index 9c39fb3b1..000000000 --- a/AUTH_ANALYSIS_SUMMARY.md +++ /dev/null @@ -1,443 +0,0 @@ -# Auth Architecture Analysis - Executive Summary - -**Analysis Date:** December 1, 2024 -**Analyst:** Auth Architecture Specialist -**Status:** Complete & Approved - ---- - -## Objective - -Analyze the mana-core-auth service as the definitive source of truth for authentication patterns in the Mana Universe ecosystem, documenting canonical patterns that all backends must follow. - ---- - -## Key Findings - -### 1. Central Authentication Service (mana-core-auth) - -**Location:** `/services/mana-core-auth` -**Port:** 3001 -**Framework:** NestJS + Better Auth -**Algorithm:** EdDSA (Elliptic Curve) with JWT plugin -**Database:** PostgreSQL with Drizzle ORM - -**Critical Role:** -- Single source of truth for all user authentication -- Manages JWT token generation and validation -- Provides JWKS (public keys) for verification -- Handles B2C and B2B (organizations) flows - -### 2. JWT Token Architecture - -**Algorithm:** EdDSA (NOT RS256 or HS256) -- Better performance than RSA -- Stronger security properties -- Smaller key size -- Used via `jose` library (not `jsonwebtoken`) - -**Claims Design:** MINIMAL (by architectural decision) -```json -{ - "sub": "user-id", - "email": "user@example.com", - "role": "user", - "sid": "session-id" -} -``` - -**What's NOT in JWT:** -- Organization data (fetch via API) -- Credit balance (fetch via API) -- Customer type (derive from session) -- Device info (from session table) - -**Expiration:** -- Access Token: 15 minutes -- Refresh Token: 7 days -- Refresh token rotation implemented for security - -### 3. API Versioning & Routes - -**Global Prefix:** `/api/v1` - -**Main Endpoints:** -- `POST /auth/register` - User registration -- `POST /auth/login` - User login -- `POST /auth/refresh` - Token refresh -- `POST /auth/validate` - Token validation -- `GET /auth/jwks` - Public keys -- `POST /auth/register/b2b` - Organization registration -- `GET /auth/organizations` - List user organizations - -### 4. Backend Integration Patterns - -**Two Integration Paths Identified:** - -**Path A: Lightweight Auth** (`@manacore/shared-nestjs-auth`) -- For services without credit tracking -- Minimal dependencies -- Used by: Zitare, Picture backends - -**Path B: Full Integration** (`@mana-core/nestjs-integration`) -- Auth + credit system -- Module-based setup -- Used by: Chat, ManaDeck backends - -**Guard Pattern:** All backends validate tokens by calling: -``` -POST /api/v1/auth/validate -{ "token": "eyJhbGciOiJFZERTQSI..." } -``` - -### 5. Database Schema - -**Storage Location:** PostgreSQL `auth` schema - -**Key Tables:** -- `auth.users` - User accounts -- `auth.sessions` - Active sessions with refresh tokens -- `auth.accounts` - Provider credentials -- `auth.verification` - Email verification/password reset -- `auth.jwks` - EdDSA signing keys (Better Auth managed) - -**ID Type:** All user IDs are TEXT (nanoid), not UUID - -### 6. Environment Configuration - -**Required for all backends:** -```env -MANA_CORE_AUTH_URL=http://localhost:3001 -``` - -**Optional development:** -```env -NODE_ENV=development -DEV_BYPASS_AUTH=true -DEV_USER_ID=test-user-id -``` - -**Better Auth manages JWT:** Do NOT set JWT_PRIVATE_KEY, JWT_PUBLIC_KEY, etc. - ---- - -## Architecture Decisions (Validated) - -### Decision 1: Minimal JWT Claims -**Status:** CONFIRMED across codebase -**Rationale:** -- Credit balance changes frequently (every operation) -- Organization context available via API -- Smaller tokens improve performance -- Follows Better Auth's session-based design - -**Testing Evidence:** -- `src/auth/jwt-validation.spec.ts` explicitly tests that complex claims are NOT present -- Comments in `better-auth.config.ts` forbid adding extra claims -- All backends follow minimal pattern - -### Decision 2: EdDSA Over RSA -**Status:** CONFIRMED -**Rationale:** -- Better Auth default algorithm -- Smaller keys (32 bytes vs 2048+ bits) -- Better performance in signing/verification -- Strong security properties - -**Implementation:** -- Keys stored in `auth.jwks` table -- Better Auth handles key generation -- `jose` library for verification (not jsonwebtoken) - -### Decision 3: Centralized Validation -**Status:** CONFIRMED -**Pattern:** -- Backends don't verify JWT locally -- Call `POST /api/v1/auth/validate` for each request -- Reduces key distribution complexity -- Single source of truth for validity - -**Guard Implementation:** -```typescript -// Fetch user data by validating token -const response = await fetch(`${authUrl}/api/v1/auth/validate`, { - method: 'POST', - body: JSON.stringify({ token }) -}); -const { valid, payload } = await response.json(); -``` - -### Decision 4: Refresh Token Rotation -**Status:** CONFIRMED -**Mechanism:** -- Old refresh token marked as revoked (soft delete) -- New token issued on refresh -- Prevents token replay attacks -- Session tracks device info - ---- - -## Validation Results - -### Code Review Findings - -**mana-core-auth Service:** βœ“ VERIFIED -- Implements Better Auth correctly -- JWT plugin configured properly -- Organization plugin working -- Credit system integrated -- Error handling appropriate - -**Shared Packages:** βœ“ VERIFIED -- `@manacore/shared-nestjs-auth` - Guard implementation correct -- `@mana-core/nestjs-integration` - Extended module working -- Both properly call validation endpoint -- Both inject CurrentUserData correctly - -**Example Backends:** βœ“ VERIFIED -- Zitare backend uses correct pattern -- Imports correct packages -- Applies guards properly -- Uses @CurrentUser() decorator correctly - -### Security Assessment - -**Strengths:** -- EdDSA algorithm secure -- Refresh token rotation implemented -- Token validation centralized -- CORS properly configured -- Development bypass supports testing - -**Best Practices Followed:** -- JWT claims minimal -- No token logging -- 401 returned for auth failures -- Password hashing via Better Auth -- Session expiration enforced - ---- - -## Deliverables Created - -### 1. AUTH_ARCHITECTURE_REPORT.md (15 sections) -**Comprehensive documentation covering:** -- API route structure and versioning -- JWT token format and claims -- Validation flow and JWKS -- Authentication guards and decorators -- Database schema -- Environment variables -- End-to-end flows (login, refresh, B2B) -- Integration best practices -- Troubleshooting guide -- Security considerations - -**Usage:** Reference for architectural decisions and implementation guidance - -### 2. AUTH_VALIDATION_CHECKLIST.md -**Practical checklist for:** -- Pre-integration decisions -- Implementation verification -- API route validation -- JWT claims verification -- Testing procedures -- Production readiness -- Code review standards -- Common issues and fixes - -**Usage:** Sign-off document for new backend integrations - -### 3. AUTH_QUICK_REFERENCE.md -**Quick lookup guide with:** -- Essential endpoints -- Common curl commands -- Guard usage patterns -- Environment variables -- Token inspection -- Troubleshooting -- File locations - -**Usage:** Daily development reference - -### 4. AUTH_ANALYSIS_SUMMARY.md (This Document) -**Executive summary with:** -- Key findings -- Architecture decisions -- Validation results -- Integration guidance -- Common patterns - -**Usage:** High-level overview for stakeholders - ---- - -## Integration Guidance for New Services - -### For New Backend Services - -1. **Choose Integration Path:** - - No credits β†’ Use `@manacore/shared-nestjs-auth` - - With credits β†’ Use `@mana-core/nestjs-integration` - -2. **Setup (5 minutes):** - - Install package - - Configure environment variables - - Add guard to main.ts - - Use @CurrentUser() decorator - -3. **Validate:** - - Use AUTH_VALIDATION_CHECKLIST.md - - Ensure all items pass - - Get code review approval - -4. **Test:** - - Start mana-core-auth service - - Test manual token flow - - Run unit tests - - Verify dev bypass works - -### Code Examples Provided - -All documentation includes working code examples: -- Guard setup in controllers -- Decorator usage patterns -- Error handling -- Public route marking -- Token testing commands - ---- - -## Common Patterns Identified - -### Pattern 1: Token Validation Guard -```typescript -// All backends use same pattern -const response = await fetch('/api/v1/auth/validate', { - method: 'POST', - body: JSON.stringify({ token }) -}); -const { valid, payload } = await response.json(); -request.user = { userId: payload.sub, ... }; -``` - -### Pattern 2: User Data Injection -```typescript -// Consistent across all services -@Get('profile') -getProfile(@CurrentUser() user: CurrentUserData) { - // user.userId, user.email, user.role available -} -``` - -### Pattern 3: Public Routes -```typescript -// Path B pattern for non-protected endpoints -@Get('health') -@Public() -health() { return { status: 'ok' }; } -``` - -### Pattern 4: Development Testing -```typescript -// All backends support -NODE_ENV=development -DEV_BYPASS_AUTH=true -// No token required, mock user injected -``` - ---- - -## Risk Assessment - -### Current State: LOW RISK -- Architecture well-defined -- Patterns consistently implemented -- Security measures in place -- Good documentation exists - -### Potential Risks: MITIGATED -1. **Token validation failure** β†’ Handled with UnauthorizedException -2. **Lost refresh tokens** β†’ 7-day rotation with revocation -3. **Auth service down** β†’ Documented in troubleshooting -4. **Configuration errors** β†’ Checklists prevent common issues - -### Recommendations -1. Add distributed caching for JWKS (performance) -2. Implement token blacklist for logout (security) -3. Add rate limiting per user (security) -4. Monitor token validation latency (operations) - ---- - -## Success Criteria Met - -- [x] Service structure documented -- [x] JWT token format explained -- [x] Validation flow documented -- [x] Expected guard/decorator patterns identified -- [x] Required environment variables listed -- [x] Integration best practices captured -- [x] Validation checklist created -- [x] Quick reference guide provided -- [x] Code examples included -- [x] Troubleshooting guide provided - ---- - -## File Locations - -### Documentation Files (Created) -- `AUTH_ARCHITECTURE_REPORT.md` - 15-section comprehensive guide -- `AUTH_VALIDATION_CHECKLIST.md` - Implementation validation checklist -- `AUTH_QUICK_REFERENCE.md` - Quick lookup guide -- `AUTH_ANALYSIS_SUMMARY.md` - This executive summary - -### Source Files (Analyzed) -- `services/mana-core-auth/src/auth/` - Main auth implementation -- `services/mana-core-auth/src/db/schema/auth.schema.ts` - Database schema -- `packages/shared-nestjs-auth/src/guards/` - Backend guard -- `packages/mana-core-nestjs-integration/src/guards/` - Extended guard -- `apps/zitare/apps/backend/` - Example backend implementation - ---- - -## Conclusion - -The mana-core-auth service successfully implements a **secure, scalable, and well-documented authentication system** for the Mana Universe ecosystem. - -**Key Takeaways:** -1. EdDSA + Better Auth provides strong security foundation -2. Minimal JWT claims design prevents stale data issues -3. Centralized validation ensures single source of truth -4. Two integration paths support diverse backend needs -5. Development bypass enables rapid testing - -**Recommendation:** Use provided documents as canonical reference for all future authentication work. - ---- - -## Approval & Sign-Off - -**Analysis Completed:** 2024-12-01 -**Documentation Status:** COMPLETE -**Validation Status:** APPROVED - -**Next Steps:** -1. Share documents with development team -2. Update new backend integration process to use checklists -3. Reference architecture report in code reviews -4. Monitor compliance via checklist - -**Questions?** Refer to: -- Quick questions β†’ AUTH_QUICK_REFERENCE.md -- Implementation details β†’ AUTH_ARCHITECTURE_REPORT.md -- Integration validation β†’ AUTH_VALIDATION_CHECKLIST.md -- Architecture decisions β†’ This summary - ---- - -**Report Generated:** December 1, 2024 -**Analyst:** Auth Architecture Specialist -**Organization:** Mana Universe Engineering -**Status:** Ready for Production Use diff --git a/AUTH_ARCHITECTURE_REPORT.md b/AUTH_ARCHITECTURE_REPORT.md deleted file mode 100644 index a5a2a61ff..000000000 --- a/AUTH_ARCHITECTURE_REPORT.md +++ /dev/null @@ -1,969 +0,0 @@ -# Mana Core Authentication Architecture - Canonical Pattern Report - -**Date:** 2024-12-01 -**Service:** mana-core-auth (Central Authentication Service) -**Author:** Auth Architecture Analysis -**Status:** Source of Truth - ---- - -## Executive Summary - -This report documents the **canonical authentication architecture** for the Mana Universe ecosystem. All backend services must implement auth according to these patterns. The mana-core-auth service (port 3001) is the single source of truth for JWT validation, token issuance, and user authentication. - -**Key Principles:** -- All JWT tokens are generated and validated via mana-core-auth -- Minimal JWT claims (no dynamic data) -- EdDSA algorithm with Better Auth's JWKS -- Better Auth framework handles all auth logic (no custom implementations) -- Development bypass mode supported for testing - ---- - -## 1. API Route Structure & Versioning - -### Global Prefix -``` -/api/v1 -``` - -**All auth endpoints are prefixed with `/api/v1/auth`** - -### Authentication Endpoints - -#### B2C (Individual Users) - -| Method | Route | Purpose | Auth Required | Response | -|--------|-------|---------|---------------|----------| -| POST | `/auth/register` | Register new user | No | `{ user, token? }` | -| POST | `/auth/login` | Sign in with credentials | No | `{ user, accessToken, refreshToken, expiresIn }` | -| POST | `/auth/logout` | Sign out user | Yes | `{ success: true, message }` | -| POST | `/auth/refresh` | Refresh access token | No | `{ user, accessToken, refreshToken, expiresIn, tokenType }` | -| GET | `/auth/session` | Get current session | Yes | `{ user, session }` | -| POST | `/auth/validate` | Validate JWT token | No | `{ valid: boolean, payload?, error? }` | -| GET | `/auth/jwks` | Get public keys (JWKS) | No | `{ keys: [] }` | - -#### B2B (Organizations) - -| Method | Route | Purpose | Auth Required | -|--------|-------|---------|---------------| -| POST | `/auth/register/b2b` | Register org with owner | No | -| GET | `/auth/organizations` | List user's organizations | Yes | -| GET | `/auth/organizations/:id` | Get org details | Yes | -| GET | `/auth/organizations/:id/members` | List org members | Yes | -| POST | `/auth/organizations/:id/invite` | Invite employee | Yes | -| POST | `/auth/organizations/accept-invitation` | Accept invitation | Yes | -| DELETE | `/auth/organizations/:id/members/:memberId` | Remove member | Yes | -| POST | `/auth/organizations/set-active` | Switch active org | Yes | - -### HTTP Status Codes - -- **200 OK** - Successful operation -- **201 Created** - Resource created (implicit in POST endpoints) -- **400 Bad Request** - Invalid input validation -- **401 Unauthorized** - Token missing or invalid -- **403 Forbidden** - Permission denied (e.g., insufficient org role) -- **404 Not Found** - Resource not found -- **409 Conflict** - Email already exists - ---- - -## 2. JWT Token Format & Structure - -### Token Algorithm -- **Algorithm:** EdDSA (Elliptic Curve Digital Signature Algorithm) -- **Key Type:** Ed25519 (NOT RSA, NOT HS256) -- **Library:** `jose` (NOT `jsonwebtoken`) -- **Key Storage:** Managed by Better Auth in `auth.jwks` table - -### Token Claims (Minimal Design) - -```json -{ - "sub": "user-uuid", // Subject (user ID) - "email": "user@example.com", // Email address - "role": "user", // Role: user | admin | service - "sid": "session-uuid", // Session ID for tracking - "iat": 1733040000, // Issued at (auto) - "exp": 1733040900, // Expires in 15 minutes (auto) - "iss": "manacore", // Issuer - "aud": "manacore" // Audience -} -``` - -### What NOT to Include in JWT - -The following should **NOT** be in JWT claims (fetch via API instead): - -| Data | Reason | API Endpoint | -|------|--------|--------------| -| Organization info | Can change frequently | `POST /organization/get-active-member` | -| Credit balance | Changes every operation | `GET /api/v1/credits/balance` | -| Customer type | Derive from `session.activeOrganizationId` | N/A | -| Device info | Static per session | `auth.sessions.deviceId` | -| Permissions | Dynamic based on role + org | Use `@CurrentUser().role` | - -### Token Expiration Times - -| Token Type | Expiry | Rotation | -|-----------|--------|----------| -| Access Token (JWT) | 15 minutes | Refresh token required | -| Refresh Token | 7 days | Refresh token rotation (old revoked) | -| Session | 7 days | Extends on activity | - -### Token Format in Headers - -``` -Authorization: Bearer eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9... -``` - -**Extraction Pattern:** -```typescript -const [type, token] = authHeader.split(' '); -const jwtToken = type === 'Bearer' ? token : undefined; -``` - ---- - -## 3. Validation Flow & JWKS - -### Token Validation Flow (For Backends) - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Client β”‚ -β”‚ (JWT Token)β”‚ -β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ - β”‚ GET /api/v1/auth/validate - β”‚ { token } - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ mana-core-auth β”‚ -β”‚ (Port 3001) β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ 1. Verify signature β”‚ -β”‚ (JWKS EdDSA keys) β”‚ -β”‚ 2. Check issuer/audienceβ”‚ -β”‚ 3. Check expiration β”‚ -β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ { valid: true, β”‚ -β”‚ payload: {...} β”‚ -β”‚ } β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### JWKS Endpoint - -``` -GET /api/v1/auth/jwks -``` - -**Response Format:** -```json -{ - "keys": [ - { - "kty": "OKP", - "crv": "Ed25519", - "x": "base64url_encoded_public_key", - "kid": "key_id" - } - ] -} -``` - -### Validation Endpoint - -``` -POST /api/v1/auth/validate -Content-Type: application/json - -{ - "token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..." -} -``` - -**Success Response (200 OK):** -```json -{ - "valid": true, - "payload": { - "sub": "user-123", - "email": "user@example.com", - "role": "user", - "sid": "session-456", - "iat": 1733040000, - "exp": 1733040900, - "iss": "manacore", - "aud": "manacore" - } -} -``` - -**Error Response (200 OK with valid=false):** -```json -{ - "valid": false, - "error": "Token expired" -} -``` - ---- - -## 4. Authentication Guards & Decorators - -### Pattern 1: Shared NestJS Auth Package - -**Package:** `@manacore/shared-nestjs-auth` - -```typescript -import { JwtAuthGuard, CurrentUser, CurrentUserData } from '@manacore/shared-nestjs-auth'; - -@Controller('api') -@UseGuards(JwtAuthGuard) -export class MyController { - @Get('profile') - getProfile(@CurrentUser() user: CurrentUserData) { - return { - userId: user.userId, - email: user.email, - role: user.role, - sessionId: user.sessionId - }; - } -} -``` - -**Environment Variables:** -```env -MANA_CORE_AUTH_URL=http://localhost:3001 -NODE_ENV=development -DEV_BYPASS_AUTH=true # Optional: development only -DEV_USER_ID=test-user-uuid # Optional: custom test user -``` - -**Development Bypass:** -- When `NODE_ENV=development` AND `DEV_BYPASS_AUTH=true` -- Guard injects mock user data instead of validating token -- Default dev user ID: `00000000-0000-0000-0000-000000000000` - -### Pattern 2: ManaCoreModule (With Credits) - -**Package:** `@mana-core/nestjs-integration` - -```typescript -// In AppModule -import { ManaCoreModule } from '@mana-core/nestjs-integration'; - -@Module({ - imports: [ - ManaCoreModule.forRootAsync({ - imports: [ConfigModule], - useFactory: (config: ConfigService) => ({ - appId: config.get('APP_ID'), // Required for credit tracking - serviceKey: config.get('SERVICE_KEY'), // For credit operations - debug: config.get('NODE_ENV') === 'development', - }), - inject: [ConfigService], - }), - ], -}) -export class AppModule {} - -// In Controller -import { AuthGuard } from '@mana-core/nestjs-integration'; -import { CurrentUser } from '@mana-core/nestjs-integration'; -import { CreditClientService } from '@mana-core/nestjs-integration'; - -@Controller('api') -@UseGuards(AuthGuard) -export class ApiController { - constructor(private creditClient: CreditClientService) {} - - @Post('generate') - async generate(@CurrentUser() user: any) { - // Consume credits - await this.creditClient.consumeCredits( - user.sub, - 'generation', - 10, - 'AI generation operation' - ); - // ... do work - } -} -``` - -**Public Routes:** -```typescript -import { Public } from '@mana-core/nestjs-integration'; - -@Controller('api') -@UseGuards(AuthGuard) -export class ApiController { - @Get('health') - @Public() - health() { - return { status: 'ok' }; - } -} -``` - -### CurrentUserData Interface - -```typescript -export interface CurrentUserData { - userId: string; // User ID from JWT sub - email: string; // Email from JWT - role: string; // Role: user | admin | service - sessionId?: string; // Session ID (sid or sessionId from JWT) -} -``` - ---- - -## 5. Database Schema (PostgreSQL) - -### Auth Schema (`auth.*`) - -#### users table -```sql -CREATE TABLE auth.users ( - id TEXT PRIMARY KEY, -- nanoid (Better Auth) - name TEXT NOT NULL, - email TEXT UNIQUE NOT NULL, - email_verified BOOLEAN DEFAULT FALSE, - image TEXT, -- Avatar URL - role user_role DEFAULT 'user', -- user | admin | service - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - deleted_at TIMESTAMP WITH TIME ZONE -- Soft delete -); -``` - -#### sessions table -```sql -CREATE TABLE auth.sessions ( - id TEXT PRIMARY KEY, -- nanoid (Better Auth) - user_id TEXT NOT NULL REFERENCES users(id), - token TEXT UNIQUE NOT NULL, -- Session token - refresh_token TEXT UNIQUE, -- Refresh token (rotating) - refresh_token_expires_at TIMESTAMP WITH TIME ZONE, - expires_at TIMESTAMP WITH TIME ZONE NOT NULL, - device_id TEXT, -- Device identifier - device_name TEXT, -- Device name - ip_address TEXT, - user_agent TEXT, - last_activity_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - revoked_at TIMESTAMP WITH TIME ZONE, -- Soft revoke for rotation - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); -``` - -#### accounts table -```sql -CREATE TABLE auth.accounts ( - id TEXT PRIMARY KEY, -- nanoid (Better Auth) - user_id TEXT NOT NULL REFERENCES users(id), - provider_id TEXT NOT NULL, -- 'credential', 'google', etc. - account_id TEXT NOT NULL, - password TEXT, -- Hashed password (for credential) - access_token TEXT, -- OAuth access token - refresh_token TEXT, -- OAuth refresh token - id_token TEXT, - scope TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); -``` - -#### verification table -```sql -CREATE TABLE auth.verification ( - id TEXT PRIMARY KEY, - identifier TEXT NOT NULL, -- Email or other identifier - value TEXT NOT NULL, -- Verification token - expires_at TIMESTAMP WITH TIME ZONE NOT NULL, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - - INDEX verification_identifier_idx (identifier) -); -``` - -#### jwks table (Better Auth JWT Plugin) -```sql -CREATE TABLE auth.jwks ( - id TEXT PRIMARY KEY, - public_key TEXT NOT NULL, -- EdDSA public key (JSON) - private_key TEXT NOT NULL, -- EdDSA private key (encrypted in production) - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); -``` - ---- - -## 6. Environment Variables (Required for All Backends) - -### Mandatory Variables - -```env -# Auth Service -MANA_CORE_AUTH_URL=http://localhost:3001 - -# Node Environment -NODE_ENV=development -``` - -### Development Mode (Optional) - -```env -# Enable auth bypass in development -DEV_BYPASS_AUTH=true - -# Custom test user ID (optional, uses default UUID if not set) -DEV_USER_ID=test-user-12345 -``` - -### For Credit Operations (If Using ManaCoreModule) - -```env -# App identifier -APP_ID=zitare - -# Service key for credit operations -MANA_CORE_SERVICE_KEY=your-service-key -``` - -### JWT Configuration (Should NOT be needed - Better Auth manages this) - -**IMPORTANT:** Do NOT set these variables. Better Auth handles JWKS via the database: - -```env -# DO NOT USE - Better Auth auto-generates EdDSA keys -JWT_PRIVATE_KEY=... -JWT_PUBLIC_KEY=... -JWT_ALGORITHM=... -``` - ---- - -## 7. Login Flow (End-to-End) - -### Step 1: User Registration (POST /api/v1/auth/register) - -**Request:** -```json -{ - "email": "user@example.com", - "password": "securePassword123", - "name": "John Doe" -} -``` - -**Response:** -```json -{ - "user": { - "id": "user-abc123", - "email": "user@example.com", - "name": "John Doe" - }, - "token": "eyJhbGciOiJFZERTQSI..." // Optional session token -} -``` - -### Step 2: User Login (POST /api/v1/auth/login) - -**Request:** -```json -{ - "email": "user@example.com", - "password": "securePassword123", - "deviceId": "device-uuid", // Optional: for multi-device tracking - "deviceName": "iPhone 14" // Optional: for device naming -} -``` - -**Response:** -```json -{ - "user": { - "id": "user-abc123", - "email": "user@example.com", - "name": "John Doe", - "role": "user" - }, - "accessToken": "eyJhbGciOiJFZERTQSI...", // JWT (15 min expiry) - "refreshToken": "nanoid-64-chars...", // Session refresh token (7 day expiry) - "expiresIn": 900, // Seconds (15 min) - "tokenType": "Bearer" -} -``` - -### Step 3: Request Protected Endpoint - -**Request:** -``` -GET /api/favorites HTTP/1.1 -Authorization: Bearer eyJhbGciOiJFZERTQSI... -``` - -**Backend Flow:** -1. Guard intercepts request -2. Extracts token from `Authorization: Bearer ...` header -3. Calls `POST http://localhost:3001/api/v1/auth/validate` with token -4. Receives payload with user claims -5. Attaches user data to request: `request.user = { userId, email, role, sessionId }` -6. Controller receives via `@CurrentUser() user: CurrentUserData` - -### Step 4: Token Refresh (POST /api/v1/auth/refresh) - -When access token expires (15 min), client uses refresh token: - -**Request:** -```json -{ - "refreshToken": "nanoid-64-chars..." -} -``` - -**Response:** -```json -{ - "user": { - "id": "user-abc123", - "email": "user@example.com", - "name": "John Doe", - "role": "user" - }, - "accessToken": "eyJhbGciOiJFZERTQSI...", // New JWT - "refreshToken": "new-nanoid-64-chars...", // New refresh token (rotation) - "expiresIn": 900, - "tokenType": "Bearer" -} -``` - -**Security Note:** Old refresh token is revoked (soft delete via `revokedAt`). Each refresh rotates the token. - ---- - -## 8. Organization (B2B) Flow - -### Register Organization - -**POST /api/v1/auth/register/b2b** - -```json -{ - "ownerEmail": "owner@company.com", - "ownerName": "Jane Smith", - "password": "securePassword123", - "organizationName": "Acme Corp" -} -``` - -**Response:** -```json -{ - "user": { ... }, - "organization": { - "id": "org-xyz789", - "name": "Acme Corp", - "slug": "acme-corp", - "logo": null, - "createdAt": "2024-12-01T10:00:00Z" - }, - "token": "session-token..." -} -``` - -### Invite Employee - -**POST /api/v1/auth/organizations/:id/invite** - -``` -Authorization: Bearer {ownerJWT} - -{ - "employeeEmail": "employee@example.com", - "role": "member" // owner | admin | member -} -``` - -### Accept Invitation - -**POST /api/v1/auth/organizations/accept-invitation** - -``` -Authorization: Bearer {employeeJWT} - -{ - "invitationId": "invitation-123" -} -``` - -### List User's Organizations - -**GET /api/v1/auth/organizations** - -``` -Authorization: Bearer {userJWT} -``` - -**Response:** -```json -{ - "organizations": [ - { - "id": "org-1", - "name": "Acme Corp", - "slug": "acme-corp", - "createdAt": "2024-12-01T10:00:00Z" - } - ] -} -``` - ---- - -## 9. Integration Best Practices - -### For Backend Authors (NestJS) - -#### 1. Choose Your Integration Path - -**Path A: Simple Auth Only** (Use `@manacore/shared-nestjs-auth`) -- For services that don't need credit tracking -- Lighter weight -- Example: Zitare, Picture - -```bash -npm install @manacore/shared-nestjs-auth -``` - -**Path B: Auth + Credits** (Use `@mana-core/nestjs-integration`) -- For services that consume credits -- More complete -- Example: Chat, ManaDeck - -```bash -npm install @mana-core/nestjs-integration -``` - -#### 2. Setup Environment Variables - -Create `.env` file: -```env -NODE_ENV=development -MANA_CORE_AUTH_URL=http://localhost:3001 - -# Development only -DEV_BYPASS_AUTH=true -DEV_USER_ID=test-user-uuid - -# If using ManaCoreModule -APP_ID=your-app-id -MANA_CORE_SERVICE_KEY=your-service-key -``` - -#### 3. Apply Guard Globally - -**For Path A:** -```typescript -// In main.ts -import { JwtAuthGuard } from '@manacore/shared-nestjs-auth'; - -const app = await NestFactory.create(AppModule); -app.useGlobalGuards(new JwtAuthGuard(app.get(ConfigService))); -``` - -**For Path B:** -```typescript -// In main.ts -import { AuthGuard } from '@mana-core/nestjs-integration'; - -const app = await NestFactory.create(AppModule); -app.useGlobalGuards(new AuthGuard(/* options */)); -``` - -#### 4. Use in Controllers - -```typescript -import { CurrentUser, CurrentUserData } from '@manacore/shared-nestjs-auth'; -// OR -import { CurrentUser } from '@mana-core/nestjs-integration'; - -@Controller('api') -@UseGuards(JwtAuthGuard) // Or AuthGuard -export class ApiController { - @Get('me') - getProfile(@CurrentUser() user: CurrentUserData) { - return { - userId: user.userId, - email: user.email, - role: user.role - }; - } - - @Get('health') - @Public() // Skip auth guard if using ManaCoreModule - health() { - return { status: 'ok' }; - } -} -``` - -#### 5. Error Handling - -All auth errors throw `UnauthorizedException`: - -```typescript -import { UnauthorizedException } from '@nestjs/common'; - -try { - // Guard will throw UnauthorizedException if token is invalid -} catch (error) { - if (error instanceof UnauthorizedException) { - return { error: 'Authentication failed', statusCode: 401 }; - } - throw error; -} -``` - -### For Client Authors (Web/Mobile) - -#### Flow: Get Token from mana-core-auth - -1. **Register:** `POST http://localhost:3001/api/v1/auth/register` -2. **Login:** `POST http://localhost:3001/api/v1/auth/login` -3. **Store tokens:** `accessToken` (memory), `refreshToken` (secure storage) -4. **Send with requests:** `Authorization: Bearer {accessToken}` -5. **Refresh when needed:** Use `refreshToken` to get new `accessToken` - -#### Testing Token in Browser - -```javascript -// Get token from login -const response = await fetch('http://localhost:3001/api/v1/auth/login', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - email: 'user@example.com', - password: 'password123' - }) -}); -const { accessToken } = await response.json(); - -// Use in authenticated request -const data = await fetch('http://localhost:3007/api/favorites', { - headers: { - 'Authorization': `Bearer ${accessToken}` - } -}); -``` - ---- - -## 10. Common Issues & Troubleshooting - -### Issue: "No token provided" Error - -**Cause:** Missing or incorrectly formatted Authorization header - -**Solution:** -```typescript -// CORRECT -Authorization: Bearer eyJhbGciOiJFZERTQSI... - -// WRONG - missing Bearer -Authorization: eyJhbGciOiJFZERTQSI... - -// WRONG - using wrong type -Authorization: Token eyJhbGciOiJFZERTQSI... -``` - -### Issue: "Invalid token" Error - -**Likely causes:** -1. Token is expired (15 min expiry) -2. Token is for different issuer/audience -3. Token was tampered with - -**Solution:** -```bash -# Refresh token if expired -POST /api/v1/auth/refresh -{ "refreshToken": "..." } - -# Check token claims -echo $TOKEN | cut -d'.' -f2 | base64 -d | jq '.' -``` - -### Issue: JWKS Fetch Error - -**Cause:** mana-core-auth service not running or wrong URL - -**Solution:** -1. Ensure `MANA_CORE_AUTH_URL` is correct -2. Check mana-core-auth is running: `curl http://localhost:3001/api/v1/auth/jwks` -3. Verify network connectivity between services - -### Issue: Dev Bypass Not Working - -**Cause:** Conditions not met for bypass - -**Solution:** -Bypass only works when ALL conditions are true: -```typescript -if (NODE_ENV === 'development' && DEV_BYPASS_AUTH === 'true') { - // Bypass enabled -} -``` - -Verify: -```bash -echo $NODE_ENV # Must be 'development' -echo $DEV_BYPASS_AUTH # Must be 'true' (string) -``` - ---- - -## 11. Testing & Debugging - -### Manual Token Validation - -```bash -# Get a token -TOKEN=$(curl -s -X POST http://localhost:3001/api/v1/auth/login \ - -H "Content-Type: application/json" \ - -d '{ - "email": "test@example.com", - "password": "password123" - }' | jq -r '.accessToken') - -# Validate it -curl -X POST http://localhost:3001/api/v1/auth/validate \ - -H "Content-Type: application/json" \ - -d "{\"token\": \"$TOKEN\"}" - -# Decode payload (inspect claims) -echo $TOKEN | cut -d'.' -f2 | base64 -d | jq '.' -``` - -### Check JWKS Keys - -```bash -curl http://localhost:3001/api/v1/auth/jwks | jq '.' -``` - -### Inspect Token Details - -```javascript -// In browser console -const token = 'eyJhbGciOiJFZERTQSI...'; -const parts = token.split('.'); -const payload = JSON.parse(atob(parts[1])); -console.log(payload); -``` - ---- - -## 12. Monitoring & Logging - -### Key Log Points to Watch - -1. **Token validation:** Check for repeated validation failures -2. **Refresh token rotation:** Track revoked sessions -3. **JWT signature errors:** Indicates key mismatch -4. **JWKS fetch failures:** Service connectivity issues - -### Health Check Endpoint - -```bash -curl http://localhost:3001/api/v1/auth/session \ - -H "Authorization: Bearer {token}" -``` - -Returns `401` if token is invalid. - ---- - -## 13. Security Considerations - -### JWT Algorithm -- **EdDSA** selected for better performance and security vs RSA -- Public keys stored in `auth.jwks` table -- Private keys managed by Better Auth framework - -### Token Storage (Client-Side) -- **Access Token (JWT):** Memory only (lost on page refresh) -- **Refresh Token:** Secure HTTP-only cookie or encrypted storage - -### Refresh Token Rotation -- Old token revoked immediately when new one issued -- Prevents token replay attacks -- Client must use new token immediately - -### CORS Headers -``` -origin: [http://localhost:3000, http://localhost:8081, ...] -credentials: true -methods: [GET, POST, PUT, DELETE, PATCH, OPTIONS] -allowedHeaders: [Content-Type, Authorization, X-Requested-With, X-App-Id] -``` - ---- - -## 14. Validation Checklist for New Backends - -When adding a new backend service, verify: - -- [ ] Using `@manacore/shared-nestjs-auth` OR `@mana-core/nestjs-integration` -- [ ] `MANA_CORE_AUTH_URL=http://localhost:3001` configured -- [ ] All protected routes use `@UseGuards(JwtAuthGuard)` or `@UseGuards(AuthGuard)` -- [ ] Health/public endpoints marked with `@Public()` decorator (if using ManaCoreModule) -- [ ] User data injected via `@CurrentUser()` decorator -- [ ] Error responses return 401 for auth failures -- [ ] Development mode supports `DEV_BYPASS_AUTH` for testing -- [ ] JWT tokens follow minimal claims pattern -- [ ] No custom JWT signing/verification code -- [ ] CORS configured to allow frontend domains -- [ ] Documentation updated in service's CLAUDE.md - ---- - -## 15. References & Further Reading - -### Key Files in Codebase - -| File | Purpose | -|------|---------| -| `services/mana-core-auth/src/auth/auth.controller.ts` | Main auth endpoints | -| `services/mana-core-auth/src/auth/services/better-auth.service.ts` | Auth business logic | -| `services/mana-core-auth/src/auth/better-auth.config.ts` | Better Auth setup with JWT plugin | -| `packages/shared-nestjs-auth/src/guards/jwt-auth.guard.ts` | Guard for backends | -| `packages/mana-core-nestjs-integration/src/guards/auth.guard.ts` | Extended guard with credits | -| `services/mana-core-auth/src/db/schema/auth.schema.ts` | Database schema | - -### External Resources - -- **Better Auth Docs:** https://www.better-auth.com/docs -- **JWT.io:** https://jwt.io (token decoder) -- **EdDSA:** https://en.wikipedia.org/wiki/EdDSA - ---- - -## Version History - -| Date | Version | Changes | -|------|---------|---------| -| 2024-12-01 | 1.0 | Initial comprehensive report | - ---- - -**Report Status:** APPROVED - This document serves as the source of truth for authentication architecture in Mana Universe. diff --git a/AUTH_DOCUMENTATION_INDEX.md b/AUTH_DOCUMENTATION_INDEX.md deleted file mode 100644 index 3d0edf2ed..000000000 --- a/AUTH_DOCUMENTATION_INDEX.md +++ /dev/null @@ -1,460 +0,0 @@ -# Mana Universe - Authentication Documentation Index - -**Analysis Date:** December 1, 2024 -**Total Documentation:** 4 comprehensive guides -**Total Size:** 52 KB -**Status:** Production Ready - ---- - -## Quick Navigation - -Choose the document that best fits your needs: - -### I need quick answers - -β†’ **AUTH_QUICK_REFERENCE.md** (6.4 KB) - -- Essential endpoints table -- Common curl commands -- Guard patterns -- Token inspection -- Error codes -- 5-minute read - -### I'm implementing auth in a new backend - -β†’ **AUTH_VALIDATION_CHECKLIST.md** (11 KB) - -- Pre-integration checklist -- Implementation steps -- Testing procedures -- Production readiness -- Sign-off form -- Use for approval - -### I need comprehensive details - -β†’ **AUTH_ARCHITECTURE_REPORT.md** (24 KB) - -- Complete 15-section guide -- API routes documented -- JWT format explained -- Database schema -- Integration patterns -- End-to-end flows -- Troubleshooting guide -- Use as reference - -### I need executive summary - -β†’ **AUTH_ANALYSIS_SUMMARY.md** (11 KB) - -- Key findings -- Architecture decisions -- Validation results -- Integration guidance -- Risk assessment -- Use for stakeholders - ---- - -## Document Comparison - -| Aspect | Quick Ref | Checklist | Report | Summary | -| ----------------- | ------------ | ------------ | ------------- | --------- | -| **Audience** | Developers | Implementers | Architects | Managers | -| **Length** | Short | Medium | Comprehensive | Medium | -| **Details** | Minimal | Practical | Complete | Strategic | -| **Use Case** | Daily lookup | Integration | Reference | Overview | -| **Sign-off** | N/A | Yes | N/A | N/A | -| **Code Examples** | Many | Some | Complete | Few | - ---- - -## Key Topics Coverage - -### Core Concepts - -**Covered in:** - -- **Service Architecture** β†’ Report (Section 1) -- **JWT Algorithm** β†’ Report (Section 2), Summary (Finding 2) -- **Token Claims** β†’ Report (Section 2), Quick Ref (Token Structure) -- **Validation Flow** β†’ Report (Section 3), Checklist (JWT section) - -### Implementation - -**Covered in:** - -- **Backend Setup** β†’ Checklist (Implementation), Report (Section 9) -- **Guard Usage** β†’ Quick Ref (Guard Patterns), Report (Section 4) -- **Decorator Patterns** β†’ Report (Section 4), Checklist (Guard Setup) -- **Error Handling** β†’ Report (Section 10), Checklist (Error Handling) - -### Testing & Validation - -**Covered in:** - -- **Manual Testing** β†’ Checklist (Testing section), Quick Ref (Requests) -- **Dev Bypass** β†’ Quick Ref (Development Bypass), Checklist (Testing) -- **Integration Testing** β†’ Checklist (Integration Testing) -- **Unit Tests** β†’ Checklist (Unit Tests section) - -### Security & Operations - -**Covered in:** - -- **Security** β†’ Report (Section 13), Summary (Risk Assessment) -- **Environment Config** β†’ Report (Section 6), Checklist (Env Variables) -- **Troubleshooting** β†’ Report (Section 10), Quick Ref (Troubleshooting) -- **Monitoring** β†’ Report (Section 12) - ---- - -## Implementation Workflow - -### Step 1: Review Architecture (30 min) - -1. Start with **AUTH_QUICK_REFERENCE.md** - understand basics -2. Read **AUTH_ANALYSIS_SUMMARY.md** - understand decisions -3. Skim **AUTH_ARCHITECTURE_REPORT.md** sections 1-4 - -### Step 2: Plan Integration (15 min) - -1. Read **AUTH_VALIDATION_CHECKLIST.md** Pre-Integration section -2. Determine integration path (A or B) -3. Set up environment variables - -### Step 3: Implement (2-3 hours) - -1. Reference **AUTH_ARCHITECTURE_REPORT.md** Section 9 -2. Follow **AUTH_VALIDATION_CHECKLIST.md** Implementation section -3. Use code examples from Quick Reference - -### Step 4: Test (1-2 hours) - -1. Follow **AUTH_VALIDATION_CHECKLIST.md** Testing section -2. Use curl commands from Quick Reference -3. Verify development bypass works - -### Step 5: Validate (30 min) - -1. Complete **AUTH_VALIDATION_CHECKLIST.md** all sections -2. Get code review approval -3. Sign off checklist - ---- - -## File Locations in Monorepo - -### Documentation (At Monorepo Root) - -``` -/ -β”œβ”€β”€ AUTH_DOCUMENTATION_INDEX.md (this file) -β”œβ”€β”€ AUTH_QUICK_REFERENCE.md -β”œβ”€β”€ AUTH_VALIDATION_CHECKLIST.md -β”œβ”€β”€ AUTH_ARCHITECTURE_REPORT.md -└── AUTH_ANALYSIS_SUMMARY.md -``` - -### Source Code (Analyzed) - -``` -services/mana-core-auth/ -β”œβ”€β”€ src/auth/ -β”‚ β”œβ”€β”€ auth.controller.ts -β”‚ β”œβ”€β”€ services/better-auth.service.ts -β”‚ β”œβ”€β”€ better-auth.config.ts -β”‚ └── jwt-validation.spec.ts -β”œβ”€β”€ src/db/schema/ -β”‚ └── auth.schema.ts -└── CLAUDE.md (project guidelines) - -packages/ -β”œβ”€β”€ shared-nestjs-auth/src/guards/jwt-auth.guard.ts -└── mana-core-nestjs-integration/src/guards/auth.guard.ts -``` - ---- - -## Key Findings Summary - -### Central Service - -- **Name:** mana-core-auth -- **Port:** 3001 -- **Framework:** NestJS + Better Auth -- **Algorithm:** EdDSA JWT -- **Database:** PostgreSQL with Drizzle - -### Integration Patterns - -- **Path A:** `@manacore/shared-nestjs-auth` (lightweight) -- **Path B:** `@mana-core/nestjs-integration` (with credits) -- **Pattern:** Centralized validation via `/api/v1/auth/validate` - -### Canonical Design - -- **JWT Claims:** Minimal (sub, email, role, sid only) -- **Token Expiry:** 15 minutes (access), 7 days (refresh) -- **Rotation:** Refresh token rotation + soft delete -- **Guards:** Use `@UseGuards()` decorator -- **Injection:** Use `@CurrentUser()` decorator - -### Environment Setup - -```env -# Required -MANA_CORE_AUTH_URL=http://localhost:3001 - -# Development (optional) -NODE_ENV=development -DEV_BYPASS_AUTH=true -DEV_USER_ID=test-uuid - -# Better Auth manages JWT (DO NOT SET) -# JWT_PRIVATE_KEY=... -# JWT_PUBLIC_KEY=... -``` - ---- - -## Architecture Decisions (Validated) - -1. **Minimal JWT Claims** - - Why: Prevents stale data (credits, org info change frequently) - - Impact: Smaller tokens, better performance - - Evidence: All backends follow pattern - -2. **EdDSA Algorithm** - - Why: Better performance + security than RSA - - Impact: Smaller keys (32 bytes vs 2048+ bits) - - Source: Better Auth framework default - -3. **Centralized Validation** - - Why: Single source of truth, reduces key distribution - - Impact: All backends call `/api/v1/auth/validate` - - Benefit: Easier security updates - -4. **Refresh Token Rotation** - - Why: Prevent token replay attacks - - Impact: Old token revoked on refresh - - Result: Enhanced session security - ---- - -## Common Mistakes (Avoid!) - -1. **Wrong JWT Algorithm** - - WRONG: RS256 or HS256 - - RIGHT: EdDSA (Better Auth default) - -2. **Hardcoded Claims** - - WRONG: Adding org data, credits to JWT - - RIGHT: Fetch via API endpoints - -3. **Missing Guard** - - WRONG: Manual token parsing in controllers - - RIGHT: Use `@UseGuards()` decorator - -4. **Wrong Library** - - WRONG: `import jwt from 'jsonwebtoken'` - - RIGHT: Use `jose` library for verification - -5. **Environment Variable** - - WRONG: Setting JWT_PRIVATE_KEY - - RIGHT: Let Better Auth manage keys - -See **AUTH_ARCHITECTURE_REPORT.md** Section 10 for troubleshooting guide. - ---- - -## Testing Quick Commands - -### Get Token - -```bash -curl -X POST http://localhost:3001/api/v1/auth/login \ - -H "Content-Type: application/json" \ - -d '{"email": "test@example.com", "password": "password123"}' -``` - -### Test Protected Endpoint - -```bash -curl http://localhost:3007/api/favorites \ - -H "Authorization: Bearer $TOKEN" -``` - -### Validate Token - -```bash -curl -X POST http://localhost:3001/api/v1/auth/validate \ - -H "Content-Type: application/json" \ - -d "{\"token\": \"$TOKEN\"}" -``` - -### Decode Token - -```bash -echo $TOKEN | cut -d'.' -f2 | base64 -d | jq '.' -``` - -More commands in **AUTH_QUICK_REFERENCE.md**. - ---- - -## Integration Checklist (TL;DR) - -- [ ] Choose integration path (A or B) -- [ ] Set `MANA_CORE_AUTH_URL=http://localhost:3001` -- [ ] Install package via pnpm -- [ ] Add guard to main.ts -- [ ] Use `@UseGuards()` on controllers -- [ ] Use `@CurrentUser()` in handlers -- [ ] Mark public routes with `@Public()` (Path B) -- [ ] Test with token -- [ ] Enable dev bypass (NODE_ENV=development, DEV_BYPASS_AUTH=true) -- [ ] Complete AUTH_VALIDATION_CHECKLIST.md -- [ ] Get code review -- [ ] Deploy - ---- - -## Support & Resources - -### Documents in This Analysis - -- **Getting started?** β†’ AUTH_QUICK_REFERENCE.md -- **Implementing?** β†’ AUTH_VALIDATION_CHECKLIST.md -- **Deep dive?** β†’ AUTH_ARCHITECTURE_REPORT.md -- **Executive brief?** β†’ AUTH_ANALYSIS_SUMMARY.md - -### External Resources - -- **Better Auth Docs:** https://www.better-auth.com/docs -- **JWT.io:** https://jwt.io (decoder) -- **EdDSA:** https://en.wikipedia.org/wiki/EdDSA - -### Project Resources - -- **Source code:** services/mana-core-auth/ -- **Project guide:** services/mana-core-auth/CLAUDE.md -- **Example backend:** apps/zitare/apps/backend/ - ---- - -## Document Maintenance - -**Last Updated:** December 1, 2024 -**Status:** Production Ready -**Version:** 1.0 - -### When to Update - -- Architecture changes -- New integration patterns discovered -- Breaking changes to API -- Security updates - -### Update Process - -1. Update AUTH_ARCHITECTURE_REPORT.md (source of truth) -2. Update AUTH_VALIDATION_CHECKLIST.md if implementation changes -3. Update AUTH_QUICK_REFERENCE.md if commands change -4. Update this index if structure changes -5. Update AUTH_ANALYSIS_SUMMARY.md with new findings - ---- - -## Approval & Sign-Off - -**Analysis Completed:** December 1, 2024 -**By:** Auth Architecture Specialist -**Status:** APPROVED FOR PRODUCTION USE - -**Next Steps:** - -1. Share documents with development team -2. Reference in PR review process -3. Use checklist for new backend integrations -4. Monitor compliance - -**Questions?** Start with AUTH_QUICK_REFERENCE.md or AUTH_ANALYSIS_SUMMARY.md. - ---- - -## Table of Contents (All Documents) - -### AUTH_QUICK_REFERENCE.md - -1. Core Service -2. Essential Endpoints -3. Backend Integration -4. JWT Token Structure -5. Common Requests -6. Guard Usage Patterns -7. Environment Variables -8. Token Inspection -9. Error Codes -10. Development Bypass -11. Troubleshooting -12. File Locations -13. Related Packages - -### AUTH_VALIDATION_CHECKLIST.md - -1. Pre-Integration Checklist -2. Implementation Checklist -3. API Route Validation -4. JWT Token Validation -5. Database Considerations -6. Testing Checklist -7. Integration Testing -8. Production Readiness -9. Code Review Checklist -10. Common Issues & Fixes -11. Sign-Off - -### AUTH_ARCHITECTURE_REPORT.md - -1. Executive Summary -2. API Route Structure & Versioning -3. JWT Token Format & Structure -4. Validation Flow & JWKS -5. Authentication Guards & Decorators -6. Database Schema -7. Environment Variables -8. Login Flow (E2E) -9. Organization (B2B) Flow -10. Integration Best Practices -11. Common Issues & Troubleshooting -12. Testing & Debugging -13. Monitoring & Logging -14. Security Considerations -15. References & Further Reading - -### AUTH_ANALYSIS_SUMMARY.md - -1. Objective -2. Key Findings -3. Architecture Decisions (Validated) -4. Validation Results -5. Deliverables Created -6. Integration Guidance -7. Common Patterns Identified -8. Risk Assessment -9. Success Criteria -10. Approval & Sign-Off - ---- - -**Master Index Created:** December 1, 2024 -**Total Documentation Pages:** 52 KB -**Sections Documented:** 60+ -**Code Examples:** 40+ -**Checklists:** 8+ - -Navigate to appropriate document and start working! diff --git a/AUTH_QUICK_REFERENCE.md b/AUTH_QUICK_REFERENCE.md deleted file mode 100644 index 6e89d193b..000000000 --- a/AUTH_QUICK_REFERENCE.md +++ /dev/null @@ -1,335 +0,0 @@ -# Mana Core Authentication - Quick Reference Guide - -**Fast lookup guide for common authentication patterns in Mana Universe.** - ---- - -## Core Service - -**Service:** mana-core-auth -**Port:** 3001 -**Prefix:** `/api/v1` -**URL:** `http://localhost:3001/api/v1` - ---- - -## Essential Endpoints - -### Auth Operations - -| Operation | Endpoint | Method | -|-----------|----------|--------| -| Register | `/auth/register` | POST | -| Login | `/auth/login` | POST | -| Logout | `/auth/logout` | POST | -| Refresh | `/auth/refresh` | POST | -| Validate | `/auth/validate` | POST | -| JWKS | `/auth/jwks` | GET | - -### Organization (B2B) - -| Operation | Endpoint | Method | -|-----------|----------|--------| -| Register B2B | `/auth/register/b2b` | POST | -| List Orgs | `/auth/organizations` | GET | -| Get Org | `/auth/organizations/:id` | GET | -| Invite | `/auth/organizations/:id/invite` | POST | -| Accept | `/auth/organizations/accept-invitation` | POST | - ---- - -## Backend Integration - -### Quick Setup (5 minutes) - -#### 1. Install Package -```bash -# Choose ONE: -pnpm add @manacore/shared-nestjs-auth # No credits -pnpm add @mana-core/nestjs-integration # With credits -``` - -#### 2. Add Environment -```env -MANA_CORE_AUTH_URL=http://localhost:3001 -NODE_ENV=development -DEV_BYPASS_AUTH=true -``` - -#### 3. Import Guard (main.ts) -```typescript -import { JwtAuthGuard } from '@manacore/shared-nestjs-auth'; - -const app = await NestFactory.create(AppModule); -app.useGlobalGuards(new JwtAuthGuard(app.get(ConfigService))); -``` - -#### 4. Use Decorator -```typescript -import { CurrentUser, CurrentUserData } from '@manacore/shared-nestjs-auth'; - -@Controller('api') -@UseGuards(JwtAuthGuard) -export class MyController { - @Get('profile') - profile(@CurrentUser() user: CurrentUserData) { - return { userId: user.userId }; - } -} -``` - ---- - -## JWT Token Structure - -### Claims (Minimal) -```json -{ - "sub": "user-id", - "email": "user@example.com", - "role": "user", - "sid": "session-id", - "iat": 1733040000, - "exp": 1733040900, - "iss": "manacore", - "aud": "manacore" -} -``` - -### Header Format -``` -Authorization: Bearer eyJhbGciOiJFZERTQSI... -``` - -### Expiration -- **Access Token:** 15 minutes -- **Refresh Token:** 7 days - ---- - -## Common Requests - -### Register User -```bash -curl -X POST http://localhost:3001/api/v1/auth/register \ - -H "Content-Type: application/json" \ - -d '{ - "email": "user@example.com", - "password": "password123", - "name": "John Doe" - }' -``` - -### Login -```bash -curl -X POST http://localhost:3001/api/v1/auth/login \ - -H "Content-Type: application/json" \ - -d '{ - "email": "user@example.com", - "password": "password123" - }' -``` - -### Use Token -```bash -TOKEN="eyJhbGciOiJFZERTQSI..." -curl http://localhost:3007/api/favorites \ - -H "Authorization: Bearer $TOKEN" -``` - -### Refresh Token -```bash -curl -X POST http://localhost:3001/api/v1/auth/refresh \ - -H "Content-Type: application/json" \ - -d '{"refreshToken": "nanoid-64-chars..."}' -``` - -### Validate Token -```bash -curl -X POST http://localhost:3001/api/v1/auth/validate \ - -H "Content-Type: application/json" \ - -d '{"token": "eyJhbGciOiJFZERTQSI..."}' -``` - ---- - -## Guard Usage Patterns - -### Simple Auth -```typescript -// No credits needed -import { JwtAuthGuard } from '@manacore/shared-nestjs-auth'; - -@UseGuards(JwtAuthGuard) -getProfile(@CurrentUser() user: CurrentUserData) { } -``` - -### With Credits -```typescript -// Credits needed -import { AuthGuard, CreditClientService } from '@mana-core/nestjs-integration'; - -@UseGuards(AuthGuard) -async generate(@CurrentUser() user: any) { - await this.credits.consumeCredits(user.sub, 'generation', 10); -} -``` - -### Public Routes -```typescript -import { Public } from '@mana-core/nestjs-integration'; - -@Get('health') -@Public() -health() { } -``` - ---- - -## Environment Variables - -### All Backends (Required) -```env -MANA_CORE_AUTH_URL=http://localhost:3001 -``` - -### Development (Optional) -```env -NODE_ENV=development -DEV_BYPASS_AUTH=true -DEV_USER_ID=test-user-uuid -``` - -### With Credits (Optional) -```env -APP_ID=zitare -MANA_CORE_SERVICE_KEY=key... -``` - ---- - -## Token Inspection - -### Decode Token -```bash -TOKEN="eyJhbGciOiJFZERTQSI..." -echo $TOKEN | cut -d'.' -f2 | base64 -d | jq '.' -``` - -### Check JWKS -```bash -curl http://localhost:3001/api/v1/auth/jwks | jq '.' -``` - -### Quick Decode (Browser) -```javascript -const payload = JSON.parse(atob(token.split('.')[1])); -console.log(payload); -``` - ---- - -## Error Codes - -| Code | Meaning | Action | -|------|---------|--------| -| 200 | Success | Proceed | -| 400 | Bad Request | Check input format | -| 401 | Unauthorized | Get new token or login | -| 403 | Forbidden | Insufficient permissions | -| 404 | Not Found | Wrong endpoint/resource | -| 409 | Conflict | Email/resource already exists | - ---- - -## Development Bypass - -### Enable (Testing) -```bash -export NODE_ENV=development -export DEV_BYPASS_AUTH=true -export DEV_USER_ID=test-123 -``` - -### Use Without Token -```bash -# Returns mock user - no token required -curl http://localhost:3007/api/profile -``` - -### Disable (Production) -```bash -unset DEV_BYPASS_AUTH -``` - ---- - -## Troubleshooting - -### No Token Error -```typescript -// WRONG -Authorization: eyJhbGciOiJFZERTQSI... - -// RIGHT -Authorization: Bearer eyJhbGciOiJFZERTQSI... -``` - -### Invalid Token -- Token expired? Use refresh endpoint -- Wrong service? Use same MANA_CORE_AUTH_URL -- Tampered? Reject and re-login - -### Validation Fails -```bash -# Check service running -curl http://localhost:3001/api/v1/auth/jwks - -# Check URL -echo $MANA_CORE_AUTH_URL - -# Check env vars -env | grep MANA_CORE -``` - ---- - -## File Locations - -| File | Purpose | -|------|---------| -| `services/mana-core-auth/` | Auth service source | -| `packages/shared-nestjs-auth/` | Lightweight guard | -| `packages/mana-core-nestjs-integration/` | Full integration | -| `AUTH_ARCHITECTURE_REPORT.md` | Detailed patterns | -| `AUTH_VALIDATION_CHECKLIST.md` | Implementation checklist | - ---- - -## Related Packages - -### For Web/Mobile Clients -- `@manacore/shared-auth` - Client auth service - -### For Backends -- `@manacore/shared-nestjs-auth` - Lightweight JWT guard -- `@mana-core/nestjs-integration` - Full integration with credits - -### Utilities -- `@manacore/shared-utils` - Common utilities -- `@manacore/shared-types` - TypeScript types - ---- - -## Useful Links - -- **Better Auth Docs:** https://www.better-auth.com/docs -- **JWT Decoder:** https://jwt.io -- **EdDSA Info:** https://en.wikipedia.org/wiki/EdDSA - ---- - -**Last Updated:** 2024-12-01 -**Status:** Source of Truth - -See `AUTH_ARCHITECTURE_REPORT.md` for comprehensive documentation. diff --git a/AUTH_VALIDATION_CHECKLIST.md b/AUTH_VALIDATION_CHECKLIST.md deleted file mode 100644 index b77ac4956..000000000 --- a/AUTH_VALIDATION_CHECKLIST.md +++ /dev/null @@ -1,434 +0,0 @@ -# Authentication Architecture - Validation Checklist - -This checklist ensures all NestJS backend services implement authentication according to canonical patterns defined in `AUTH_ARCHITECTURE_REPORT.md`. - ---- - -## Pre-Integration Checklist - -Use this before integrating auth into a new backend service. - -### Package Selection - -- [ ] Reviewed `AUTH_ARCHITECTURE_REPORT.md` section 9 (Integration Best Practices) -- [ ] Determined whether service needs credit tracking - - [ ] No credits β†’ Use `@manacore/shared-nestjs-auth` (lightweight) - - [ ] Yes, credits β†’ Use `@mana-core/nestjs-integration` (full-featured) -- [ ] Package dependency documented in `package.json` - -### Environment Variables - -- [ ] `.env` file created with required variables: - - [ ] `MANA_CORE_AUTH_URL=http://localhost:3001` - - [ ] `NODE_ENV=development` (for dev mode) - - [ ] `DEV_BYPASS_AUTH=true` (for testing without token) - - [ ] `DEV_USER_ID=test-user-uuid` (optional, for custom test user) - -- [ ] Verified `.env` is NOT committed to git -- [ ] Verified `.env.example` documents all variables - -### Documentation - -- [ ] Service's `CLAUDE.md` updated with: - - [ ] Auth integration pattern used (Path A or B) - - [ ] Example of `@UseGuards` usage - - [ ] Example of `@CurrentUser()` usage - - [ ] Required environment variables listed - - [ ] Development bypass instructions - ---- - -## Implementation Checklist - -### Guard Setup - -- [ ] Guard imported from correct package: - ```typescript - // Path A only - import { JwtAuthGuard } from '@manacore/shared-nestjs-auth'; - - // Path B only - import { AuthGuard } from '@mana-core/nestjs-integration'; - ``` - -- [ ] Guard applied globally in `main.ts`: - ```typescript - app.useGlobalGuards(new JwtAuthGuard(app.get(ConfigService))); - // OR - app.useGlobalGuards(new AuthGuard(options)); - ``` - -- [ ] Guard applied to protected controllers: - ```typescript - @Controller('api') - @UseGuards(JwtAuthGuard) // or AuthGuard - export class MyController { ... } - ``` - -### Decorator Usage - -- [ ] `@CurrentUser()` imported from correct package: - ```typescript - // Path A - import { CurrentUser, CurrentUserData } from '@manacore/shared-nestjs-auth'; - - // Path B - import { CurrentUser } from '@mana-core/nestjs-integration'; - ``` - -- [ ] Decorator used in protected route handlers: - ```typescript - @Get('profile') - getProfile(@CurrentUser() user: CurrentUserData) { - // user.userId, user.email, user.role, user.sessionId available - } - ``` - -### Public Routes (Path B Only) - -If using `@mana-core/nestjs-integration`: - -- [ ] `@Public()` decorator imported: - ```typescript - import { Public } from '@mana-core/nestjs-integration'; - ``` - -- [ ] Applied to non-protected endpoints: - ```typescript - @Get('health') - @Public() - health() { - return { status: 'ok' }; - } - ``` - -- [ ] Verified all public routes are marked (health check, openapi, etc.) - -### Error Handling - -- [ ] Imported `UnauthorizedException` from `@nestjs/common` -- [ ] Auth errors return 401 status code -- [ ] Error messages don't leak implementation details -- [ ] Example error response: - ```json - { - "statusCode": 401, - "message": "Unauthorized" - } - ``` - ---- - -## API Route Validation - -### Route Naming Convention - -- [ ] All endpoints prefixed with `/api` (NestJS convention) -- [ ] Global prefix set in `main.ts`: βœ— `app.setGlobalPrefix('api/v1');` (This is in mana-core-auth only) - - For other backends: Regular `/api` prefix only -- [ ] Controllers use appropriate path prefixes - -### Protected Routes - -For each protected route, verify: - -- [ ] Decorated with `@UseGuards(JwtAuthGuard)` or `@UseGuards(AuthGuard)` -- [ ] Uses `@CurrentUser()` to extract user data -- [ ] Returns `401 Unauthorized` if token is missing/invalid -- [ ] Doesn't require JWT parsing in handler (guard does it) - -Example: -```typescript -@Controller('api/favorites') -@UseGuards(JwtAuthGuard) -export class FavoriteController { - @Get() - async list(@CurrentUser() user: CurrentUserData) { - return { items: [] }; // user.userId available - } -} -``` - -### Health/Status Routes - -- [ ] Health endpoint does NOT require auth -- [ ] Properly decorated with `@Public()` (if using Path B) -- [ ] Returns `{ status: 'ok' }` or similar - ---- - -## JWT Token Validation - -### Token Format - -- [ ] Tokens received in `Authorization: Bearer {token}` format -- [ ] Guard extracts token correctly using `split(' ')` -- [ ] No custom token parsing in controllers - -### Token Claims - -- [ ] Verified token contains minimal claims only: - - [ ] `sub` (user ID) - - [ ] `email` - - [ ] `role` (user | admin | service) - - [ ] `sid` or `sessionId` (session ID) - -- [ ] Verified token DOES NOT contain: - - [ ] Organization data (fetch via API) - - [ ] Credit balance (fetch via API) - - [ ] Customer type (derive from org presence) - - [ ] Device info (use session data) - -### Validation Endpoint Usage - -- [ ] Guard calls `POST http://localhost:3001/api/v1/auth/validate` -- [ ] Validation is synchronous (guard waits for response) -- [ ] Error handling works when auth service is unreachable - ---- - -## Database Considerations - -### Schema Assumptions - -- [ ] Service assumes `auth.*` schema exists in main database -- [ ] Or uses separate auth database (mana-core-auth default) -- [ ] Database connection URL correctly configured - -### User Data Storage - -- [ ] User IDs stored as TEXT (matching `auth.users.id` type) -- [ ] No re-hashing of passwords (auth service handles) -- [ ] Foreign keys to auth.users use TEXT type: - ```sql - user_id TEXT REFERENCES auth.users(id) - ``` - ---- - -## Testing Checklist - -### Manual Token Testing - -```bash -# 1. Start mana-core-auth service -pnpm dev:auth - -# 2. Register user -curl -X POST http://localhost:3001/api/v1/auth/register \ - -H "Content-Type: application/json" \ - -d '{ - "email": "test@example.com", - "password": "password123", - "name": "Test User" - }' - -# 3. Login to get tokens -TOKEN=$(curl -s -X POST http://localhost:3001/api/v1/auth/login \ - -H "Content-Type: application/json" \ - -d '{ - "email": "test@example.com", - "password": "password123" - }' | jq -r '.accessToken') - -# 4. Test protected endpoint -curl http://localhost:3007/api/favorites \ - -H "Authorization: Bearer $TOKEN" - -# 5. Test without token (should fail) -curl http://localhost:3007/api/favorites -# Should return: 401 Unauthorized -``` - -- [ ] Login returns valid JWT token -- [ ] Protected endpoint accepts valid token -- [ ] Protected endpoint rejects missing token -- [ ] Protected endpoint rejects expired token -- [ ] Token refresh works -- [ ] User data correctly injected via `@CurrentUser()` - -### Development Mode Testing - -- [ ] Set `DEV_BYPASS_AUTH=true` -- [ ] Set `DEV_USER_ID=test-123` (optional) -- [ ] Protected endpoint works WITHOUT token -- [ ] Returns mock user data when DEV_BYPASS_AUTH enabled - -### Unit Tests - -- [ ] Mock `ConfigService` in tests -- [ ] Mock HTTP fetch for token validation -- [ ] Test guard with valid token -- [ ] Test guard with invalid token -- [ ] Test guard with missing token -- [ ] Test `@CurrentUser()` decorator injection - -Example test: -```typescript -it('should attach user to request when token is valid', async () => { - const mockUser = { userId: 'user-123', email: 'test@example.com', role: 'user' }; - const guard = new JwtAuthGuard(mockConfigService); - - const result = await guard.canActivate(mockContext); - - expect(result).toBe(true); - expect(request.user).toEqual(mockUser); -}); -``` - ---- - -## Integration Testing - -### With mana-core-auth Service - -- [ ] Start mana-core-auth on port 3001 -- [ ] Start backend service (e.g., on port 3007) -- [ ] Test real token validation flow -- [ ] Verify JWKS endpoint accessible: `curl http://localhost:3001/api/v1/auth/jwks` -- [ ] Verify validation endpoint accessible: `curl -X POST http://localhost:3001/api/v1/auth/validate` - -### Multi-Service Auth - -If multiple backends run simultaneously: - -- [ ] All backends point to same `MANA_CORE_AUTH_URL` -- [ ] Token from one backend works in another -- [ ] No auth service conflicts on port 3001 -- [ ] JWKS cached or refetched appropriately - ---- - -## Production Readiness - -### Environment Variables - -- [ ] `.env` file NOT committed -- [ ] `.env.example` documents all variables -- [ ] All secrets retrieved from environment (not hardcoded) -- [ ] `NODE_ENV` set to `production` in prod -- [ ] `DEV_BYPASS_AUTH` set to `false` or unset in prod - -### Security - -- [ ] HTTPS used for auth requests (in production) -- [ ] CORS properly configured for frontend domains -- [ ] No auth tokens in logs -- [ ] No user passwords in logs -- [ ] Rate limiting enabled on auth endpoints (mana-core-auth) - -### Monitoring - -- [ ] Logging captures auth failures -- [ ] Metrics track token validation latency -- [ ] Alerts for repeated validation failures -- [ ] JWKS fetch errors monitored - -### Error Messages - -- [ ] Don't reveal implementation details in 401 responses -- [ ] Generic "Unauthorized" message (not "invalid signature" or "token expired") -- [ ] Development logging more verbose than production - ---- - -## Code Review Checklist - -When reviewing auth integration PR: - -- [ ] Uses only canonical guard (`JwtAuthGuard` or `AuthGuard`) -- [ ] No custom JWT parsing or validation code -- [ ] No hardcoded auth URLs (uses ConfigService) -- [ ] No plain-text tokens in logs or responses -- [ ] All protected routes have guard -- [ ] All public routes marked with `@Public()` (if using Path B) -- [ ] `@CurrentUser()` used correctly -- [ ] Error handling appropriate (401 for auth errors) -- [ ] Tests cover auth scenarios -- [ ] Documentation updated - ---- - -## Common Issues & Fixes - -### Issue: "No token provided" on every request - -**Cause:** Guard not applied or incorrectly applied - -**Fix:** -```typescript -// Check main.ts - guard must be global OR per-controller -app.useGlobalGuards(new JwtAuthGuard(app.get(ConfigService))); - -// Verify @UseGuards decorator present -@Controller('api') -@UseGuards(JwtAuthGuard) // Must be here if not global -export class MyController { ... } -``` - -### Issue: `@CurrentUser()` returns undefined - -**Cause:** Guard not running before decorator - -**Fix:** -1. Ensure guard applied to route/controller -2. Ensure guard successfully attaches `request.user` -3. Check guard implementation: - ```typescript - request.user = { userId, email, role, sessionId }; - ``` - -### Issue: Dev bypass not working - -**Cause:** Environment variables not set correctly - -**Fix:** -```bash -# Must be EXACT strings -NODE_ENV=development # NOT 'dev' or 'test' -DEV_BYPASS_AUTH=true # String 'true', not boolean -DEV_USER_ID=test-123 # Optional, any UUID-like string -``` - -### Issue: Token validation always fails - -**Cause:** Wrong `MANA_CORE_AUTH_URL` or service not running - -**Fix:** -```bash -# Verify service running -curl http://localhost:3001/api/v1/auth/jwks - -# Verify config -echo $MANA_CORE_AUTH_URL # Should be http://localhost:3001 - -# Check logs in both services -``` - ---- - -## Sign-Off - -**Service Name:** ___________________________ - -**Backend Port:** ___________________________ - -**Integration Path:** [ ] A: Lightweight Auth [ ] B: Auth + Credits - -**Completed By:** ___________________________ **Date:** ___________________________ - -**Reviewed By:** ___________________________ **Date:** ___________________________ - ---- - -## Approval Checklist - -- [ ] All items in Implementation Checklist verified -- [ ] All items in Testing Checklist verified -- [ ] Code review passed -- [ ] Integration test passed -- [ ] Documentation updated -- [ ] Production-ready configuration verified - -**Auth Architecture Approved:** ___________________________ **Date:** ___________________________ - diff --git a/BACKEND_DESIGN_PATTERN_AUDIT.md b/BACKEND_DESIGN_PATTERN_AUDIT.md deleted file mode 100644 index ace04d16c..000000000 --- a/BACKEND_DESIGN_PATTERN_AUDIT.md +++ /dev/null @@ -1,1066 +0,0 @@ -# Backend Design Pattern Audit Report -## Mana Universe Monorepo - Comprehensive Analysis - -**Audit Date:** 2025-12-01 -**Source of Truth:** mana-core-auth service (port 3001) -**Backends Analyzed:** 5 active NestJS backends -**Total Issues Found:** 18 (3 critical, 8 high, 7 medium) - ---- - -## Executive Summary - -This comprehensive audit evaluated all backend services in the Mana Universe monorepo against the mana-core-auth service as the source of truth for authentication and API design patterns. - -### Key Findings - -βœ… **PASSED**: All backends are functional and compatible with mana-core-auth JWT validation -⚠️ **CRITICAL ISSUES**: 3 blocking issues prevent simultaneous backend execution -πŸ”§ **MAJOR DEVIATIONS**: 8 high-priority inconsistencies require standardization -πŸ“‹ **RECOMMENDATIONS**: 7 medium-priority improvements for code quality - -### Overall Compliance Score: 6.2/10 - -**Score Breakdown:** -- Authentication Integration: 7/10 (functional but fragmented) -- API Route Patterns: 5/10 (inconsistent versioning) -- Environment Configuration: 5/10 (port conflicts, hardcoded values) -- Code Standardization: 6/10 (duplicate implementations) -- Security Posture: 8/10 (validation works, lacks observability) - ---- - -## Table of Contents - -1. [Source of Truth: mana-core-auth Analysis](#source-of-truth) -2. [Backend Comparison Matrix](#backend-matrix) -3. [Critical Issues (Blocking)](#critical-issues) -4. [High-Priority Deviations](#high-priority) -5. [Medium-Priority Improvements](#medium-priority) -6. [Implementation Roadmap](#roadmap) -7. [Detailed Findings by Category](#detailed-findings) -8. [Compliance Checklist](#checklist) - ---- - -## 1. Source of Truth: mana-core-auth Analysis {#source-of-truth} - -### Service Architecture - -**Location:** `/services/mana-core-auth/` -**Port:** 3001 -**Framework:** NestJS 11 + Better Auth -**Algorithm:** EdDSA (NOT RS256 or HS256) -**API Prefix:** `/api/v1` - -### Canonical API Route Structure - -``` -BASE: http://localhost:3001/api/v1 - -Authentication: -POST /api/v1/auth/register -POST /api/v1/auth/login -POST /api/v1/auth/logout -POST /api/v1/auth/validate ← JWT validation endpoint -POST /api/v1/auth/refresh -GET /api/v1/auth/session - -User Management: -GET /api/v1/users/:id -PATCH /api/v1/users/:id -DELETE /api/v1/users/:id -``` - -### JWT Token Structure (EdDSA) - -```json -{ - "sub": "user-id", // User ID (nanoid, not UUID) - "email": "user@example.com", - "role": "user", // Role claim - "sid": "session-id", // Session ID - "exp": 1764606251, // 15 minutes from issue - "iss": "manacore", - "aud": "manacore" -} -``` - -**What's NOT in the token:** -- Organization data (fetch via API) -- Credit balance (fetch via API) -- Customer type (fetch via API) - -### Validation Flow (Source of Truth) - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” Bearer token β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” POST /validate β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Client │─────────────────>β”‚ Backend │───────────────────>β”‚ mana-core-auth β”‚ -β”‚ (Web/Mobile)β”‚ β”‚ (NestJS) β”‚ {token} β”‚ (port 3001) β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β”‚ - β”‚<────────────────────────────────────│ - β”‚ {valid: true, payload: {...}} β”‚ -``` - -### Required Environment Variables - -```bash -# All backends MUST have these -MANA_CORE_AUTH_URL=http://localhost:3001 -NODE_ENV=development|production - -# Optional dev bypass -DEV_BYPASS_AUTH=true -DEV_USER_ID=00000000-0000-0000-0000-000000000000 - -# For credit operations (optional) -MANA_CORE_SERVICE_KEY=your-service-key -APP_ID=your-app-id -``` - -### Integration Patterns (Source of Truth Defines Two Paths) - -**Path A: Lightweight Auth Only** -- Package: `@manacore/shared-nestjs-auth` -- Features: JWT validation, @CurrentUser decorator -- Use when: Simple auth without credit system - -**Path B: Full Integration** -- Package: `@mana-core/nestjs-integration` -- Features: JWT validation + credit client + @Public decorator -- Use when: Need credit consumption tracking - ---- - -## 2. Backend Comparison Matrix {#backend-matrix} - -| Backend | Port | Route Prefix | Versioning | Auth Package | Integration Path | Compliance | -|---------|------|--------------|------------|--------------|-----------------|------------| -| **mana-core-auth** | 3001 | `/api/v1` | v1 | N/A (source) | N/A | 10/10 βœ… | -| **Chat** | 3002 | `/api` | None | Custom (local) | Divergent | 5/10 ⚠️ | -| **Picture** | 3006 | `/api` | None | Custom (local) | Divergent | 4/10 ⚠️ | -| **Zitare** | 3007 | `/api` | None | `@manacore/shared-nestjs-auth` | Path A βœ“ | 7/10 βœ“ | -| **Presi** | 3008 | `/api` | None | Custom (local) | Divergent | 5/10 ⚠️ | -| **ManaDeck** | 8080 | `/v1` | v1 | `@mana-core/nestjs-integration` | Path B βœ“ | 6/10 ⚠️ | - -### Compliance Legend -- 10/10: Perfect alignment with source of truth -- 7-9/10: Good compliance, minor deviations -- 5-6/10: Functional but significant deviations -- 0-4/10: Major issues, requires immediate attention - ---- - -## 3. Critical Issues (Blocking) {#critical-issues} - -### 🚨 CRITICAL #1: Route Prefix Inconsistency - -**Severity:** HIGH (API Contract Violation) -**Status:** ❌ BLOCKING - -**Issue:** ManaDeck uses `/v1` prefix while source of truth uses `/api/v1` - -| Service | Prefix | Status | -|---------|--------|--------| -| mana-core-auth (source) | `/api/v1` | βœ… Standard | -| Chat | `/api` | ⚠️ Missing version | -| Picture | `/api` | ⚠️ Missing version | -| Zitare | `/api` | ⚠️ Missing version | -| Presi | `/api` | ⚠️ Missing version | -| ManaDeck | `/v1` | ❌ Wrong prefix | - -**Impact:** -- Client code must handle 2 different URL patterns -- API documentation is inconsistent -- Future versioning strategy unclear - -**Files Affected:** -``` -apps/chat/apps/backend/src/main.ts:36 -apps/picture/apps/backend/src/main.ts:50 -apps/zitare/apps/backend/src/main.ts:32 -apps/presi/apps/backend/src/main.ts:33 -apps/manadeck/apps/backend/src/main.ts:39 -``` - -**Recommended Fix:** -```typescript -// Option 1: Full compliance with source of truth -app.setGlobalPrefix('api/v1'); - -// Option 2: Consistent api prefix, prepare for versioning -app.setGlobalPrefix('api'); - -// Option 3: Version-first (requires client updates) -app.setGlobalPrefix('v1'); -``` - -**Decision Required:** Choose one standard for all backends - ---- - -### 🚨 CRITICAL #2: Port 3002 Conflict - -**Severity:** HIGH (Development Blocker) -**Status:** ❌ BLOCKING - -**Issue:** Chat and Nutriphi backends both configured for port 3002 - -```bash -# .env.development -CHAT_BACKEND_PORT=3002 ← Conflict -NUTRIPHI_BACKEND_PORT=3002 ← Conflict -``` - -**Impact:** Cannot run both backends simultaneously in development - -**Recommended Fix:** -```bash -# Reassign ports sequentially -CHAT_BACKEND_PORT=3002 # Keep (active project) -NUTRIPHI_BACKEND_PORT=3010 # Move (archived project) -``` - ---- - -### 🚨 CRITICAL #3: Port 3003 Conflict - -**Severity:** HIGH (Development Blocker) -**Status:** ❌ BLOCKING - -**Issue:** Maerchenzauber and Picture backends both configured for port 3003 - -```bash -# .env.development -MAERCHENZAUBER_BACKEND_PORT=3003 ← Conflict -PICTURE_BACKEND_PORT=3003 ← Conflict -``` - -**Additional Issue:** Picture's code defaults to 3003 but docs say 3006 - -```typescript -// apps/picture/apps/backend/src/main.ts:52 -await app.listen(process.env.PORT || 3003); // Says 3003 - -// CLAUDE.md says port 3006 -``` - -**Recommended Fix:** -```bash -# Reassign to match documentation -MAERCHENZAUBER_BACKEND_PORT=3011 # Move (archived) -PICTURE_BACKEND_PORT=3006 # Match docs (active) -``` - -**Code Fix Required:** -```typescript -// apps/picture/apps/backend/src/main.ts:52 -await app.listen(process.env.PORT || 3006); // Fix default -``` - ---- - -## 4. High-Priority Deviations {#high-priority} - -### ⚠️ HIGH #1: Authentication Implementation Fragmentation - -**Severity:** HIGH (Maintainability Issue) -**Status:** ⚠️ NEEDS ATTENTION - -**Issue:** 3 backends use custom local guards instead of shared packages - -| Backend | Current Implementation | Should Use | -|---------|----------------------|------------| -| Chat | Custom `JwtAuthGuard` (local) | `@manacore/shared-nestjs-auth` | -| Picture | Custom `JwtAuthGuard` (local) | `@manacore/shared-nestjs-auth` | -| Presi | Custom `AuthGuard` (local) | `@mana-core/nestjs-integration` | -| Zitare | βœ… `@manacore/shared-nestjs-auth` | βœ… Already correct | -| ManaDeck | βœ… `@mana-core/nestjs-integration` | βœ… Already correct | - -**Files to Replace:** -``` -apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts (58 lines) -apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts (52 lines) -apps/presi/apps/backend/src/auth/auth.guard.ts (47 lines) -``` - -**Problems with Local Implementations:** -1. **Code Duplication:** 157 lines of duplicate guard logic -2. **Inconsistent Behavior:** Chat has dev bypass, Picture doesn't -3. **No Decorators:** Missing `@CurrentUser()`, `@Public()` support -4. **Maintenance Burden:** Bug fixes must be applied 3 times - -**Migration Path:** - -**For Chat & Picture (simple auth):** -```typescript -// Before (local guard) -import { JwtAuthGuard } from './common/guards/jwt-auth.guard'; - -// After (shared package) -import { JwtAuthGuard, CurrentUser, CurrentUserData } from '@manacore/shared-nestjs-auth'; - -@Controller('api') -@UseGuards(JwtAuthGuard) -export class ApiController { - @Get('profile') - getProfile(@CurrentUser() user: CurrentUserData) { - return { userId: user.userId, email: user.email }; - } -} -``` - -**For Presi (needs credits):** -```typescript -// Migrate to full integration -import { AuthGuard } from '@mana-core/nestjs-integration/guards'; -import { CurrentUser } from '@mana-core/nestjs-integration/decorators'; - -@Module({ - imports: [ - ManaCoreModule.forRootAsync({ - useFactory: (config: ConfigService) => ({ - appId: config.get('APP_ID'), - serviceKey: config.get('MANA_CORE_SERVICE_KEY'), - }), - inject: [ConfigService], - }), - ], -}) -``` - ---- - -### ⚠️ HIGH #2: Inconsistent Dev User ID - -**Severity:** HIGH (Development Experience Issue) -**Status:** ⚠️ NEEDS ATTENTION - -**Issue:** Three different dev user IDs across backends - -| Backend/Package | Dev User ID | Source | -|----------------|-------------|--------| -| `@manacore/shared-nestjs-auth` | `00000000-0000-0000-0000-000000000000` | Hardcoded const | -| Chat Backend | `00000000-0000-0000-0000-000000000000` | Hardcoded const | -| Picture Backend | `17cb0be7-058a-4964-9e18-1fe7055fd014` | Hardcoded const | -| `@mana-core/nestjs-integration` | Configurable via `DEV_USER_ID` | βœ… Best practice | - -**Files Affected:** -``` -packages/shared-nestjs-auth/src/guards/jwt-auth.guard.ts:12 -apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts:8 -apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts:7 -``` - -**Impact:** -- Development data inconsistent across backends -- Can't test user-specific features with same ID -- Confusion when switching between backends - -**Recommended Fix:** -```bash -# Add to .env.development -DEV_USER_ID=00000000-0000-0000-0000-000000000000 -``` - -```typescript -// Update all guards to read from config -const devUserId = this.configService.get('DEV_USER_ID') || - '00000000-0000-0000-0000-000000000000'; -``` - ---- - -### ⚠️ HIGH #3: Missing Dev Bypass in Picture Backend - -**Severity:** HIGH (Development Experience Issue) -**Status:** ⚠️ NEEDS ATTENTION - -**Issue:** Picture backend custom guard lacks `DEV_BYPASS_AUTH` support - -**Comparison:** - -```typescript -// Chat backend (HAS dev bypass) -const isDev = this.configService.get('NODE_ENV') === 'development'; -const bypassAuth = this.configService.get('DEV_BYPASS_AUTH') === 'true'; - -if (isDev && bypassAuth) { - request.user = { userId: DEV_USER_ID, ... }; - return true; -} - -// Picture backend (NO dev bypass) -// Missing this feature entirely! -``` - -**Impact:** -- Picture backend always requires valid JWT in development -- Can't test with curl/Postman easily -- Inconsistent dev experience - -**Recommended Fix:** Add dev bypass to Picture guard or migrate to shared package - ---- - -### ⚠️ HIGH #4: Auth URL Variable Naming Inconsistency - -**Severity:** HIGH (Configuration Issue) -**Status:** ⚠️ NEEDS ATTENTION - -**Issue:** Three different environment variable names for auth service URL - -| Backend | Variable Name | Status | -|---------|--------------|--------| -| Chat | `MANA_CORE_AUTH_URL` | βœ… Standard | -| Picture | `MANA_CORE_AUTH_URL` | βœ… Standard | -| Zitare | `MANA_CORE_AUTH_URL` | βœ… Standard | -| Presi | `MANA_CORE_AUTH_URL` | βœ… Standard | -| ManaDeck | `MANA_SERVICE_URL` | ❌ Non-standard | -| Nutriphi | `MANACORE_AUTH_URL` | ❌ Non-standard | - -**Files Affected:** -``` -apps/manadeck/apps/backend/.env.example:3 -scripts/generate-env.mjs (mapping for Nutriphi) -``` - -**Recommended Fix:** Standardize to `MANA_CORE_AUTH_URL` everywhere - ---- - -### ⚠️ HIGH #5: Token Field Naming Divergence - -**Severity:** HIGH (API Contract Issue) -**Status:** ⚠️ NEEDS ATTENTION - -**Issue:** User ID field named differently across implementations - -| Implementation | Field Name | Decorator Returns | -|---------------|------------|-------------------| -| JWT payload (source of truth) | `sub` | N/A | -| `@manacore/shared-nestjs-auth` | `userId` | `CurrentUserData.userId` | -| `@mana-core/nestjs-integration` | `sub` | `JwtPayload.sub` | -| Chat backend | `userId` | `request.user.userId` | -| Picture backend | `userId` | `request.user.userId` | -| Presi backend | `sub` | `request.user.sub` | - -**Problem:** Inconsistent property access across backends - -```typescript -// Zitare (using shared-nestjs-auth) -@CurrentUser() user: CurrentUserData -console.log(user.userId); // Works - -// ManaDeck (using nestjs-integration) -@CurrentUser() user: JwtPayload -console.log(user.sub); // Works -console.log(user.userId); // undefined! -``` - -**Impact:** -- Code is not portable between backends -- Confusion for developers switching projects -- Violates JWT standard (should be `sub`) - -**Recommended Fix:** Standardize on `sub` (JWT standard) with migration alias - -```typescript -export interface CurrentUserData { - sub: string; // JWT standard - userId?: string; // Deprecated alias - email: string; - role: string; - sessionId?: string; -} -``` - ---- - -### ⚠️ HIGH #6: Hardcoded CORS Origins - -**Severity:** MEDIUM-HIGH (Security Configuration Issue) -**Status:** ⚠️ NEEDS ATTENTION - -**Issue:** 4 backends hardcode CORS origins in source code instead of environment - -**Files with Hardcoded CORS:** -```typescript -// apps/chat/apps/backend/src/main.ts:20 -app.enableCors({ - origin: 'http://localhost:5173', // Hardcoded! - credentials: true, -}); - -// apps/picture/apps/backend/src/main.ts:34 -app.enableCors({ - origin: ['http://localhost:5173', 'http://localhost:3000'], // Hardcoded! - credentials: true, -}); - -// apps/zitare/apps/backend/src/main.ts:18 -app.enableCors({ - origin: ['http://localhost:5173'], // Hardcoded! - credentials: true, -}); - -// apps/presi/apps/backend/src/main.ts:19 -app.enableCors({ - origin: ['http://localhost:5173'], // Hardcoded! - credentials: true, -}); -``` - -**Impact:** -- Can't change CORS policy without code changes -- Different environments require separate builds -- Security risk if origins need quick updates - -**Recommended Fix:** -```bash -# .env.development -CORS_ORIGINS=http://localhost:5173,http://localhost:3000 -``` - -```typescript -// main.ts -const corsOrigins = configService.get('CORS_ORIGINS')?.split(',') || - ['http://localhost:5173']; -app.enableCors({ - origin: corsOrigins, - credentials: true, -}); -``` - ---- - -### ⚠️ HIGH #7: Missing Validation Schemas - -**Severity:** MEDIUM-HIGH (Error Handling Issue) -**Status:** ⚠️ NEEDS ATTENTION - -**Issue:** 4 backends lack environment variable validation - -| Backend | Has Validation Schema | Status | -|---------|---------------------|--------| -| mana-core-auth | βœ… YES | Good | -| Chat | ❌ NO | At risk | -| Picture | ❌ NO | At risk | -| Zitare | ❌ NO | At risk | -| Presi | ❌ NO | At risk | -| ManaDeck | βœ… YES | Good | - -**Problem:** Backends start with invalid config and fail at runtime - -**Example Error (Picture backend without MANA_CORE_AUTH_URL):** -``` -Error: MANA_CORE_AUTH_URL is not defined - at JwtAuthGuard.canActivate (jwt-auth.guard.ts:45) - at ExecutionContextHost.switchToHttp (execution-context.ts:34) -``` - -**Recommended Fix:** Add Joi validation to all backends - -```typescript -// app.module.ts -import * as Joi from 'joi'; - -@Module({ - imports: [ - ConfigModule.forRoot({ - validationSchema: Joi.object({ - NODE_ENV: Joi.string().valid('development', 'production').required(), - PORT: Joi.number().default(3000), - MANA_CORE_AUTH_URL: Joi.string().uri().required(), - DEV_BYPASS_AUTH: Joi.boolean().default(false), - DEV_USER_ID: Joi.string().optional(), - }), - }), - ], -}) -``` - ---- - -### ⚠️ HIGH #8: ManaDeck Controller Organization - -**Severity:** MEDIUM (Maintainability Issue) -**Status:** ⚠️ NEEDS REFACTORING - -**Issue:** ManaDeck uses single 971-line controller vs. modular approach - -**Comparison:** - -| Backend | Organization | Largest Controller | Modules | -|---------|--------------|-------------------|---------| -| Chat | Modular | ~150 lines | 6 feature modules | -| Picture | Modular | ~180 lines | 6 feature modules | -| Zitare | Modular | ~100 lines | 2 feature modules | -| Presi | Modular | ~200 lines | 4 feature modules | -| ManaDeck | **Monolithic** | **971 lines** | 1 mega controller | - -**File:** `apps/manadeck/apps/backend/src/controllers/api.controller.ts` - -**Problems:** -- Hard to navigate and understand -- Merge conflicts more likely -- Difficult to test individual features -- Violates single responsibility principle - -**Recommended Refactoring:** -``` -api.controller.ts (971 lines) β†’ - β”œβ”€β”€ deck/deck.controller.ts (~150 lines) - β”œβ”€β”€ card/card.controller.ts (~200 lines) - β”œβ”€β”€ study-session/study-session.controller.ts (~180 lines) - β”œβ”€β”€ progress/progress.controller.ts (~120 lines) - β”œβ”€β”€ ai/ai.controller.ts (~150 lines) - └── category/category.controller.ts (~100 lines) -``` - ---- - -## 5. Medium-Priority Improvements {#medium-priority} - -### πŸ“‹ MEDIUM #1: Missing .env.example Files - -**Issue:** Zitare and Presi lack example environment files - -**Missing:** -- `apps/zitare/apps/backend/.env.example` -- `apps/presi/apps/backend/.env.example` - -**Recommended:** Copy from Chat or Picture backend and adjust - ---- - -### πŸ“‹ MEDIUM #2: Inconsistent Health Check Implementation - -**Issue:** Mix of basic and advanced health checks - -| Backend | Implementation | Endpoints | -|---------|---------------|-----------| -| Chat | Basic | `/health` | -| Picture | Basic | `/health` | -| Zitare | Basic | `/health` | -| Presi | **Terminus** | `/health`, `/health/ready`, `/health/live` | -| ManaDeck | **Terminus** | `/health`, `/health/ready`, `/health/live` | - -**Recommended:** Standardize on Terminus with service dependency checks - ---- - -### πŸ“‹ MEDIUM #3: Missing Public Route Support - -**Issue:** Only `@mana-core/nestjs-integration` provides `@Public()` decorator - -**Workaround in other backends:** -```typescript -// Current: Must exclude routes from global guard -app.setGlobalPrefix('api', { - exclude: ['health', 'webhook'] -}); - -// Better: Use @Public decorator -@Public() -@Get('webhook') -handleWebhook() { } -``` - -**Recommended:** Add `@Public()` decorator to `@manacore/shared-nestjs-auth` - ---- - -### πŸ“‹ MEDIUM #4: No Request Context Logging - -**Issue:** Guards don't log which endpoint failed auth - -**Impact:** Difficult to debug production auth failures - -**Recommended:** -```typescript -if (this.options?.debug || process.env.NODE_ENV === 'development') { - console.log(`[AuthGuard] Validating token for ${request.method} ${request.path}`); -} -``` - ---- - -### πŸ“‹ MEDIUM #5: Missing Circuit Breaker Pattern - -**Issue:** No retry logic or fallback if mana-core-auth is down - -**Current Behavior:** All requests fail immediately if auth service unavailable - -**Recommended:** Implement circuit breaker with short-term token caching - ---- - -### πŸ“‹ MEDIUM #6: Inconsistent Error Response Format - -**Issue:** Different error messages across backends - -```typescript -// Shared package -throw new UnauthorizedException('Invalid token'); - -// Mana Core Integration -throw new UnauthorizedException('Invalid or expired token'); - -// Chat backend -throw new UnauthorizedException('Token validation failed'); -``` - -**Recommended:** Standardize error codes and messages - ---- - -### πŸ“‹ MEDIUM #7: Port 8080 Outlier - -**Issue:** ManaDeck uses port 8080 instead of 3000-series - -**Current Port Allocation:** -``` -3001 - mana-core-auth -3002 - Chat -3006 - Picture (should be) -3007 - Zitare -3008 - Presi -8080 - ManaDeck (outlier) -``` - -**Recommended:** Reassign ManaDeck to 3009 for consistency - ---- - -## 6. Implementation Roadmap {#roadmap} - -### Phase 1: Critical Fixes (2-3 hours) - -**Priority:** MUST DO IMMEDIATELY -**Blocks:** Development, testing, deployment - -**Tasks:** -1. Fix port conflicts (3002, 3003) - - Reassign Nutriphi: 3002 β†’ 3010 - - Reassign Maerchenzauber: 3003 β†’ 3011 - - Fix Picture default: 3003 β†’ 3006 - - Update `.env.development` and `generate-env.mjs` - -2. Standardize route prefixes - - **Decision needed:** Choose `/api`, `/api/v1`, or `/v1` - - Update all `main.ts` files - - Document decision in CLAUDE.md - -3. Add DEV_USER_ID to central config - - Add to `.env.development` - - Update Chat/Picture guards to read from config - -**Validation:** -```bash -# Test: All backends should start simultaneously -pnpm dev:chat:backend & -pnpm dev:picture:backend & -pnpm dev:zitare:backend & -pnpm dev:presi:backend & -pnpm dev:manadeck:backend & - -# Should see no port conflicts -``` - ---- - -### Phase 2: High-Priority Standardization (4-6 hours) - -**Priority:** DO THIS WEEK -**Impact:** Code quality, maintainability, consistency - -**Tasks:** -1. Migrate custom auth guards to shared packages (3-4 hours) - - Chat β†’ `@manacore/shared-nestjs-auth` - - Picture β†’ `@manacore/shared-nestjs-auth` (add dev bypass first) - - Presi β†’ `@mana-core/nestjs-integration` - - Update all controller imports - - Test auth flows - -2. Standardize auth URL variable naming (30 min) - - Rename ManaDeck: `MANA_SERVICE_URL` β†’ `MANA_CORE_AUTH_URL` - - Rename Nutriphi: `MANACORE_AUTH_URL` β†’ `MANA_CORE_AUTH_URL` - - Update `generate-env.mjs` - -3. Extract CORS origins to environment (1 hour) - - Add `CORS_ORIGINS` to `.env.development` - - Update all `main.ts` files - - Test with different origins - -4. Standardize token field naming (1-2 hours) - - Add `sub` field to shared auth types - - Keep `userId` as deprecated alias - - Update documentation - -**Validation:** -```bash -# Test: Auth should work identically across backends -TOKEN=$(curl -X POST http://localhost:3001/api/v1/auth/login \ - -d '{"email":"test@example.com","password":"password"}' | jq -r '.accessToken') - -for PORT in 3002 3006 3007 3008 3009; do - curl http://localhost:$PORT/api/health -H "Authorization: Bearer $TOKEN" -done -``` - ---- - -### Phase 3: Code Quality Improvements (6-8 hours) - -**Priority:** PLAN THIS WEEK, EXECUTE NEXT WEEK -**Impact:** Error handling, observability, maintainability - -**Tasks:** -1. Add validation schemas to 4 backends (2 hours) - - Chat, Picture, Zitare, Presi - - Copy from mana-core-auth or ManaDeck - - Test with missing/invalid env vars - -2. Refactor ManaDeck controller (3-4 hours) - - Break into feature modules - - Update app.module.ts - - Test all endpoints - -3. Standardize health checks (1-2 hours) - - Add Terminus to Chat, Picture, Zitare - - Implement readiness/liveness probes - - Add dependency checks - -4. Create missing .env.example files (30 min) - - Zitare backend - - Presi backend - -5. Add @Public decorator support (1 hour) - - Update `@manacore/shared-nestjs-auth` - - Test webhook/public endpoints - -**Validation:** -```bash -# Test: All backends should fail fast with clear errors -unset MANA_CORE_AUTH_URL -pnpm dev:chat:backend -# Should see: "Configuration validation error: MANA_CORE_AUTH_URL is required" -``` - ---- - -### Phase 4: Observability & Security (4-6 hours) - -**Priority:** FUTURE SPRINT -**Impact:** Production readiness, debugging, security - -**Tasks:** -1. Add request context logging (1 hour) -2. Implement circuit breaker for auth service (2-3 hours) -3. Standardize error response format (1-2 hours) -4. Add auth flow integration tests (2-3 hours) - ---- - -## 7. Detailed Findings by Category {#detailed-findings} - -### Category A: API Route Structure - -**Source of Truth Standard:** `/api/v1/[resource]` - -**Findings:** -- βœ… mana-core-auth: `/api/v1` (perfect) -- ⚠️ Chat: `/api` (missing version) -- ⚠️ Picture: `/api` (missing version) -- ⚠️ Zitare: `/api` (missing version) -- ⚠️ Presi: `/api` (missing version) -- ❌ ManaDeck: `/v1` (wrong prefix) - -**Recommendation:** Adopt `/api/v1` across all backends for future-proof versioning - ---- - -### Category B: JWT Integration - -**Source of Truth Standard:** POST `/api/v1/auth/validate` with Bearer token - -**Findings:** -- βœ… All backends call correct validation endpoint -- βœ… All backends extract Bearer tokens correctly -- βœ… All backends handle EdDSA JWT algorithm -- ⚠️ Token field naming inconsistent (userId vs sub) -- ⚠️ Dev bypass implementation varies -- ⚠️ Error handling not standardized - -**Recommendation:** Validation flow is correct; standardize field names and errors - ---- - -### Category C: Authentication Guards - -**Source of Truth Standard:** Use shared packages with standard decorators - -**Findings:** -- βœ… Zitare uses `@manacore/shared-nestjs-auth` (good) -- βœ… ManaDeck uses `@mana-core/nestjs-integration` (good) -- ❌ Chat uses custom local guard (duplication) -- ❌ Picture uses custom local guard (duplication) -- ❌ Presi uses custom local guard (duplication) -- ⚠️ 157 lines of duplicate guard code across 3 backends - -**Recommendation:** Eliminate custom guards; migrate to shared packages - ---- - -### Category D: Environment Configuration - -**Source of Truth Standard:** Centralized .env.development with consistent naming - -**Findings:** -- βœ… Centralized .env.development exists -- βœ… Port allocation documented -- ❌ Port conflicts: 3002 (2 backends), 3003 (2 backends) -- ⚠️ Auth URL naming: 3 different variable names -- ⚠️ CORS origins hardcoded in 4 backends -- ⚠️ Missing validation schemas in 4 backends - -**Recommendation:** Fix port conflicts, standardize variable names, add validation - ---- - -### Category E: Code Organization - -**Source of Truth Standard:** Feature-based modular structure - -**Findings:** -- βœ… Chat: Modular (6 feature modules) -- βœ… Picture: Modular (6 feature modules) -- βœ… Zitare: Modular (2 feature modules) -- βœ… Presi: Modular (4 feature modules) -- ❌ ManaDeck: Monolithic (1 controller, 971 lines) - -**Recommendation:** Refactor ManaDeck to feature-based modules - ---- - -## 8. Compliance Checklist {#checklist} - -### API Design Compliance - -- [ ] All backends use same route prefix pattern -- [ ] Versioning strategy documented and consistent -- [ ] Health check endpoints standardized -- [ ] Error response format consistent - -### Authentication Compliance - -- [x] All backends call correct validation endpoint -- [x] All backends support Bearer token extraction -- [ ] All backends use shared auth packages (3/5) -- [ ] Token field naming standardized -- [ ] Dev bypass implemented consistently (3/5) -- [ ] @CurrentUser decorator available everywhere -- [ ] @Public decorator supported for public routes - -### Environment Configuration Compliance - -- [ ] No port conflicts -- [ ] Auth URL variable naming standardized -- [ ] Dev user ID centralized -- [ ] CORS origins configurable -- [ ] Environment validation schemas implemented -- [ ] .env.example files present - -### Code Quality Compliance - -- [ ] No duplicate guard implementations -- [ ] Feature-based modular structure -- [ ] Request context logging -- [ ] Circuit breaker for auth service -- [ ] Integration tests for auth flows - -### Security Compliance - -- [x] JWT validation via central service -- [x] EdDSA algorithm support -- [ ] Error messages don't leak sensitive info -- [ ] Dev bypass requires explicit flag -- [ ] Production config validation -- [ ] CORS properly configured per environment - ---- - -## Appendix: Supporting Documentation - -### Generated Reports - -All detailed findings are available in these reports: - -1. **AUTH_ARCHITECTURE_REPORT.md** (24 KB) - - Complete mana-core-auth analysis - - JWT token structure - - Validation flow - - Integration patterns - -2. **JWT_VALIDATION_REPORT.md** (18 KB) - - Backend-by-backend JWT integration analysis - - Guard implementation comparison - - Dev user ID issues - -3. **ENV_CONFIGURATION_AUDIT.md** (12 KB) - - Environment variable matrix - - Port conflicts - - Configuration issues - -4. **ENV_BACKEND_MATRIX.md** (8 KB) - - Visual configuration comparison - - Missing variables - - Standardization needs - -### File Paths Reference - -**Source of Truth:** -- `/services/mana-core-auth/` (entire service) -- `/services/mana-core-auth/src/auth/auth.controller.ts:36` (validation endpoint) - -**Shared Packages:** -- `/packages/shared-nestjs-auth/src/guards/jwt-auth.guard.ts` -- `/packages/nestjs-integration/src/guards/auth.guard.ts` - -**Backend Guards:** -- `/apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts` -- `/apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts` -- `/apps/presi/apps/backend/src/auth/auth.guard.ts` - -**Configuration Files:** -- `/.env.development` (central config) -- `/scripts/generate-env.mjs` (env generation) - ---- - -## Summary - -This comprehensive audit identified **18 issues** across 5 backends: -- **3 critical** (blocking development) -- **8 high-priority** (requiring immediate attention) -- **7 medium-priority** (code quality improvements) - -**Estimated effort to reach 9/10 compliance:** 16-23 hours across 4 phases - -**Current state:** All backends are functional but lack standardization -**Target state:** Consistent patterns, shared packages, zero duplication -**Risk level:** MEDIUM (functional but fragile, maintenance burden) - -**Next Steps:** -1. Review and approve this audit -2. Prioritize Phase 1 critical fixes -3. Schedule Phase 2 migration work -4. Plan Phase 3 code quality improvements - ---- - -**Audit completed by:** Claude Flow Swarm (5 specialized agents) -**Documentation generated:** 7 comprehensive reports -**Total analysis:** 2,604 lines of findings across 68 KB of documentation diff --git a/COMMANDS.md b/COMMANDS.md deleted file mode 100644 index 3a45ed9ba..000000000 --- a/COMMANDS.md +++ /dev/null @@ -1,492 +0,0 @@ -# Manacore Monorepo - Befehle - -# Alles starten (PostgreSQL, Redis, Auth, Chat) - -pnpm docker:up:all - -pnpm docker:down - -pnpm dev:chat:full -pnpm dev:picture:full -pnpm dev:calendar:full -pnpm dev:contacts:full -pnpm dev:todo:full -pnpm dev:presi:full -pnpm dev:storage:full -pnpm dev:skilltree:full -pnpm dev:questions:full - -pnpm dev:manacore:app # Nur ManaCore Web -pnpm dev:manacore:backends # Alle 7 Backends fΓΌr Dashboard-Widgets -pnpm dev:manacore:full # Web + alle Backends (empfohlen) - -# Deployment Landingpages: - -## Einzelne Landing Page - -pnpm deploy:landing:chat -pnpm deploy:landing:picture -pnpm deploy:landing:manacore -pnpm deploy:landing:manadeck - -Hier sind alle Landing Page URLs: - -| Projekt | URL | -| -------- | ---------------------------------- | -| Chat | https://chat-landing-90m.pages.dev | -| Picture | https://picture-landing.pages.dev | -| ManaCore | https://manacore-landing.pages.dev | -| ManaDeck | https://manadeck-landing.pages.dev | - -## Alle auf einmal - -pnpm deploy:landing:all - -Übersicht aller wichtigen Befehle zum Starten, Stoppen und Verwalten der Apps. - -## Inhaltsverzeichnis - -- [Voraussetzungen](#voraussetzungen) -- [Docker & Infrastruktur](#docker--infrastruktur) -- [Mana Core Auth](#mana-core-auth) -- [Chat](#chat) -- [Picture](#picture) -- [Manadeck](#manadeck) -- [SkillTree](#skilltree) -- [Questions](#questions) -- [Mana Search](#mana-search) -- [Manacore](#manacore) -- [Mana Games](#mana-games) -- [Allgemeine Befehle](#allgemeine-befehle) -- [Stoppen & AufrΓ€umen](#stoppen--aufrΓ€umen) - ---- - -## Voraussetzungen - -```bash -# Dependencies installieren (generiert auch .env Dateien) -pnpm install - -# Nur .env Dateien neu generieren -pnpm setup:env - -# Shared Packages bauen -pnpm build:packages -``` - ---- - -## Docker & Infrastruktur - -### Starten - -```bash -# Nur PostgreSQL + Redis (Basis-Infrastruktur) -pnpm docker:up - -# Mit Mana Core Auth Service -pnpm docker:up:auth - -# Mit Chat Backend -pnpm docker:up:chat - -# Alles starten (PostgreSQL, Redis, Auth, Chat) -pnpm docker:up:all -``` - -### Status & Logs - -```bash -# Container-Status anzeigen -pnpm docker:ps - -# Alle Logs anzeigen (live) -pnpm docker:logs - -# Nur Auth-Logs -pnpm docker:logs:auth - -# Nur Chat-Logs -pnpm docker:logs:chat -``` - -### Stoppen - -```bash -# Alle Container stoppen -pnpm docker:down - -# Stoppen + Volumes lΓΆschen (Datenbank-Reset!) -pnpm docker:clean -``` - ---- - -## Mana Core Auth - -Der zentrale Authentifizierungs-Service (Port 3001). - -```bash -# Im Docker starten (empfohlen) -pnpm docker:up:auth - -# Oder lokal starten -cd services/mana-core-auth -pnpm start:dev - -# Datenbank-Migration -cd services/mana-core-auth -pnpm migration:generate # Migration erstellen -pnpm migration:run # Migration ausfΓΌhren -pnpm db:push # Schema direkt pushen (dev) -pnpm db:studio # Drizzle Studio ΓΆffnen -``` - ---- - -## Chat - -| App | Port | Befehl | -| ------- | ---- | ----------------------- | -| Web | 5174 | `pnpm dev:chat:web` | -| Backend | 3002 | `pnpm dev:chat:backend` | -| Mobile | 8081 | `pnpm dev:chat:mobile` | -| Landing | - | `pnpm dev:chat:landing` | - -```bash -# Web + Backend zusammen starten -pnpm dev:chat:app - -# Alles (Web, Backend, Mobile, Landing) -pnpm chat:dev -``` - ---- - -## Picture - -| App | Port | Befehl | -| ------- | ---- | -------------------------- | -| Web | 5173 | `pnpm dev:picture:web` | -| Backend | - | `pnpm dev:picture:backend` | -| Mobile | 8081 | `pnpm dev:picture:mobile` | -| Landing | - | `pnpm dev:picture:landing` | - -```bash -# Web + Backend zusammen starten -pnpm dev:picture:app - -# Alles -pnpm picture:dev -``` - ---- - -## Manadeck - -| App | Port | Befehl | -| ------- | ---- | --------------------------- | -| Web | - | `pnpm dev:manadeck:web` | -| Backend | - | `pnpm dev:manadeck:backend` | -| Mobile | 8081 | `pnpm dev:manadeck:mobile` | -| Landing | - | `pnpm dev:manadeck:landing` | - -```bash -# Web + Backend zusammen starten -pnpm dev:manadeck:app - -# Alles -pnpm manadeck:dev -``` - ---- - -## SkillTree - -Gamified Skill-Tracking App - wie ein RPG Skill Tree fΓΌr echte FΓ€higkeiten. - -| App | Port | Befehl | -| ------- | ---- | ---------------------------- | -| Web | 5195 | `pnpm dev:skilltree:web` | -| Backend | 3024 | `pnpm dev:skilltree:backend` | - -```bash -# Web + Backend zusammen starten -pnpm dev:skilltree:app - -# Mit Auth + automatischem DB-Setup (empfohlen) -pnpm dev:skilltree:full - -# Datenbank -pnpm skilltree:db:push # Schema pushen -pnpm skilltree:db:studio # Drizzle Studio -``` - ---- - -## Questions - -AI-powered Research Assistant - sammelt Fragen und fΓΌhrt Web-Recherche durch. - -| App | Port | Befehl | -| ------- | ---- | ---------------------------- | -| Web | 5111 | `pnpm dev:questions:web` | -| Backend | 3011 | `pnpm dev:questions:backend` | - -```bash -# Web + Backend zusammen starten -pnpm dev:questions:app - -# Mit Auth + Search Service + automatischem DB-Setup (empfohlen) -pnpm dev:questions:full - -# Datenbank -cd apps/questions/apps/backend -pnpm drizzle-kit push # Schema pushen -pnpm drizzle-kit studio # Drizzle Studio -``` - -**Hinweis:** Questions benΓΆtigt den mana-search Service fΓΌr Web-Recherche. - ---- - -## Mana Search - -Zentraler Such-Microservice mit SearXNG fΓΌr Web-Suche und Content-Extraktion. - -| Service | Port | Befehl | -| ------- | ---- | ----------------- | -| API | 3021 | `pnpm dev:search` | -| SearXNG | 8080 | (Docker) | -| Redis | 6380 | (Docker) | - -```bash -# SearXNG + Redis in Docker starten -pnpm dev:search:docker - -# NestJS API starten -pnpm dev:search - -# Beides zusammen (empfohlen) -pnpm dev:search:full - -# Docker stoppen -pnpm dev:search:docker:down - -# Logs anzeigen -pnpm dev:search:docker:logs -``` - -### API testen - -```bash -# Health Check -curl http://localhost:3021/api/v1/health - -# Web-Suche -curl -X POST http://localhost:3021/api/v1/search \ - -H "Content-Type: application/json" \ - -d '{"query": "TypeScript tutorial", "options": {"limit": 5}}' - -# Content extrahieren -curl -X POST http://localhost:3021/api/v1/extract \ - -H "Content-Type: application/json" \ - -d '{"url": "https://example.com", "options": {"includeMarkdown": true}}' -``` - ---- - -## Manacore - -| App | Port | Befehl | -| -------- | ---- | ---------------------------- | -| Web | 5173 | `pnpm dev:manacore:web` | -| Mobile | 8081 | `pnpm dev:manacore:mobile` | -| Landing | - | `pnpm dev:manacore:landing` | -| Backends | - | `pnpm dev:manacore:backends` | - -```bash -# Nur ManaCore Web -pnpm dev:manacore:app - -# Alle Backends fΓΌr Dashboard-Widgets starten (7 Services parallel) -# Startet: auth, chat, calendar, contacts, todo, picture, manadeck -pnpm dev:manacore:backends - -# ManaCore Web + alle Backends zusammen (empfohlen fΓΌr Dashboard-Entwicklung) -pnpm dev:manacore:full - -# Alles inkl. Mobile -pnpm manacore:dev -``` - -### Dashboard-Backends Übersicht - -Die Dashboard-Widgets benΓΆtigen diese Backend-Services: - -| Widget | Backend | Port | -| -------------------- | -------- | ---- | -| Credits | auth | 3001 | -| Chat Recent | chat | 3002 | -| Calendar Events | calendar | 3014 | -| Contacts Favorites | contacts | 3015 | -| Tasks Today/Upcoming | todo | 3018 | -| Picture Recent | picture | 3006 | -| Manadeck Progress | manadeck | 3009 | - ---- - -## Mana Games - -```bash -# Web + Backend zusammen starten -pnpm dev:mana-games:app - -# Einzeln -pnpm dev:mana-games:web -pnpm dev:mana-games:backend - -# Alles -pnpm mana-games:dev -``` - ---- - -## Allgemeine Befehle - -```bash -# Alles bauen -pnpm build - -# Type-Check -pnpm type-check - -# Linting -pnpm lint - -# Formatierung -pnpm format # Formatieren -pnpm format:check # Nur prΓΌfen - -# Tests -pnpm test - -# Cache leeren -pnpm clean -``` - ---- - -## Stoppen & AufrΓ€umen - -### Prozesse stoppen - -```bash -# Alle Node-Prozesse beenden (macOS/Linux) -pkill -f "node" - -# Spezifischen Port freigeben -lsof -ti:3001 | xargs kill -9 # Port 3001 (Auth) -lsof -ti:3002 | xargs kill -9 # Port 3002 (Chat Backend) -lsof -ti:5174 | xargs kill -9 # Port 5174 (Chat Web) - -# Turbo Cache leeren -pnpm clean -``` - -### Docker stoppen - -```bash -# Container stoppen (Daten bleiben) -pnpm docker:down - -# Container + Volumes lΓΆschen (Datenbank-Reset!) -pnpm docker:clean -``` - -### Komplettes Cleanup - -```bash -# Alles stoppen und aufrΓ€umen -pnpm docker:down -pkill -f "node" -pnpm clean -rm -rf node_modules/.cache -``` - ---- - -## Typische Workflows - -### Chat-Entwicklung starten - -```bash -# 1. Infrastruktur starten -pnpm docker:up - -# 2. Auth-Service starten (neues Terminal) -cd services/mana-core-auth && pnpm start:dev - -# 3. Chat App starten (neues Terminal) -pnpm dev:chat:app -``` - -### Alles mit Docker - -```bash -# Alles in Docker starten -pnpm docker:up:all - -# Nur Frontend lokal -pnpm dev:chat:web -``` - -### Nach Code-Γ„nderungen in Shared Packages - -```bash -# Packages neu bauen -pnpm build:packages - -# Oder spezifisches Package -pnpm --filter @manacore/shared-ui build -``` - ---- - -## App-Übersicht - -### Aktive Apps (apps/) - 12 Apps - -- **calendar** - Kalender-App fΓΌr persΓΆnliches und geteiltes Zeitmanagement mit wiederkehrenden Terminen, CalDAV/iCal-Sync und Erinnerungen -- **chat** - KI-Chat-Anwendung mit verschiedenen KI-Modellen und Konversationsverlauf -- **contacts** - Kontaktverwaltung mit Import/Export und Google-Synchronisation -- **context** - AI document context (Expo mobile only) -- **manacore** - Multi-App Ecosystem Platform - zentrales Dashboard fΓΌr alle Mana-Apps -- **manadeck** - Karteikarten-/Lernkarten-Management fΓΌr Spaced Repetition Learning -- **nutriphi** - Nutrition tracking (geplant, noch kein Backend) -- **picture** - KI-Bildgenerierung mit verschiedenen Modellen und Galerie-Verwaltung -- **questions** - AI-powered Research Assistant mit Web-Recherche ΓΌber mana-search -- **skilltree** - Gamified Skill-Tracking mit XP-System, Leveln und 6 Skill-Branches -- **storage** - Cloud storage (geplant, noch kein Backend) -- **todo** - Task-Management mit Projekten, Subtasks, Labels und wiederkehrenden Aufgaben - -### Games (games/) - 5 Games - -- **figgos** - Collectible Figure Game mit KI-generierten Fantasy-Figuren zum Sammeln -- **mana-games** - Browser-Spieleplatform mit 22+ Spielen und KI-Spielgenerierung -- **voxel-lava** - 3D Voxel Building & Platforming Game mit Level-Editor und Sharing -- **whopixels** - Pixel-Art-Editor-Spiel mit Phaser.js -- **worldream** - Text-first World-Building-Plattform fΓΌr fiktive Welten mit @slug-Referenzen - -### Services (services/) - 2 Services - -- **mana-core-auth** - Zentraler Authentifizierungs-Service fΓΌr alle Apps (Better Auth + EdDSA JWT) -- **mana-search** - Zentraler Such-Service mit SearXNG fΓΌr Web-Suche und Content-Extraktion (Port 3021) - -### Shared Packages (packages/) - 4 Kern-Packages - -shared-ui - Gemeinsame UI-Komponenten fΓΌr alle Web-Apps -shared-auth - Client-seitige Auth-Integration fΓΌr Web/Mobile -shared-nestjs-auth - NestJS Guards/Decorators fΓΌr JWT-Validierung -shared-storage - S3-kompatible Storage-Abstraktion (MinIO) diff --git a/COMPATIBILITY_MATRIX_AND_REMEDIATION.md b/COMPATIBILITY_MATRIX_AND_REMEDIATION.md deleted file mode 100644 index b111ada84..000000000 --- a/COMPATIBILITY_MATRIX_AND_REMEDIATION.md +++ /dev/null @@ -1,1144 +0,0 @@ -# Backend Compatibility Matrix & Remediation Plan -## Mana Universe Monorepo - -**Date:** 2025-12-01 -**Source of Truth:** mana-core-auth (port 3001, `/api/v1`) -**Status:** ⚠️ FUNCTIONAL BUT NEEDS STANDARDIZATION - ---- - -## Quick Reference Compatibility Matrix - -| Feature | mana-core-auth | Chat | Picture | Zitare | Presi | ManaDeck | Status | -|---------|---------------|------|---------|--------|-------|----------|--------| -| **Route Prefix** | `/api/v1` βœ… | `/api` ⚠️ | `/api` ⚠️ | `/api` ⚠️ | `/api` ⚠️ | `/v1` ❌ | INCONSISTENT | -| **Port** | 3001 βœ… | 3002 ⚠️ | 3006 βœ… | 3007 βœ… | 3008 βœ… | 8080 ⚠️ | CONFLICTS | -| **Auth Package** | N/A | Custom ❌ | Custom ❌ | Shared βœ… | Custom ❌ | Integration βœ… | FRAGMENTED | -| **JWT Validation** | Source βœ… | Works βœ… | Works βœ… | Works βœ… | Works βœ… | Works βœ… | COMPATIBLE | -| **Field Naming** | `sub` βœ… | `userId` ⚠️ | `userId` ⚠️ | `userId` ⚠️ | `sub` βœ… | `sub` βœ… | MIXED | -| **Dev Bypass** | N/A | Yes βœ… | No ❌ | Yes βœ… | Yes βœ… | Yes βœ… | MISSING (1) | -| **Dev User ID** | N/A | `000...` βœ… | Custom ❌ | `000...` βœ… | N/A | Config βœ… | INCONSISTENT | -| **@CurrentUser** | N/A | No ❌ | No ❌ | Yes βœ… | No ❌ | Yes βœ… | MISSING (3) | -| **@Public** | N/A | No ❌ | No ❌ | No ❌ | No ❌ | Yes βœ… | MISSING (4) | -| **Env Validation** | Yes βœ… | No ❌ | No ❌ | No ❌ | No ❌ | Yes βœ… | MISSING (4) | -| **Health Checks** | Advanced βœ… | Basic ⚠️ | Basic ⚠️ | Basic ⚠️ | Terminus βœ… | Terminus βœ… | MIXED | -| **CORS Config** | Config βœ… | Hardcoded ❌ | Hardcoded ❌ | Hardcoded ❌ | Hardcoded ❌ | Hardcoded ❌ | HARDCODED (5) | - -### Legend -- βœ… Fully compliant with source of truth -- ⚠️ Works but deviates from standard -- ❌ Missing or incompatible - ---- - -## Detailed Feature Comparison - -### 1. API Route Structure - -| Backend | Current Prefix | Current Version | Target Prefix | Migration Effort | -|---------|---------------|----------------|---------------|-----------------| -| mana-core-auth | `/api/v1` | v1 | N/A (source) | N/A | -| Chat | `/api` | None | `/api/v1` | 5 min | -| Picture | `/api` | None | `/api/v1` | 5 min | -| Zitare | `/api` | None | `/api/v1` | 5 min | -| Presi | `/api` | None | `/api/v1` | 5 min | -| ManaDeck | `/v1` | v1 | `/api/v1` | 10 min + client updates | - -**Compatibility:** ⚠️ PARTIAL - All backends reachable but inconsistent client URLs - ---- - -### 2. Port Allocation - -| Backend | Current Port | Has Conflict | Target Port | Migration Effort | -|---------|-------------|--------------|-------------|-----------------| -| mana-core-auth | 3001 | No | 3001 | N/A | -| Chat | 3002 | **Yes** (Nutriphi) | 3002 | Move Nutriphi to 3010 | -| Picture | 3006 | **Yes** (Maerchenzauber) | 3006 | Move Maerchenzauber to 3011 | -| Zitare | 3007 | No | 3007 | N/A | -| Presi | 3008 | No | 3008 | N/A | -| ManaDeck | 8080 | No | 3009 | 5 min | - -**Compatibility:** ❌ BLOCKED - Cannot run all backends simultaneously - ---- - -### 3. Authentication Implementation - -| Backend | Current Guard | Package Location | Target Package | Migration Effort | -|---------|--------------|-----------------|----------------|-----------------| -| mana-core-auth | N/A | N/A | N/A | N/A | -| Chat | `JwtAuthGuard` | Local (58 lines) | `@manacore/shared-nestjs-auth` | 30 min | -| Picture | `JwtAuthGuard` | Local (52 lines) | `@manacore/shared-nestjs-auth` | 30 min | -| Zitare | `JwtAuthGuard` | `@manacore/shared-nestjs-auth` | No change | N/A | -| Presi | `AuthGuard` | Local (47 lines) | `@mana-core/nestjs-integration` | 1 hour | -| ManaDeck | `AuthGuard` | `@mana-core/nestjs-integration` | No change | N/A | - -**Compatibility:** βœ… COMPATIBLE - All validate via mana-core-auth correctly - -**Code Duplication:** 157 lines of duplicate guard logic to eliminate - ---- - -### 4. JWT Token Field Mapping - -| Backend/Package | User ID Field | Email Field | Role Field | Session Field | Compatible | -|----------------|--------------|-------------|------------|---------------|-----------| -| JWT Payload (source) | `sub` | `email` | `role` | `sid` / `sessionId` | N/A | -| `@manacore/shared-nestjs-auth` | `userId` ⚠️ | `email` βœ… | `role` βœ… | `sessionId` βœ… | MAPPED | -| `@mana-core/nestjs-integration` | `sub` βœ… | `email` βœ… | `role` βœ… | `sessionId` βœ… | EXACT | -| Chat (local) | `userId` ⚠️ | `email` βœ… | `role` βœ… | `sessionId` βœ… | MAPPED | -| Picture (local) | `userId` ⚠️ | `email` βœ… | `role` βœ… | `sessionId` βœ… | MAPPED | -| Presi (local) | `sub` βœ… | `email` βœ… | `role` βœ… | N/A | PARTIAL | - -**Compatibility:** ⚠️ FUNCTIONAL - Different field names but values correct - -**Issue:** Code not portable between backends using `userId` vs `sub` - ---- - -### 5. Development Mode Support - -| Backend | Dev Bypass | Dev User ID | Dev User Email | Config Source | -|---------|-----------|------------|----------------|--------------| -| mana-core-auth | N/A | N/A | N/A | N/A | -| Chat | βœ… YES | `000...000` | `test@example.com` | Hardcoded const | -| Picture | ❌ NO | `17cb...014` | N/A | Hardcoded const (unused) | -| Zitare | βœ… YES | `000...000` | `dev@example.com` | Shared package | -| Presi | βœ… YES | N/A | N/A | Local guard (no bypass implemented) | -| ManaDeck | βœ… YES | Configurable | `dev@example.com` | Environment variable | - -**Compatibility:** ⚠️ MIXED - Picture lacks dev bypass entirely - -**Issue:** 3 different dev user IDs in use - ---- - -### 6. Decorator Support - -| Backend | `@CurrentUser()` | `@CurrentUser('field')` | `@Public()` | `OptionalAuthGuard` | -|---------|-----------------|------------------------|-------------|-------------------| -| mana-core-auth | N/A | N/A | N/A | N/A | -| Chat | ❌ NO | ❌ NO | ❌ NO | ❌ NO | -| Picture | ❌ NO | ❌ NO | ❌ NO | ❌ NO | -| Zitare | βœ… YES | ❌ NO | ❌ NO | ❌ NO | -| Presi | ❌ NO | ❌ NO | ❌ NO | ❌ NO | -| ManaDeck | βœ… YES | βœ… YES | βœ… YES | βœ… YES | - -**Compatibility:** ❌ FRAGMENTED - Feature parity varies widely - ---- - -### 7. Environment Configuration - -| Variable | mana-core-auth | Chat | Picture | Zitare | Presi | ManaDeck | Standardized | -|----------|---------------|------|---------|--------|-------|----------|--------------| -| `MANA_CORE_AUTH_URL` | N/A | βœ… | βœ… | βœ… | βœ… | ❌ (uses `MANA_SERVICE_URL`) | NO | -| `NODE_ENV` | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | YES | -| `PORT` | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | YES | -| `DEV_BYPASS_AUTH` | N/A | βœ… | ❌ | βœ… | βœ… | βœ… | NO (missing 1) | -| `DEV_USER_ID` | N/A | Hardcoded | Hardcoded | Hardcoded | N/A | βœ… | NO | -| `CORS_ORIGINS` | βœ… | Hardcoded | Hardcoded | Hardcoded | Hardcoded | Hardcoded | NO | -| Validation Schema | βœ… | ❌ | ❌ | ❌ | ❌ | βœ… | NO (missing 4) | - -**Compatibility:** ⚠️ FUNCTIONAL - Configs work but naming inconsistent - ---- - -### 8. Code Organization - -| Backend | Structure | Controllers | Largest File | Modular | Maintainability | -|---------|-----------|------------|-------------|---------|----------------| -| mana-core-auth | Modular | 3 | ~200 lines | βœ… YES | HIGH | -| Chat | Modular | 6 | ~150 lines | βœ… YES | HIGH | -| Picture | Modular | 6 | ~180 lines | βœ… YES | HIGH | -| Zitare | Modular | 2 | ~100 lines | βœ… YES | HIGH | -| Presi | Modular | 4 | ~200 lines | βœ… YES | HIGH | -| ManaDeck | **Monolithic** | 3 (1 huge) | **971 lines** | ❌ NO | LOW | - -**Compatibility:** βœ… MOSTLY GOOD - Only ManaDeck needs refactoring - ---- - -## Compatibility Risk Assessment - -### Risk Level: MEDIUM - -**Why MEDIUM and not HIGH:** -- βœ… All backends can authenticate successfully -- βœ… JWT validation works correctly -- βœ… No data corruption or security vulnerabilities -- βœ… All backends can run (just not simultaneously) - -**Why MEDIUM and not LOW:** -- ⚠️ Port conflicts prevent simultaneous execution -- ⚠️ Code duplication creates maintenance burden -- ⚠️ Inconsistent patterns confuse developers -- ⚠️ Missing features limit functionality - -### Compatibility Scores by Category - -| Category | Score | Status | -|----------|-------|--------| -| **JWT Validation** | 10/10 | βœ… PERFECT - All backends validate correctly | -| **API Routes** | 4/10 | ❌ POOR - Inconsistent prefixes and versioning | -| **Port Allocation** | 3/10 | ❌ POOR - Conflicts prevent simultaneous use | -| **Auth Implementation** | 6/10 | ⚠️ FAIR - Works but duplicated code | -| **Environment Config** | 5/10 | ⚠️ FAIR - Functional but inconsistent naming | -| **Code Organization** | 7/10 | βœ… GOOD - Only ManaDeck needs work | -| **Developer Experience** | 5/10 | ⚠️ FAIR - Inconsistent patterns confuse | -| **Maintainability** | 5/10 | ⚠️ FAIR - Duplicate code increases burden | - -**Overall Compatibility: 6.2/10** - ---- - -## Remediation Plan - -### Phase 1: Emergency Fixes (2-3 hours) - -**Goal:** Enable simultaneous backend execution -**Urgency:** IMMEDIATE -**Blocking:** Development, testing, demos - -#### Task 1.1: Fix Port Conflicts (30 minutes) - -**Conflicts to resolve:** -1. Port 3002: Chat vs Nutriphi -2. Port 3003: Picture vs Maerchenzauber - -**Actions:** -```bash -# Edit .env.development -CHAT_BACKEND_PORT=3002 # Keep (active) -NUTRIPHI_BACKEND_PORT=3010 # Move (archived) -PICTURE_BACKEND_PORT=3006 # Fix (documented as 3006) -MAERCHENZAUBER_BACKEND_PORT=3011 # Move (archived) -``` - -**Files to edit:** -- `.env.development` (2 lines changed) -- `apps/picture/apps/backend/src/main.ts:52` (change default from 3003 to 3006) - -**Validation:** -```bash -pnpm dev:chat:backend & -pnpm dev:picture:backend & -pnpm dev:zitare:backend & -pnpm dev:presi:backend & -pnpm dev:manadeck:backend & - -# All should start without port conflicts -ps aux | grep node -``` - -#### Task 1.2: Standardize Route Prefix (1 hour) - -**Decision needed:** Choose one standard - -**Option A: Full compliance** (`/api/v1`) -```typescript -// All backends -app.setGlobalPrefix('api/v1'); -``` -- βœ… Matches source of truth exactly -- βœ… Future-proof for versioning -- ⚠️ Requires client URL updates for all backends - -**Option B: Prepare for versioning** (`/api`) -```typescript -// All backends -app.setGlobalPrefix('api'); -``` -- βœ… Minimal changes (only ManaDeck affected) -- βœ… Easy to add /v1 later -- ⚠️ Doesn't match source of truth now - -**Recommended: Option A** (Full compliance) - -**Actions:** -```typescript -// Edit each main.ts -// Chat: apps/chat/apps/backend/src/main.ts:36 -// Picture: apps/picture/apps/backend/src/main.ts:50 -// Zitare: apps/zitare/apps/backend/src/main.ts:32 -// Presi: apps/presi/apps/backend/src/main.ts:33 -// ManaDeck: apps/manadeck/apps/backend/src/main.ts:39 - -app.setGlobalPrefix('api/v1', { - exclude: ['health', 'health/ready', 'health/live'] -}); -``` - -**Files to edit:** 5 main.ts files - -#### Task 1.3: Add DEV_USER_ID to Central Config (30 minutes) - -**Actions:** -```bash -# Add to .env.development -DEV_USER_ID=00000000-0000-0000-0000-000000000000 -``` - -```typescript -// Update Chat guard: apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts:8 -- const DEV_USER_ID = '17cb0be7-058a-4964-9e18-1fe7055fd014'; -+ const devUserId = this.configService.get('DEV_USER_ID') || -+ '00000000-0000-0000-0000-000000000000'; - -// Update Picture guard similarly -``` - -**Files to edit:** -- `.env.development` (1 line added) -- `scripts/generate-env.mjs` (add DEV_USER_ID mapping) -- `apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts` -- `apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts` - -**Validation:** -```bash -# Test dev bypass -curl http://localhost:3002/api/v1/health \ - -H "X-Test: dev-mode" # Should work with DEV_BYPASS_AUTH=true -``` - -#### Task 1.4: Add Dev Bypass to Picture Backend (30 minutes) - -**Action:** -```typescript -// apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts - -// Add after line 20 (before token extraction) -const isDev = this.configService.get('NODE_ENV') === 'development'; -const bypassAuth = this.configService.get('DEV_BYPASS_AUTH') === 'true'; - -if (isDev && bypassAuth) { - const devUserId = this.configService.get('DEV_USER_ID') || - '00000000-0000-0000-0000-000000000000'; - request.user = { - userId: devUserId, - email: 'dev@example.com', - role: 'user', - sessionId: 'dev-session', - }; - return true; -} -``` - -**Validation:** -```bash -# Set env vars -export DEV_BYPASS_AUTH=true -export NODE_ENV=development - -# Test Picture backend -curl http://localhost:3006/api/v1/health -# Should work without Bearer token -``` - ---- - -### Phase 2: Standardization (4-6 hours) - -**Goal:** Eliminate code duplication and inconsistencies -**Urgency:** HIGH (this week) -**Impact:** Code quality, maintainability - -#### Task 2.1: Migrate Chat to Shared Auth Package (1 hour) - -**Current:** Custom local guard (58 lines) -**Target:** `@manacore/shared-nestjs-auth` - -**Actions:** -1. Install package (if not already) -```bash -pnpm add @manacore/shared-nestjs-auth --filter @chat/backend -``` - -2. Update all imports -```typescript -// Find all files with: import { JwtAuthGuard } from './common/guards/jwt-auth.guard' -// Replace with: import { JwtAuthGuard, CurrentUser, CurrentUserData } from '@manacore/shared-nestjs-auth' - -// Files to update: -// apps/chat/apps/backend/src/**/*.controller.ts -``` - -3. Add decorators -```typescript -// Before -@UseGuards(JwtAuthGuard) -@Get('profile') -getProfile(@Request() req) { - return { user: req.user }; -} - -// After -@UseGuards(JwtAuthGuard) -@Get('profile') -getProfile(@CurrentUser() user: CurrentUserData) { - return { user }; -} -``` - -4. Delete local guard -```bash -rm apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts -``` - -**Validation:** -```bash -# Run tests -pnpm --filter @chat/backend test - -# Test auth flow -TOKEN=$(curl -X POST http://localhost:3001/api/v1/auth/login \ - -H "Content-Type: application/json" \ - -d '{"email":"test@example.com","password":"password"}' | jq -r '.accessToken') - -curl http://localhost:3002/api/v1/profile \ - -H "Authorization: Bearer $TOKEN" -``` - -#### Task 2.2: Migrate Picture to Shared Auth Package (1 hour) - -**Same steps as Task 2.1**, but for Picture backend - -**Files affected:** -- All `apps/picture/apps/backend/src/**/*.controller.ts` -- Delete `apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts` - -#### Task 2.3: Migrate Presi to Mana Core Integration (2 hours) - -**Current:** Custom local guard (47 lines) -**Target:** `@mana-core/nestjs-integration` (for credit support) - -**Actions:** -1. Install package -```bash -pnpm add @mana-core/nestjs-integration --filter @presi/backend -``` - -2. Configure module -```typescript -// apps/presi/apps/backend/src/app.module.ts -import { ManaCoreModule } from '@mana-core/nestjs-integration'; - -@Module({ - imports: [ - ManaCoreModule.forRootAsync({ - imports: [ConfigModule], - useFactory: (config: ConfigService) => ({ - appId: config.get('APP_ID'), - serviceKey: config.get('MANA_CORE_SERVICE_KEY'), - debug: config.get('NODE_ENV') === 'development', - }), - inject: [ConfigService], - }), - ], -}) -``` - -3. Update all controllers -```typescript -// Before -import { AuthGuard } from '../auth/auth.guard'; - -// After -import { AuthGuard } from '@mana-core/nestjs-integration/guards'; -import { CurrentUser } from '@mana-core/nestjs-integration/decorators'; -``` - -4. Add environment variables -```bash -# .env.development -PRESI_APP_ID=presi -PRESI_MANA_CORE_SERVICE_KEY=your-service-key -``` - -5. Delete local guard -```bash -rm apps/presi/apps/backend/src/auth/auth.guard.ts -``` - -**Validation:** Same as Tasks 2.1 and 2.2 - -#### Task 2.4: Standardize Auth URL Variable (30 minutes) - -**Changes:** -```bash -# .env.development -# ManaDeck: Rename MANA_SERVICE_URL β†’ MANA_CORE_AUTH_URL -- MANADECK_MANA_SERVICE_URL=http://localhost:3001 -+ MANADECK_MANA_CORE_AUTH_URL=http://localhost:3001 - -# Nutriphi: Rename MANACORE_AUTH_URL β†’ MANA_CORE_AUTH_URL -- NUTRIPHI_MANACORE_AUTH_URL=http://localhost:3001 -+ NUTRIPHI_MANA_CORE_AUTH_URL=http://localhost:3001 -``` - -```javascript -// scripts/generate-env.mjs -// Update mappings for ManaDeck and Nutriphi -``` - -**Files to edit:** -- `.env.development` -- `scripts/generate-env.mjs` -- `apps/manadeck/apps/backend/.env.example` (if exists) - -#### Task 2.5: Extract CORS Origins to Environment (1 hour) - -**Changes:** -```bash -# .env.development -CORS_ORIGINS=http://localhost:5173,http://localhost:3000,http://localhost:4173 -``` - -```typescript -// Each main.ts -const corsOrigins = configService - .get('CORS_ORIGINS') - ?.split(',') - .map(origin => origin.trim()) || ['http://localhost:5173']; - -app.enableCors({ - origin: corsOrigins, - credentials: true, -}); -``` - -**Files to edit:** -- `.env.development` (add CORS_ORIGINS) -- `apps/chat/apps/backend/src/main.ts:20` -- `apps/picture/apps/backend/src/main.ts:34` -- `apps/zitare/apps/backend/src/main.ts:18` -- `apps/presi/apps/backend/src/main.ts:19` - ---- - -### Phase 3: Code Quality (6-8 hours) - -**Goal:** Add missing features and improve maintainability -**Urgency:** MEDIUM (next week) -**Impact:** Error handling, observability, code quality - -#### Task 3.1: Add Environment Validation Schemas (2 hours) - -**For each backend** (Chat, Picture, Zitare, Presi): - -1. Install Joi -```bash -pnpm add joi --filter @{backend}/backend -``` - -2. Create validation schema -```typescript -// apps/{backend}/apps/backend/src/config/validation.schema.ts -import * as Joi from 'joi'; - -export const validationSchema = Joi.object({ - NODE_ENV: Joi.string() - .valid('development', 'production', 'test') - .default('development'), - PORT: Joi.number().default(3000), - MANA_CORE_AUTH_URL: Joi.string().uri().required(), - DEV_BYPASS_AUTH: Joi.boolean().default(false), - DEV_USER_ID: Joi.string().optional(), - CORS_ORIGINS: Joi.string().default('http://localhost:5173'), - // Add backend-specific vars -}); -``` - -3. Register in module -```typescript -// apps/{backend}/apps/backend/src/app.module.ts -import { validationSchema } from './config/validation.schema'; - -@Module({ - imports: [ - ConfigModule.forRoot({ - validationSchema, - validationOptions: { - abortEarly: false, // Show all errors - }, - }), - ], -}) -``` - -**Validation:** -```bash -# Test with missing var -unset MANA_CORE_AUTH_URL -pnpm dev:{backend}:backend - -# Should see clear error: -# "Configuration validation failed: -# - MANA_CORE_AUTH_URL is required" -``` - -#### Task 3.2: Refactor ManaDeck Controller (3-4 hours) - -**Current:** 971-line monolithic controller -**Target:** Feature-based modular structure - -**New structure:** -``` -apps/manadeck/apps/backend/src/ -β”œβ”€β”€ controllers/ -β”‚ β”œβ”€β”€ health.controller.ts (existing, keep) -β”‚ └── public.controller.ts (existing, keep) -β”œβ”€β”€ modules/ -β”‚ β”œβ”€β”€ deck/ -β”‚ β”‚ β”œβ”€β”€ deck.controller.ts (NEW - ~150 lines) -β”‚ β”‚ β”œβ”€β”€ deck.service.ts -β”‚ β”‚ └── deck.module.ts -β”‚ β”œβ”€β”€ card/ -β”‚ β”‚ β”œβ”€β”€ card.controller.ts (NEW - ~200 lines) -β”‚ β”‚ β”œβ”€β”€ card.service.ts -β”‚ β”‚ └── card.module.ts -β”‚ β”œβ”€β”€ study-session/ -β”‚ β”‚ β”œβ”€β”€ study-session.controller.ts (NEW - ~180 lines) -β”‚ β”‚ β”œβ”€β”€ study-session.service.ts -β”‚ β”‚ └── study-session.module.ts -β”‚ β”œβ”€β”€ progress/ -β”‚ β”‚ β”œβ”€β”€ progress.controller.ts (NEW - ~120 lines) -β”‚ β”‚ β”œβ”€β”€ progress.service.ts -β”‚ β”‚ └── progress.module.ts -β”‚ └── ai/ -β”‚ β”œβ”€β”€ ai.controller.ts (NEW - ~150 lines) -β”‚ β”œβ”€β”€ ai.service.ts -β”‚ └── ai.module.ts -└── app.module.ts (update imports) -``` - -**Migration steps:** -1. Create feature modules -2. Extract routes from api.controller.ts -3. Move business logic to services -4. Update app.module.ts imports -5. Delete old api.controller.ts -6. Test all endpoints - -**Validation:** -```bash -# Run full test suite -pnpm --filter @manadeck/backend test - -# Test each feature endpoint -curl http://localhost:3009/api/v1/decks -H "Authorization: Bearer $TOKEN" -curl http://localhost:3009/api/v1/cards -H "Authorization: Bearer $TOKEN" -# etc. -``` - -#### Task 3.3: Standardize Health Checks (1-2 hours) - -**Add Terminus to** Chat, Picture, Zitare: - -1. Install Terminus -```bash -pnpm add @nestjs/terminus --filter @{backend}/backend -``` - -2. Create health module -```typescript -// apps/{backend}/apps/backend/src/health/health.module.ts -import { Module } from '@nestjs/common'; -import { TerminusModule } from '@nestjs/terminus'; -import { HttpModule } from '@nestjs/axios'; -import { HealthController } from './health.controller'; - -@Module({ - imports: [TerminusModule, HttpModule], - controllers: [HealthController], -}) -export class HealthModule {} -``` - -3. Update health controller -```typescript -// apps/{backend}/apps/backend/src/health/health.controller.ts -import { Controller, Get } from '@nestjs/common'; -import { HealthCheck, HealthCheckService, HttpHealthIndicator } from '@nestjs/terminus'; - -@Controller('health') -export class HealthController { - constructor( - private health: HealthCheckService, - private http: HttpHealthIndicator, - ) {} - - @Get() - @HealthCheck() - check() { - return this.health.check([ - () => this.http.pingCheck('mana-core-auth', 'http://localhost:3001/api/v1/health'), - ]); - } - - @Get('ready') - @HealthCheck() - readiness() { - return this.health.check([ - () => this.http.pingCheck('auth-service', 'http://localhost:3001/api/v1/health'), - // Add database check, etc. - ]); - } - - @Get('live') - liveness() { - return { status: 'ok', timestamp: new Date().toISOString() }; - } -} -``` - -**Validation:** -```bash -curl http://localhost:3002/health -curl http://localhost:3002/health/ready -curl http://localhost:3002/health/live -``` - -#### Task 3.4: Create Missing .env.example Files (30 minutes) - -**For Zitare:** -```bash -# apps/zitare/apps/backend/.env.example -NODE_ENV=development -PORT=3007 -MANA_CORE_AUTH_URL=http://localhost:3001 -DEV_BYPASS_AUTH=true -DEV_USER_ID=00000000-0000-0000-0000-000000000000 -CORS_ORIGINS=http://localhost:5173 -SUPABASE_URL=your-supabase-url -SUPABASE_ANON_KEY=your-anon-key -``` - -**For Presi:** -```bash -# apps/presi/apps/backend/.env.example -NODE_ENV=development -PORT=3008 -MANA_CORE_AUTH_URL=http://localhost:3001 -DEV_BYPASS_AUTH=true -DEV_USER_ID=00000000-0000-0000-0000-000000000000 -CORS_ORIGINS=http://localhost:5173 -APP_ID=presi -MANA_CORE_SERVICE_KEY=your-service-key -SUPABASE_URL=your-supabase-url -SUPABASE_ANON_KEY=your-anon-key -``` - -#### Task 3.5: Add @Public Decorator to Shared Auth (1 hour) - -**Update shared package:** -```typescript -// packages/shared-nestjs-auth/src/decorators/public.decorator.ts (NEW) -import { SetMetadata } from '@nestjs/common'; - -export const IS_PUBLIC_KEY = 'isPublic'; -export const Public = () => SetMetadata(IS_PUBLIC_KEY, true); -``` - -```typescript -// packages/shared-nestjs-auth/src/guards/jwt-auth.guard.ts -import { IS_PUBLIC_KEY } from '../decorators/public.decorator'; - -async canActivate(context: ExecutionContext): Promise { - // Check for @Public decorator - const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [ - context.getHandler(), - context.getClass(), - ]); - - if (isPublic) { - return true; - } - - // Continue with normal auth check - // ... -} -``` - -```typescript -// packages/shared-nestjs-auth/src/index.ts -export { Public } from './decorators/public.decorator'; -``` - -**Usage in backends:** -```typescript -import { Public } from '@manacore/shared-nestjs-auth'; - -@Public() -@Get('webhook') -handleWebhook() { - // No auth required -} -``` - ---- - -### Phase 4: Observability & Advanced Features (4-6 hours) - -**Goal:** Production-ready monitoring and resilience -**Urgency:** LOW (future sprint) -**Impact:** Debugging, reliability, security - -#### Task 4.1: Add Request Context Logging (1 hour) - -**Update all guards:** -```typescript -async canActivate(context: ExecutionContext): Promise { - const request = context.switchToHttp().getRequest(); - - // Log in development - if (process.env.NODE_ENV === 'development') { - console.log(`[${new Date().toISOString()}] Auth check: ${request.method} ${request.path}`); - } - - // Continue with auth logic - // ... -} -``` - -#### Task 4.2: Implement Circuit Breaker (2-3 hours) - -**Add circuit breaker for auth service:** -```typescript -// packages/shared-nestjs-auth/src/utils/circuit-breaker.ts -export class CircuitBreaker { - private failureCount = 0; - private readonly threshold = 5; - private readonly timeout = 30000; // 30 seconds - private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED'; - private openedAt: number = 0; - - async call(fn: () => Promise): Promise { - if (this.state === 'OPEN') { - if (Date.now() - this.openedAt > this.timeout) { - this.state = 'HALF_OPEN'; - } else { - throw new Error('Circuit breaker is OPEN'); - } - } - - try { - const result = await fn(); - this.onSuccess(); - return result; - } catch (error) { - this.onFailure(); - throw error; - } - } - - private onSuccess() { - this.failureCount = 0; - this.state = 'CLOSED'; - } - - private onFailure() { - this.failureCount++; - if (this.failureCount >= this.threshold) { - this.state = 'OPEN'; - this.openedAt = Date.now(); - } - } -} -``` - -#### Task 4.3: Standardize Error Response Format (1-2 hours) - -**Create error codes enum:** -```typescript -// packages/shared-nestjs-auth/src/types/errors.ts -export enum AuthErrorCode { - NO_TOKEN = 'AUTH_NO_TOKEN', - INVALID_TOKEN = 'AUTH_INVALID_TOKEN', - EXPIRED_TOKEN = 'AUTH_EXPIRED_TOKEN', - SERVICE_UNAVAILABLE = 'AUTH_SERVICE_UNAVAILABLE', -} - -export class AuthException extends UnauthorizedException { - constructor( - public readonly code: AuthErrorCode, - message: string, - public readonly details?: unknown, - ) { - super({ code, message, details }); - } -} -``` - -**Use in guards:** -```typescript -if (!token) { - throw new AuthException( - AuthErrorCode.NO_TOKEN, - 'No authorization token provided' - ); -} - -if (!result.valid) { - throw new AuthException( - AuthErrorCode.INVALID_TOKEN, - 'Invalid or expired token', - { reason: result.error } - ); -} -``` - -#### Task 4.4: Add Integration Tests (2-3 hours) - -**Create auth integration test suite:** -```typescript -// packages/shared-nestjs-auth/src/__tests__/integration.spec.ts -describe('Auth Integration Tests', () => { - it('should validate valid JWT token', async () => { - // Get token from mana-core-auth - const token = await getTestToken(); - - // Call protected endpoint - const response = await request(app.getHttpServer()) - .get('/protected') - .set('Authorization', `Bearer ${token}`) - .expect(200); - - expect(response.body.user).toBeDefined(); - }); - - it('should reject invalid token', async () => { - await request(app.getHttpServer()) - .get('/protected') - .set('Authorization', 'Bearer invalid-token') - .expect(401); - }); - - it('should allow dev bypass in development', async () => { - process.env.NODE_ENV = 'development'; - process.env.DEV_BYPASS_AUTH = 'true'; - - await request(app.getHttpServer()) - .get('/protected') - .expect(200); - }); -}); -``` - ---- - -## Remediation Timeline - -### Sprint Overview - -| Phase | Duration | Start | End | Effort | Priority | -|-------|----------|-------|-----|--------|----------| -| Phase 1: Emergency Fixes | 2-3 hours | Day 1 | Day 1 | 1 dev | CRITICAL | -| Phase 2: Standardization | 4-6 hours | Day 2 | Day 3 | 1 dev | HIGH | -| Phase 3: Code Quality | 6-8 hours | Day 4 | Day 6 | 1 dev | MEDIUM | -| Phase 4: Observability | 4-6 hours | Week 2 | Week 2 | 1 dev | LOW | - -**Total Effort:** 16-23 hours (2-3 developer days) - -### Critical Path - -``` -Day 1 (CRITICAL): -└─ Phase 1: Emergency Fixes (2-3 hours) - β”œβ”€ Task 1.1: Fix port conflicts (30 min) ← BLOCKING - β”œβ”€ Task 1.2: Standardize route prefix (1 hour) - β”œβ”€ Task 1.3: Add DEV_USER_ID to config (30 min) - └─ Task 1.4: Add dev bypass to Picture (30 min) - -Day 2-3 (HIGH): -└─ Phase 2: Standardization (4-6 hours) - β”œβ”€ Task 2.1: Migrate Chat auth (1 hour) - β”œβ”€ Task 2.2: Migrate Picture auth (1 hour) - β”œβ”€ Task 2.3: Migrate Presi auth (2 hours) - β”œβ”€ Task 2.4: Standardize auth URL var (30 min) - └─ Task 2.5: Extract CORS to env (1 hour) - -Day 4-6 (MEDIUM): -└─ Phase 3: Code Quality (6-8 hours) - β”œβ”€ Task 3.1: Add validation schemas (2 hours) - β”œβ”€ Task 3.2: Refactor ManaDeck controller (3-4 hours) - β”œβ”€ Task 3.3: Standardize health checks (1-2 hours) - β”œβ”€ Task 3.4: Create .env.example files (30 min) - └─ Task 3.5: Add @Public decorator (1 hour) - -Week 2 (LOW): -└─ Phase 4: Observability (4-6 hours) - β”œβ”€ Task 4.1: Add request logging (1 hour) - β”œβ”€ Task 4.2: Circuit breaker (2-3 hours) - β”œβ”€ Task 4.3: Standardize errors (1-2 hours) - └─ Task 4.4: Integration tests (2-3 hours) -``` - ---- - -## Success Criteria - -### Phase 1 Complete When: -- [ ] All 5 active backends start simultaneously without port conflicts -- [ ] All backends use same route prefix pattern -- [ ] Dev user ID is centralized and consistent -- [ ] Picture backend has dev bypass support - -### Phase 2 Complete When: -- [ ] Zero duplicate auth guard code -- [ ] All backends use shared packages -- [ ] Auth URL variable naming is consistent -- [ ] CORS origins are configurable via environment - -### Phase 3 Complete When: -- [ ] All backends have environment validation -- [ ] ManaDeck uses modular controller structure -- [ ] Health checks are standardized with Terminus -- [ ] All backends have .env.example files -- [ ] @Public decorator available in all backends - -### Phase 4 Complete When: -- [ ] Request context logging enabled -- [ ] Circuit breaker protects against auth service failures -- [ ] Error responses include codes and details -- [ ] Integration test suite achieves 80% coverage - -### Overall Success (All Phases): -- [ ] Compatibility score: 9/10 or higher -- [ ] Zero code duplication in auth logic -- [ ] Consistent API patterns across all backends -- [ ] Comprehensive documentation -- [ ] All backends production-ready - ---- - -## Rollback Plan - -### If Phase 1 Fails: -```bash -# Restore original port configuration -git checkout -- .env.development -git checkout -- apps/picture/apps/backend/src/main.ts - -# Restart backends with original config -pnpm install -``` - -### If Phase 2 Fails: -```bash -# Revert shared package migrations -git checkout -- apps/chat/apps/backend/src -git checkout -- apps/picture/apps/backend/src -git checkout -- apps/presi/apps/backend/src - -# Restore local guards -git restore apps/*/apps/backend/src/*/guards/*.ts -``` - -### If Phase 3/4 Fails: -- Code quality improvements don't break functionality -- Can be rolled back individually without affecting other phases - ---- - -## Post-Remediation Validation - -### Comprehensive Test Suite - -```bash -#!/bin/bash -# test-compatibility.sh - -echo "Starting all backends..." -pnpm dev:chat:backend & -pnpm dev:picture:backend & -pnpm dev:zitare:backend & -pnpm dev:presi:backend & -pnpm dev:manadeck:backend & - -sleep 10 - -echo "Testing authentication flow..." -TOKEN=$(curl -s -X POST http://localhost:3001/api/v1/auth/login \ - -H "Content-Type: application/json" \ - -d '{"email":"test@example.com","password":"password"}' \ - | jq -r '.accessToken') - -if [ -z "$TOKEN" ]; then - echo "❌ Failed to get auth token" - exit 1 -fi - -echo "Testing each backend..." -for PORT in 3002 3006 3007 3008 3009; do - RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \ - http://localhost:$PORT/api/v1/health \ - -H "Authorization: Bearer $TOKEN") - - if [ "$RESPONSE" = "200" ]; then - echo "βœ… Backend on port $PORT: OK" - else - echo "❌ Backend on port $PORT: FAILED ($RESPONSE)" - fi -done - -echo "Testing dev bypass..." -export DEV_BYPASS_AUTH=true -export NODE_ENV=development - -for PORT in 3002 3006 3007 3008 3009; do - RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \ - http://localhost:$PORT/api/v1/health) - - if [ "$RESPONSE" = "200" ]; then - echo "βœ… Dev bypass on port $PORT: OK" - else - echo "❌ Dev bypass on port $PORT: FAILED" - fi -done - -echo "All tests complete!" -``` - -### Compatibility Scorecard (Post-Remediation Target) - -| Category | Current Score | Target Score | Status | -|----------|--------------|--------------|--------| -| JWT Validation | 10/10 | 10/10 | βœ… Already perfect | -| API Routes | 4/10 | 10/10 | πŸ“ˆ Phase 1 fixes | -| Port Allocation | 3/10 | 10/10 | πŸ“ˆ Phase 1 fixes | -| Auth Implementation | 6/10 | 10/10 | πŸ“ˆ Phase 2 fixes | -| Environment Config | 5/10 | 9/10 | πŸ“ˆ Phases 2-3 fix | -| Code Organization | 7/10 | 9/10 | πŸ“ˆ Phase 3 fixes | -| Developer Experience | 5/10 | 9/10 | πŸ“ˆ All phases | -| Maintainability | 5/10 | 9/10 | πŸ“ˆ All phases | - -**Overall Target: 9.4/10** (up from 6.2/10) - ---- - -## Summary - -This remediation plan addresses **18 identified issues** across 5 backends: -- **3 critical blocking issues** (Phase 1 - 2-3 hours) -- **8 high-priority deviations** (Phase 2 - 4-6 hours) -- **7 medium-priority improvements** (Phases 3-4 - 10-14 hours) - -**Total estimated effort:** 16-23 hours (2-3 developer days) - -**Expected outcome:** -- Zero port conflicts -- Consistent API patterns -- Shared authentication packages -- No code duplication -- Production-ready observability -- Compatibility score: 6.2/10 β†’ 9.4/10 - -**Risk level after remediation:** LOW (from MEDIUM) - ---- - -**Document Version:** 1.0 -**Last Updated:** 2025-12-01 -**Next Review:** After Phase 2 completion diff --git a/HISTORICAL-ANALYSIS.md b/HISTORICAL-ANALYSIS.md deleted file mode 100644 index 0ab9066aa..000000000 --- a/HISTORICAL-ANALYSIS.md +++ /dev/null @@ -1,373 +0,0 @@ -# Historical Analysis: dev vs dev-1 Branch Comparison - -**Date:** 2025-12-05 -**Analyst:** Historical Analyst Agent -**Scope:** Understanding CI/CD setup and identifying changes that may have broken type-check - ---- - -## Executive Summary - -The `dev` branch has **30 commits ahead** of `dev-1`, primarily focused on: - -1. **Code quality infrastructure** (ESLint v9, lint-staged, pre-commit hooks) -2. **CI/CD simplification** (disabled most workflows for rapid iteration) -3. **Project archival** (moved finance, mail, moodlit, inventory, presi, storage to `apps-archived/`) -4. **Build system fixes** (removed recursive turbo calls, fixed Dockerfiles) - -**Key Finding:** The `dev` branch introduced aggressive ESLint enforcement and pre-commit hooks that run `type-check`, which is likely causing the current failures. - ---- - -## 1. CI/CD Setup Comparison - -### dev-1 Branch (Clean State) - -**Active Workflows:** - -- `.github/workflows/ci-pull-request.yml` - Full PR validation -- `.github/workflows/ci-main.yml` - Full main branch validation -- `.github/workflows/test.yml` - Test runner -- `.github/workflows/test-coverage.yml` - Coverage reports -- `.github/workflows/dependency-update.yml` - Dependency management -- `.github/workflows/cd-staging.yml` - Staging deployment -- `.github/workflows/cd-production.yml` - Production deployment -- `.github/workflows/cd-staging-tagged.yml` - Tagged staging deploys - -**CI Features on dev-1:** - -```yaml -# ci-main.yml (dev-1) -jobs: - validate: - - Install dependencies - - Build shared packages - - Run format check - - Run lint (continue-on-error: true) - - Run type check βœ“ - - Build all projects - - Run tests - - build-docker-images: - - Builds: maerchenzauber, chat, manadeck, nutriphi, news, mana-core-auth - - Uses proper caching and multi-stage builds -``` - -**PR Workflow Features (dev-1):** - -- Change detection (dorny/paths-filter) -- Scoped validation (only changed projects) -- Lint and format checks -- Type checking with shared package builds -- Docker build validation -- Security scanning -- Required status checks - -### dev Branch (Current State) - -**Disabled Workflows:** - -- `ci-pull-request.yml` β†’ **ci-pull-request.yml.bak** -- `test.yml` β†’ **test.yml.bak** -- `test-coverage.yml` β†’ **test-coverage.yml.bak** -- `dependency-update.yml` β†’ **dependency-update.yml.bak** - -**Simplified ci-main.yml:** - -```yaml -# ci-main.yml (dev) -jobs: - build-docker-images: # NO VALIDATION STEP - - Only builds: mana-core-auth, chat-backend, chat-web - - Removed build-args - - Simplified tags to only 'latest' -``` - -**Key Changes:** - -- ❌ **Removed** the `validate` job entirely -- ❌ **Removed** format check, lint, type-check from CI -- ❌ **Removed** test execution from CI -- βœ… Kept Docker builds (minimal services only) - ---- - -## 2. Husky Pre-commit Hooks - -### dev-1 Branch - -```bash -# .husky/pre-commit (both branches identical) -pnpm exec lint-staged -pnpm run type-check -``` - -### dev Branch (Same) - -```bash -# .husky/pre-commit -pnpm exec lint-staged -pnpm run type-check -``` - -**Lint-staged Configuration:** - -**dev-1:** - -```js -// lint-staged.config.js (dev-1) -export default { - '*.{ts,tsx,js,jsx,json,md,svelte,astro}': ['prettier --config .prettierrc.json --write'], -}; -``` - -**dev (STRICTER):** - -```js -// lint-staged.config.js (dev) -export default { - '*.{ts,tsx,js,jsx,mjs,cjs}': [ - 'eslint --fix --ignore-pattern "apps-archived/**"', // NEW! - 'prettier --config .prettierrc.json --write', - ], - '*.{json,md,svelte,astro}': ['prettier --config .prettierrc.json --write'], -}; -``` - -**Impact:** Pre-commit now runs ESLint on all staged files, which could fail if ESLint configs are incomplete. - ---- - -## 3. ESLint Infrastructure Changes - -### New in dev Branch - -**Added shared ESLint config package:** - -``` -packages/eslint-config/ -β”œβ”€β”€ base.js (77 lines) -β”œβ”€β”€ index.js (44 lines) -β”œβ”€β”€ nestjs.js (122 lines) -β”œβ”€β”€ prettier.js (37 lines) -β”œβ”€β”€ react.js (85 lines) -β”œβ”€β”€ svelte.js (90 lines) -β”œβ”€β”€ typescript.js (94 lines) -└── package.json (40 lines) -``` - -**Root ESLint configuration added:** - -- Commit: `fd962c30` - "chore: add root ESLint config and enable lint in pre-commit" -- Commit: `f720a25c` - "chore: enforce stricter ESLint rules" -- Commit: `ec236307` - "chore: add lint:root and lint:fix scripts" - -**New package.json scripts (dev):** - -```json -"lint:root": "eslint . --cache", -"lint:fix": "eslint . --fix --cache" -``` - ---- - -## 4. Build System Changes - -### Critical Fix: Recursive Turbo Calls - -**Commit:** `e32e4b1b` - "fix(build): remove recursive build scripts from parent packages" - -**Problem:** Parent workspace packages had scripts like: - -```json -// WRONG - Creates infinite recursion -{ - "scripts": { - "type-check": "turbo run type-check", - "build": "turbo run build" - } -} -``` - -**Solution:** Removed these from parent packages to let root turbo orchestrate. - -### Shared Package Changes - -**Modified packages:** - -- `@mana-core/nestjs-integration` - Import fixes -- `@manacore/shared-auth` - Device adapter improvements -- `@manacore/shared-branding` - Removed archived app logos -- `@manacore/shared-api-client` - **DELETED** (218 lines removed) - -**Key changes:** - -```diff -// packages/shared-api-client was REMOVED entirely -- packages/shared-api-client/package.json -- packages/shared-api-client/src/client.ts (218 lines) -- packages/shared-api-client/src/index.ts -- packages/shared-api-client/src/types.ts -- packages/shared-api-client/tsconfig.json -``` - ---- - -## 5. Archival Changes - -**Projects moved to apps-archived/ on dev:** - -- finance (backend + web) -- mail (backend + web + mobile + landing) -- moodlit (backend + web + mobile + landing) -- inventory (backend + web + landing + packages) -- presi (all apps) -- storage (backend + web) - -**Workspace cleanup:** - -```diff -- Remove from pnpm-workspace.yaml (implicitly via apps-archived exclusion) -- Remove scripts from root package.json -- Move entire directory structure -``` - ---- - -## 6. Type-Check Differences - -### dev-1 Approach - -```bash -# Simple turbo orchestration -pnpm run type-check # Runs turbo run type-check -``` - -### dev Approach - -```bash -# Same command, but: -# 1. Fewer projects (archived apps excluded) -# 2. New ESLint strict rules -# 3. Shared package changes (removed shared-api-client) -# 4. Pre-commit hook enforcement -``` - -**Root Cause Analysis:** - -The type-check is failing on `dev` likely due to: - -1. **Import errors** from removed `@manacore/shared-api-client` package -2. **ESLint errors** treated as type errors (if misconfigured) -3. **Missing dependencies** in archived apps still being scanned -4. **Turbo cache poisoning** from the recursive build fix - ---- - -## 7. Commit Timeline (dev-1 to dev) - -**Key commits in chronological order:** - -1. **Code Quality Phase (Dec 3-4)** - - `0086e339` - Add ESLint v9 config - - `fd962c30` - Enable ESLint in pre-commit - - `f720a25c` - Enforce stricter rules - - `16cb8e75` - Improve code quality - - `49001060` - Fix Prettier formatting - -2. **Build Fixes Phase (Nov 30 - Dec 2)** - - `e32e4b1b` - Remove recursive turbo calls - - `aca6cdba` - Fix build errors - - `9c471195` - Fix wrong type imports - -3. **CI/CD Simplification (Nov 28-29)** - - `80f80053` - Simplify to mana-core-auth + chat only - - `1ecdee46` - Simplify pipelines - - `c1d14a4a` - Disable PR workflows (renamed to .bak) - -4. **Archival Phase (Earlier)** - - Projects moved to apps-archived/ - - Workspace updated - ---- - -## 8. Recommendations - -### Immediate Actions - -1. **Check for dangling imports** - - ```bash - grep -r "@manacore/shared-api-client" --exclude-dir=node_modules --exclude-dir=apps-archived - ``` - -2. **Validate ESLint configs** - - ```bash - # Check if all active apps have valid ESLint configs - find apps -name "eslint.config.*" -type f - ``` - -3. **Clear Turbo cache** - - ```bash - pnpm exec turbo clean - rm -rf .turbo - ``` - -4. **Rebuild shared packages** - ```bash - pnpm run build:packages - ``` - -### Restoration Path (if needed) - -To restore full CI/CD from dev-1: - -```bash -# 1. Restore workflows -cp .github/workflows/ci-pull-request.yml.bak .github/workflows/ci-pull-request.yml -cp .github/workflows/test.yml.bak .github/workflows/test.yml -cp .github/workflows/test-coverage.yml.bak .github/workflows/test-coverage.yml -cp .github/workflows/dependency-update.yml.bak .github/workflows/dependency-update.yml - -# 2. Restore full ci-main validation -git show dev-1:.github/workflows/ci-main.yml > .github/workflows/ci-main.yml - -# 3. Simplify lint-staged (optional) -git show dev-1:lint-staged.config.js > lint-staged.config.js -``` - ---- - -## 9. Summary Table - -| Feature | dev-1 | dev | Impact | -| ---------------------- | ---------------------------------- | ------------------------- | ------ | -| **PR Workflow** | βœ… Full validation | ❌ Disabled (.bak) | High | -| **Main CI Validation** | βœ… Format, lint, type-check, build | ❌ Only Docker builds | High | -| **Pre-commit Hooks** | βœ… Prettier only | βœ… ESLint + Prettier | Medium | -| **ESLint Config** | ❌ Fragmented | βœ… Centralized package | Medium | -| **Shared Packages** | All active | Removed shared-api-client | High | -| **Archived Apps** | In apps/ | In apps-archived/ | Low | -| **Turbo Recursion** | ⚠️ Present | βœ… Fixed | High | -| **Test Workflows** | βœ… Active | ❌ Disabled (.bak) | Medium | - ---- - -## 10. Next Steps - -1. **Run type-check analysis** to identify specific failing packages -2. **Check for removed package imports** (`shared-api-client`) -3. **Validate ESLint configs** across all active apps -4. **Consider selective workflow restoration** (at minimum PR checks) -5. **Update CLAUDE.md** to reflect current state vs planned state - ---- - -**Files for Review:** - -- `/Users/wuesteon/dev/mana_universe/manacore-monorepo/.husky/pre-commit` -- `/Users/wuesteon/dev/mana_universe/manacore-monorepo/lint-staged.config.js` -- `/Users/wuesteon/dev/mana_universe/manacore-monorepo/.github/workflows/*.bak` -- `/Users/wuesteon/dev/mana_universe/manacore-monorepo/packages/eslint-config/` diff --git a/JWT_VALIDATION_REPORT.md b/JWT_VALIDATION_REPORT.md deleted file mode 100644 index 6394d90a5..000000000 --- a/JWT_VALIDATION_REPORT.md +++ /dev/null @@ -1,526 +0,0 @@ -# JWT Integration Validation Report - -**Generated:** 2025-12-01 -**Status:** VALIDATION COMPLETE -**Validator:** JWT Integration Validator Agent - ---- - -## Executive Summary - -All 5 backends are correctly integrated with mana-core-auth JWT validation. However, there are **critical differences** in implementation approaches: - -- **2 backends** (Zitare, ManaDeck) use the standardized shared packages -- **3 backends** (Chat, Picture, Presi) implement their own auth guards (custom/duplicated code) -- **All backends** successfully call mana-core-auth's `/api/v1/auth/validate` endpoint -- **1 critical issue:** Inconsistent dev bypass behavior and default user IDs - ---- - -## Detailed Backend Analysis - -### 1. Chat Backend - -**Integration Method:** Custom Implementation (Duplicated Code) -**Status:** COMPATIBLE - Functional but NOT standardized - -**Package Dependencies:** -- No shared auth packages imported -- Implements local `JwtAuthGuard` - -**Auth Implementation:** -- File: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts` -- Lines: 1-79 -- Validation Flow: - - Extracts Bearer token from Authorization header (line 76) - - DEV_BYPASS_AUTH support (lines 14-27) - - Calls `{MANA_CORE_AUTH_URL}/api/v1/auth/validate` (line 41) - - Maps response payload to request.user (lines 58-63) - -**CurrentUser Decorator:** -- File: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/apps/chat/apps/backend/src/common/decorators/current-user.decorator.ts` -- Lines: 1-15 -- Interface: `CurrentUserData` (userId, email, role, sessionId) - -**Guard Application:** -- Controller-level: `@UseGuards(JwtAuthGuard)` -- Applied to: ConversationController, SpaceController, DocumentController, TemplateController, ChatController -- All protected routes use `@CurrentUser()` decorator correctly - -**Environment Variables:** -- `MANA_CORE_AUTH_URL` configured via ConfigService (default: `http://localhost:3001`) -- `DEV_BYPASS_AUTH` supported (line 16) -- Dev user ID: hardcoded `17cb0be7-058a-4964-9e18-1fe7055fd014` (line 5) - -**Issues Identified:** -1. Custom implementation duplicates code from shared packages -2. Non-standard dev user ID -3. No error logging for failed validations - -**Recommendation:** Migrate to `@manacore/shared-nestjs-auth` package - ---- - -### 2. Picture Backend - -**Integration Method:** Custom Implementation (Duplicated Code) -**Status:** COMPATIBLE - Functional but NOT standardized - -**Package Dependencies:** -- No shared auth packages imported -- Implements local `JwtAuthGuard` - -**Auth Implementation:** -- File: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts` -- Lines: 1-60 -- Validation Flow: - - Extracts Bearer token from Authorization header (line 57) - - NO DEV_BYPASS_AUTH support (differs from others) - - Calls `{MANA_CORE_AUTH_URL}/api/v1/auth/validate` (line 22) - - Maps response payload to request.user (lines 39-44) - -**CurrentUser Decorator:** -- File: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/apps/picture/apps/backend/src/common/decorators/current-user.decorator.ts` -- Lines: 1-15 -- Interface: `CurrentUserData` (userId, email, role, sessionId) - -**Guard Application:** -- Controller-level: `@UseGuards(JwtAuthGuard)` -- Applied to: GenerateController, BoardController, ImageController, ProfileController, etc. - -**Environment Variables:** -- `MANA_CORE_AUTH_URL` configured via ConfigService (default: `http://localhost:3001`) -- DEV_BYPASS_AUTH: NOT supported - -**Issues Identified:** -1. Custom implementation duplicates code -2. Missing dev bypass functionality -3. No dev user support (problematic for local testing) -4. No error logging - -**Recommendation:** Add dev bypass support and migrate to shared package - ---- - -### 3. Zitare Backend - -**Integration Method:** Standardized - Uses @manacore/shared-nestjs-auth -**Status:** FULLY COMPLIANT - -**Package Dependencies:** -```json -{ - "@manacore/shared-nestjs-auth": "workspace:*" -} -``` - -**Auth Implementation:** -- Package: `@manacore/shared-nestjs-auth` -- Guard: `JwtAuthGuard` (from shared package) -- Validation Flow: - - Calls `{MANA_CORE_AUTH_URL}/api/v1/auth/validate` - - Supports dev bypass via DEV_BYPASS_AUTH - - Extracts Bearer token correctly - -**Guard Application:** -- Controller-level: `@UseGuards(JwtAuthGuard)` -- Applied to: FavoriteController, ListController -- Uses: `@CurrentUser()` decorator from shared package - -**Controllers:** -- File: `apps/zitare/apps/backend/src/favorite/favorite.controller.ts` -- File: `apps/zitare/apps/backend/src/list/list.controller.ts` - -**Environment Variables:** -- Inherits from central `.env.development`: `MANA_CORE_AUTH_URL=http://localhost:3001` - -**Status:** No issues identified - best practice implementation - ---- - -### 4. Presi Backend - -**Integration Method:** Custom Implementation (Duplicated Code) -**Status:** COMPATIBLE - Functional but NOT standardized - -**Package Dependencies:** -- No shared auth packages imported -- Implements local `AuthGuard` - -**Auth Implementation:** -- File: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/apps/presi/apps/backend/src/auth/auth.guard.ts` -- Lines: 1-84 -- Validation Flow: - - Extracts Bearer token from Authorization header (lines 76-82) - - DEV_BYPASS_AUTH support (lines 17-28) - - Calls `{MANA_CORE_AUTH_URL}/api/v1/auth/validate` (line 42) - - Maps response payload to request.user (lines 59-64) - -**CurrentUser Parameter:** -- Uses raw `request.user` object directly (no decorator found) -- Injected via `@Request()` parameter in controllers -- Property access: `request.user.sub`, `request.user.email`, etc. - -**Guard Application:** -- Controller-level: `@UseGuards(AuthGuard)` -- Applied to: DeckController, SlideController, ShareController -- Access user via `@Request() request` parameter - -**Environment Variables:** -- `MANA_CORE_AUTH_URL` configured via ConfigService (default: `http://localhost:3001`) -- `DEV_BYPASS_AUTH` supported (line 19) -- Dev user ID: UUID `00000000-0000-0000-0000-000000000000` (line 23) - -**Issues Identified:** -1. Custom implementation duplicates code -2. No @CurrentUser decorator (inconsistent with other projects) -3. Uses `request.user` directly (less convenient) -4. No error logging - -**Recommendation:** Migrate to `@mana-core/nestjs-integration` for consistency - ---- - -### 5. ManaDeck Backend - -**Integration Method:** Standardized - Uses @mana-core/nestjs-integration -**Status:** FULLY COMPLIANT - Most Complete Implementation - -**Package Dependencies:** -```json -{ - "@mana-core/nestjs-integration": "workspace:*" -} -``` - -**Auth Implementation:** -- Package: `@mana-core/nestjs-integration` -- Guard: `AuthGuard` + `OptionalAuthGuard` -- Validation Flow: - - Calls `{MANA_CORE_AUTH_URL}/api/v1/auth/validate` - - Supports dev bypass via DEV_BYPASS_AUTH - - Extracts Bearer token correctly - - Provides enhanced features (credit system integration) - -**Guard Application:** -- File: `apps/manadeck/apps/backend/src/controllers/api.controller.ts` -- Uses: `@UseGuards(AuthGuard)` -- Uses: `@CurrentUser()` decorator from shared package -- Uses: `CreditClientService` for credit operations - -**Public Routes:** -- File: `apps/manadeck/apps/backend/src/controllers/public.controller.ts` -- Uses: `@UseGuards(OptionalAuthGuard)` -- Allows both authenticated and unauthenticated access - -**Module Setup:** -- File: `apps/manadeck/apps/backend/src/app.module.ts` -- Imports: `ManaCoreModule.forRootAsync()` -- Provides centralized configuration - -**Features:** -- AuthGuard with JwtAuthGuard + Public decorator support -- OptionalAuthGuard for public endpoints -- CurrentUser decorator for parameter injection -- CreditClientService integration -- Reflector support for public routes -- Enhanced error handling with debug mode - -**Environment Variables:** -- Inherits from central `.env.development`: `MANA_CORE_AUTH_URL=http://localhost:3001` -- App ID support: `MANADECK_APP_ID` -- Service key support: `MANA_CORE_SERVICE_KEY` - -**Status:** Best practice implementation with full feature set - ---- - -## JWT Validation Flow Analysis - -### Consistent Pattern Across All Backends - -All backends follow the same validation pattern: - -```typescript -// 1. Extract Bearer token -const [type, token] = authHeader.split(' '); -if (type !== 'Bearer') return unauthorized; - -// 2. Call mana-core-auth validate endpoint -POST /api/v1/auth/validate -{ - "token": "eyJhbGc..." -} - -// 3. Validate response -{ - "valid": true, - "payload": { - "sub": "user-id", - "email": "user@example.com", - "role": "user", - "sessionId": "session-id" - } -} - -// 4. Attach to request -request.user = { - userId: payload.sub, - email: payload.email, - role: payload.role, - sessionId: payload.sessionId || payload.sid -} -``` - -### mana-core-auth Validation Implementation - -**File:** `/Users/wuesteon/dev/mana_universe/manacore-monorepo/services/mana-core-auth/src/auth/services/better-auth.service.ts` - -**Method:** `validateToken()` (lines 786-831) - -**Flow:** -1. Decodes JWT header to check algorithm -2. Fetches JWKS from `/api/v1/auth/jwks` (EdDSA keys) -3. Uses jose library `jwtVerify()` for signature validation -4. Verifies issuer and audience claims -5. Returns payload on success or error message on failure - -**Endpoint:** `POST /api/v1/auth/validate` (auth.controller.ts, lines 123-127) - -**Algorithm:** EdDSA (Better Auth default, NOT RS256 or HS256) - -**Status:** Validation is correctly implemented using jose library with Better Auth's JWKS - ---- - -## Dev Mode Bypass Analysis - -### Implementation Comparison - -| Backend | Bypass Support | Condition | Dev User ID | -|---------|---|---|---| -| Chat | βœ“ Yes | NODE_ENV=dev AND DEV_BYPASS_AUTH=true | `17cb0be7-058a-4964-9e18-1fe7055fd014` | -| Picture | βœ— No | - | - | -| Zitare | βœ“ Yes | NODE_ENV=dev AND DEV_BYPASS_AUTH=true | `00000000-0000-0000-0000-000000000000` | -| Presi | βœ“ Yes | NODE_ENV=dev AND DEV_BYPASS_AUTH=true | `00000000-0000-0000-0000-000000000000` | -| ManaDeck | βœ“ Yes | NODE_ENV=dev AND DEV_BYPASS_AUTH=true | `00000000-0000-0000-0000-000000000000` | - -### Issue: Inconsistent Dev User IDs - -**Problem:** Chat backend uses non-standard dev user ID -- Chat: `17cb0be7-058a-4964-9e18-1fe7055fd014` -- Others: `00000000-0000-0000-0000-000000000000` - -**Impact:** Testing tools expecting standard dev user ID will fail with Chat backend - -**Location:** -- Chat: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts:5` - -**Configuration:** `.env.development` (line 59) -``` -DEV_BYPASS_AUTH=true -``` - ---- - -## Shared Package Analysis - -### 1. @manacore/shared-nestjs-auth - -**Location:** `/Users/wuesteon/dev/mana_universe/manacore-monorepo/packages/shared-nestjs-auth/` - -**Exports:** -- `JwtAuthGuard` - NestJS guard for JWT validation -- `CurrentUser` - Parameter decorator -- Type definitions - -**Implementation Details:** -- Guard: `src/guards/jwt-auth.guard.ts` -- Decorator: `src/decorators/current-user.decorator.ts` -- Types: `src/types/index.ts` - -**Features:** -- DEV_BYPASS_AUTH support -- Default dev user ID: `00000000-0000-0000-0000-000000000000` -- Calls mana-core-auth `/validate` endpoint -- Extracts Bearer tokens correctly - -**Used By:** -- Zitare backend - -**Status:** Lightweight, single-purpose, well-implemented - ---- - -### 2. @mana-core/nestjs-integration - -**Location:** `/Users/wuesteon/dev/mana_universe/manacore-monorepo/packages/mana-core-nestjs-integration/` - -**Exports:** -- `AuthGuard` - Enhanced JWT guard with public route support -- `OptionalAuthGuard` - For endpoints allowing anonymous access -- `CurrentUser` - Parameter decorator with field extraction -- `ManaCoreModule` - NestJS module with configuration -- `CreditClientService` - Credit deduction service -- Type definitions - -**Implementation Details:** -- Main Guard: `src/guards/auth.guard.ts` -- Optional Guard: `src/guards/optional-auth.guard.ts` -- Decorator: `src/decorators/current-user.decorator.ts` -- Public Decorator: `src/decorators/public.decorator.ts` -- Module: `src/mana-core.module.ts` -- Credit Service: `src/services/credit-client.service.ts` - -**Features:** -- DEV_BYPASS_AUTH support -- Default dev user ID: `00000000-0000-0000-0000-000000000000` -- Calls mana-core-auth `/validate` endpoint -- Reflector support for public routes via `@Public()` decorator -- CurrentUser decorator supports field extraction: `@CurrentUser('email')` -- Credit system integration -- Debug mode support -- App ID tracking -- Access token preservation in request object - -**Used By:** -- ManaDeck backend - -**Status:** Full-featured, production-ready, enterprise-grade - ---- - -## Compatibility Matrix - -| Backend | Package | Compatible | Works | Issues | -|---------|---------|---|---|---| -| Chat | Custom | βœ“ Yes | βœ“ Yes | Non-standard dev user ID, code duplication | -| Picture | Custom | βœ“ Yes | βœ“ Yes | No dev bypass, code duplication | -| Zitare | shared-nestjs-auth | βœ“ Yes | βœ“ Yes | None | -| Presi | Custom | βœ“ Yes | βœ“ Yes | No decorator, code duplication | -| ManaDeck | nestjs-integration | βœ“ Yes | βœ“ Yes | None | - ---- - -## Error Handling Consistency - -### Good Practices Observed -- All backends throw `UnauthorizedException` for invalid tokens -- All backends extract tokens correctly -- All backends handle response parsing safely - -### Issues Identified -1. Picture backend doesn't support development mode at all -2. Chat backend logs errors but uses inconsistent format -3. Presi backend doesn't include @CurrentUser decorator -4. Custom implementations lack consistent error messages - ---- - -## Recommendations - -### Priority 1 (Critical) - -1. **Standardize Dev User ID** - - Update Chat backend to use `00000000-0000-0000-0000-000000000000` - - File: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts:5` - - Current: `17cb0be7-058a-4964-9e18-1fe7055fd014` - -2. **Add Dev Bypass to Picture** - - Implement DEV_BYPASS_AUTH support in Picture backend - - Matches pattern used in other backends - -### Priority 2 (High) - -1. **Migrate Chat to @manacore/shared-nestjs-auth** - - Remove custom guard - - Use shared package - - Reduces maintenance burden - - Benefit: Code reuse, consistency - -2. **Migrate Picture to @manacore/shared-nestjs-auth** - - Remove custom guard - - Use shared package - - Adds dev bypass support - - Benefit: Code reuse, consistency, dev mode support - -3. **Migrate Presi to @mana-core/nestjs-integration** - - Remove custom auth guard - - Use shared package - - Add @CurrentUser decorator - - Benefit: Code reuse, consistency, public route support - -### Priority 3 (Medium) - -1. **Enhance Error Logging** - - Add consistent error logging across all backends - - Include user ID in error logs for debugging - - Track failed validation attempts - -2. **Document Integration Pattern** - - Create integration guide for new backends - - Specify which package to use based on requirements - - Add code examples - ---- - -## Token Structure Verification - -### JWT Header (EdDSA) -```json -{ - "alg": "EdDSA", - "typ": "JWT", - "kid": "key-id" -} -``` - -### JWT Payload -```json -{ - "sub": "user-id", - "email": "user@example.com", - "role": "user", - "sid": "session-id", - "iss": "manacore", - "aud": "manacore", - "iat": 1699999999, - "exp": 1700000899 -} -``` - -### Validation Endpoint -- **URL:** `POST /api/v1/auth/validate` -- **Port:** 3001 (default) -- **Request:** `{ "token": "eyJhbGc..." }` -- **Response Success:** `{ "valid": true, "payload": {...} }` -- **Response Error:** `{ "valid": false, "error": "message" }` - ---- - -## Summary Table - -| Aspect | Chat | Picture | Zitare | Presi | ManaDeck | -|--------|------|---------|--------|-------|----------| -| **Integration** | Custom | Custom | Shared | Custom | Shared | -| **Guard Name** | JwtAuthGuard | JwtAuthGuard | JwtAuthGuard | AuthGuard | AuthGuard | -| **Dev Bypass** | βœ“ | βœ— | βœ“ | βœ“ | βœ“ | -| **Decorator** | βœ“ @CurrentUser | βœ“ @CurrentUser | βœ“ @CurrentUser | βœ— (uses @Request) | βœ“ @CurrentUser | -| **Public Support** | βœ— | βœ— | βœ— | βœ— | βœ“ @Public | -| **Credit System** | βœ— | βœ— | βœ— | βœ— | βœ“ | -| **Validation** | βœ“ | βœ“ | βœ“ | βœ“ | βœ“ | -| **Status** | Works, Migrate | Works, Add Dev, Migrate | Best | Works, Migrate | Best | - ---- - -## Validation Conclusion - -**Overall Status:** PASSED WITH RECOMMENDATIONS - -All backends are currently functional and compatible with mana-core-auth JWT validation. The validation flow is correctly implemented across all projects. However, implementing the recommendations would significantly improve code quality, maintainability, and consistency across the ecosystem. - -**Next Steps:** -1. Implement Priority 1 fixes (standardize dev user ID, add dev bypass to Picture) -2. Plan migration timeline for Priority 2 items -3. Document integration patterns for future backends - diff --git a/MANACORE-TODOS.md b/MANACORE-TODOS.md deleted file mode 100644 index 4b8920ba1..000000000 --- a/MANACORE-TODOS.md +++ /dev/null @@ -1,423 +0,0 @@ -# Manacore App - Entwicklungs-Roadmap - -> Erstellt am: 2024-12-05 -> Status: Aktive Entwicklung - -## Inhaltsverzeichnis - -- [Aktueller Stand](#aktueller-stand) -- [Kritische TODOs](#kritische-todos-hohe-prioritΓ€t) -- [Mittlere PrioritΓ€t](#mittlere-prioritΓ€t) -- [Nice-to-have](#niedrige-prioritΓ€t-nice-to-have) -- [Empfohlene Reihenfolge](#empfohlene-reihenfolge) - ---- - -## Aktueller Stand - -### Vorhandene Features - -| Feature | Status | Beschreibung | -| -------------- | ------ | --------------------------------------------- | -| Dashboard | βœ… | Anpassbare Widgets, Drag & Drop | -| Credits-System | βœ… | Übersicht, Transaktionen, Pakete, Stripe-Kauf | -| Teams | βœ… | Team-Verwaltung | -| Organizations | βœ… | Organisations-Verwaltung | -| Settings | βœ… | Benutzereinstellungen | -| Themes | βœ… | Theme-Auswahl | -| Feedback | βœ… | Feedback-Formular | -| Profil | βœ… | Basis-Profil-Ansicht | -| i18n | βœ… | 5 Sprachen (DE, EN, ES, FR, IT) | -| Apps-Übersicht | βœ… | Alle Mana-Apps anzeigen | - -### Dashboard-Widgets (6 Typen) - -| Widget | Status | -| ------------------ | ------ | -| Credits | βœ… | -| Tasks Today | βœ… | -| Calendar Events | βœ… | -| Quick Actions | βœ… | -| Chat Recent | βœ… | -| Contacts Favorites | βœ… | - -### API-Integrationen - -| Service | Status | Datei | -| -------- | ------ | ------------------------------ | -| Calendar | βœ… | `lib/api/services/calendar.ts` | -| Chat | βœ… | `lib/api/services/chat.ts` | -| Contacts | βœ… | `lib/api/services/contacts.ts` | -| Todo | βœ… | `lib/api/services/todo.ts` | -| Zitare | βœ… | `lib/api/services/zitare.ts` | -| Credits | βœ… | `lib/api/credits.ts` | - ---- - -## Kritische TODOs (Hohe PrioritΓ€t) - -### 1. βœ… Stripe-Integration fΓΌr Credit-Kauf (ERLEDIGT) - -**Status:** Abgeschlossen am 2026-02-13 - -**Implementiert:** - -- [x] Stripe SDK integrieren (`@stripe/mcp` v17.5.0) -- [x] `StripeService` fΓΌr PaymentIntent-Erstellung -- [x] `POST /credits/purchase` Endpoint -- [x] Webhook-Handler fΓΌr `payment_intent.succeeded`/`payment_intent.payment_failed` -- [x] Credit-Gutschrift nach erfolgreicher Zahlung (idempotent) -- [x] Stripe MCP Server eingerichtet (OAuth-basiert) -- [x] Test-Pakete angelegt (Starter, Basic, Pro, Ultra) - -**Credit-Pakete:** - -| Paket | Credits | Preis | Hinweis | -| ------- | ------- | ------ | ----------------------- | -| Starter | 100 | €1,00 | 1 Mana = 1 Cent (immer) | -| Basic | 500 | €5,00 | Kein Mengenrabatt | -| Pro | 1.500 | €15,00 | Kein Mengenrabatt | -| Ultra | 5.000 | €50,00 | Kein Mengenrabatt | - -> **Preisregel:** 1 Mana = 1 Cent. Keine Rabatte fΓΌr grâßere Pakete. - -**Dateien:** - -- `services/mana-core-auth/src/stripe/` - Stripe-Module -- `services/mana-core-auth/src/credits/credits.service.ts` - Purchase-Methoden - -**Frontend (Implementiert 2026-02-13):** - -- [x] Credits-Seite: Stripe Checkout Integration -- [x] Loading-States und Toast-Benachrichtigungen - -**Rechnungs-PDFs:** - -- [x] Stripe Invoice PDFs werden automatisch ΓΌber Webhooks synchronisiert (`invoicePdfUrl`) - ---- - -### 2. βœ… App-Config aktualisieren (ERLEDIGT) - -**Status:** Bereits vollstΓ€ndig implementiert - -**Datei:** `apps/manacore/apps/web/src/lib/config/apps.ts` - -**Alle Apps konfiguriert:** - -| Kategorie | Apps | -| ------------ | ------------------------------------------- | -| Core | manacore | -| AI-Powered | chat, picture, presi, mail | -| Productivity | manadeck, todo, calendar, contacts, finance | -| Utility | clock, zitare, storage, moodlit | - -Archivierte Apps (memoro, storyteller) wurden bereits entfernt. - ---- - -### 3. βœ… Dashboard-Widgets erweitern (GRΓ–SSTENTEILS ERLEDIGT) - -**Status:** 13 von 15 Widgets implementiert (Finance + Mail fehlen) - -**Existierende Widgets (13 Typen):** - -| Widget | App | Status | -| ----------------------- | -------------- | ------ | -| CreditsWidget | mana-core-auth | βœ… | -| TransactionsWidget | mana-core-auth | βœ… | -| QuickActionsWidget | core | βœ… | -| TasksTodayWidget | todo | βœ… | -| TasksUpcomingWidget | todo | βœ… | -| CalendarEventsWidget | calendar | βœ… | -| ChatRecentWidget | chat | βœ… | -| ContactsFavoritesWidget | contacts | βœ… | -| ZitareQuoteWidget | zitare | βœ… | -| PictureRecentWidget | picture | βœ… | -| ManadeckProgressWidget | manadeck | βœ… | -| ClockTimersWidget | clock | βœ… | -| StorageUsageWidget | storage | βœ… | - -**Neue Widgets (2026-02-13):** - -- [x] StorageUsageWidget - Speichernutzung und letzte Dateien - -**Noch offen (Backend fehlt noch):** - -- [ ] FinanceBalanceWidget (finance Backend nΓΆtig) -- [ ] MailInboxWidget (mail Backend nΓΆtig) - ---- - -### 4. βœ… Profil-Features vervollstΓ€ndigen (Backend ERLEDIGT) - -**Status:** Backend implementiert am 2026-02-13 - -**Implementierte Backend-Endpoints:** - -| Endpoint | Methode | Beschreibung | -| ----------------------- | ------- | ---------------------------------------------------- | -| `/auth/profile` | GET | Profil-Daten abrufen | -| `/auth/profile` | POST | Profil aktualisieren (Name, Bild) | -| `/auth/change-password` | POST | Passwort Γ€ndern (mit aktuellem Passwort) | -| `/auth/account` | DELETE | Konto lΓΆschen (Soft-Delete mit Passwort-BestΓ€tigung) | - -**Feature-Status:** - -| Feature | Backend | Frontend | PrioritΓ€t | -| ----------------- | ------- | -------- | --------- | -| Profil bearbeiten | βœ… | βœ… | Hoch | -| Passwort Γ€ndern | βœ… | βœ… | Hoch | -| Konto lΓΆschen | βœ… | βœ… | Mittel | -| Avatar hochladen | βœ… | βœ… | Niedrig | -| 2FA aktivieren | ❌ | ❌ | Niedrig | - -**Dateien:** - -- `services/mana-core-auth/src/auth/auth.controller.ts` - Endpoints -- `services/mana-core-auth/src/auth/services/better-auth.service.ts` - Service-Methoden -- `services/mana-core-auth/src/auth/dto/update-profile.dto.ts` - Profil-Update DTO -- `services/mana-core-auth/src/auth/dto/change-password.dto.ts` - Passwort-Γ„ndern DTO -- `services/mana-core-auth/src/auth/dto/delete-account.dto.ts` - Konto-LΓΆschen DTO - -**Frontend (Implementiert 2026-02-13):** - -- [x] Profil-Edit Modal erstellt (`EditProfileModal.svelte`) -- [x] Passwort-Γ„ndern Dialog erstellt (`ChangePasswordModal.svelte`) -- [x] Konto-LΓΆschung mit BestΓ€tigung (`DeleteAccountModal.svelte`) - -**Avatar-Upload (Implementiert 2026-02-13):** - -- [x] Storage-Modul fΓΌr S3/MinIO (`services/mana-core-auth/src/storage/`) -- [x] Presigned URL Endpoint: `POST /api/v1/storage/avatar/upload-url` -- [x] Direct Upload Endpoint: `POST /api/v1/storage/avatar` -- [x] `manacore-storage` Bucket konfiguriert -- [x] Frontend-Integration (EditProfileModal mit Avatar-Picker und Presigned-URL-Upload) - ---- - -## Mittlere PrioritΓ€t - -### 5. Benachrichtigungen/Notifications - -**Beschreibung:** Zentrales Benachrichtigungssystem fΓΌr alle Apps - -**Use Cases:** - -- Kalender-Erinnerungen (15 min vor Termin) -- Todo-Deadlines (Heute fΓ€llig) -- Credit-Warnungen (< 10 Credits) -- Neue Chat-Nachrichten -- Manadeck (Karten zum Lernen) - -**Aufgaben:** - -- [ ] Notification-Service erstellen -- [ ] Push-Notification Setup (Web Push API) -- [ ] Notification-Center UI -- [ ] Einstellungen pro Notification-Typ -- [ ] Backend: Notification-Queue - -**GeschΓ€tzter Aufwand:** 3-5 Tage - ---- - -### 6. βœ… Subscription/Plan-Management (Backend ERLEDIGT) - -**Status:** Backend implementiert am 2026-02-13 - -**Implementiert:** - -- [x] DB-Schema: `subscriptions.plans`, `subscriptions.subscriptions`, `subscriptions.invoices` -- [x] `SubscriptionsService` mit Checkout, Portal, Cancel, Reactivate -- [x] `SubscriptionsController` mit REST-Endpoints -- [x] Stripe Checkout Session fΓΌr Subscriptions -- [x] Stripe Customer Portal Integration (Self-Service Billing) -- [x] Webhook-Handler fΓΌr Subscription/Invoice Events -- [x] PlΓ€ne angelegt (Free, Pro, Enterprise) - -**Subscription-PlΓ€ne:** - -| Plan | Mana/Monat | Monatlich | JΓ€hrlich | Features | -| ---------- | ---------- | --------- | -------- | --------------------------------------- | -| Free | 150 | €0 | €0 | Basis-Features, Community Support | -| Pro | 1.500 | €9,99 | €99,90 | Alle Features, Priority Support, API | -| Enterprise | 10.000 | €49,99 | €499,90 | SSO, Audit Logs, SLA, Dedicated Support | - -**API-Endpoints:** - -``` -GET /api/v1/subscriptions/plans # Alle PlΓ€ne -GET /api/v1/subscriptions/current # Aktuelles Abo -POST /api/v1/subscriptions/checkout # Stripe Checkout starten -POST /api/v1/subscriptions/portal # Billing Portal ΓΆffnen -POST /api/v1/subscriptions/cancel # KΓΌndigen -POST /api/v1/subscriptions/reactivate # Reaktivieren -GET /api/v1/subscriptions/invoices # Rechnungen -``` - -**Frontend (Implementiert 2026-02-13):** - -- [x] Plan-Übersicht Seite im Frontend (`/subscription`) -- [x] Plan-Vergleichs-UI mit monatlich/jΓ€hrlich Toggle -- [x] Stripe Checkout Integration fΓΌr Subscriptions -- [x] Billing Portal Integration -- [x] RechnungsΓΌbersicht -- [x] Subscription-Plans Seed-Script erstellt (`pnpm db:seed:plans`) -- [ ] Stripe Products/Prices erstellen und ENV-Variablen setzen - ---- - -### 7. API-Keys Verwaltung - -**Beschreibung:** FΓΌr Entwickler/Power-User API-Zugang ermΓΆglichen - -**Features:** - -- API-Key generieren -- Key-Liste mit Berechtigungen -- Key widerrufen -- Usage-Statistiken pro Key - -**Aufgaben:** - -- [ ] API-Keys Seite erstellen -- [ ] Backend: Key-Generation -- [ ] Scopes/Berechtigungen definieren -- [ ] Rate-Limiting pro Key - -**GeschΓ€tzter Aufwand:** 2-3 Tage - ---- - -### 8. βœ… Onboarding-Flow (ERLEDIGT) - -**Status:** Implementiert am 2026-02-13 - -**Beschreibung:** Welcome-Wizard fΓΌr neue Benutzer - -**Implementierte Schritte:** - -1. Willkommen & Kurze EinfΓΌhrung (WelcomeStep) -2. Profil vervollstΓ€ndigen - Name, Avatar (ProfileStep) -3. Apps-Übersicht - alle Mana-Apps zeigen (AppsStep) -4. Credits-System erklΓ€ren (CreditsStep) -5. Fertig - Quick Actions zum Start (CompleteStep) - -**Aufgaben:** - -- [x] Onboarding-Store (`lib/stores/onboarding.svelte.ts`) -- [x] OnboardingWizard Komponente mit Step-Navigation -- [x] 5 Step-Komponenten (Welcome, Profile, Apps, Credits, Complete) -- [x] Progress-Tracking (LocalStorage-basiert) -- [x] Skip-Option -- [x] Integration in App-Layout (zeigt Wizard fΓΌr neue User) - -**Dateien:** - -- `apps/manacore/apps/web/src/lib/stores/onboarding.svelte.ts` -- `apps/manacore/apps/web/src/lib/components/onboarding/OnboardingWizard.svelte` -- `apps/manacore/apps/web/src/lib/components/onboarding/steps/*.svelte` - ---- - -## Niedrige PrioritΓ€t (Nice-to-have) - -### 9. Mobile App aktivieren - -**Beschreibung:** Die Mobile App (`apps/mobile`) existiert, aber scheint nicht aktiv genutzt - -**Status:** Expo-Projekt vorhanden, aber mΓΆglicherweise veraltet - -**Aufgaben:** - -- [ ] Dependencies aktualisieren -- [ ] FunktionalitΓ€t mit Web-App abgleichen -- [ ] Auth-Flow testen -- [ ] App Store Submission vorbereiten - ---- - -### 10. DSGVO-konformer Daten-Export - -**Beschreibung:** Benutzer kΓΆnnen alle ihre Daten exportieren - -**Features:** - -- "Meine Daten exportieren" Button -- ZIP mit allen Daten (JSON/CSV) -- Inkl. aller App-Daten -- Account-Migration zu anderer Instanz - -**Aufgaben:** - -- [ ] Export-Job Backend -- [ ] Download-Link per E-Mail -- [ ] Fortschrittsanzeige - ---- - -### 11. AktivitΓ€ts-Feed - -**Beschreibung:** Übergreifende Timeline aller AktivitΓ€ten - -**Features:** - -- "Was habe ich heute gemacht?" -- Filter nach App -- Zeitraum-Auswahl -- Export als Report - ---- - -### 12. Keyboard Shortcuts - -**Beschreibung:** Power-User Shortcuts - -**Shortcuts:** - -- `Cmd/Ctrl + K` - Quick Search/Command Palette -- `Cmd/Ctrl + 1-9` - Schnellzugriff auf Apps -- `Cmd/Ctrl + N` - Neue Aktion (kontextabhΓ€ngig) - ---- - -## Empfohlene Reihenfolge - -| # | Task | Aufwand | Impact | Status | -| --- | --------------------------- | -------- | -------- | ----------- | -| 1 | App-Config aktualisieren | 2-4h | Hoch | βœ… Erledigt | -| 2 | Stripe-Integration | 2-3 Tage | Kritisch | βœ… Erledigt | -| 3 | Dashboard-Widgets erweitern | 1-2 Tage | Hoch | βœ… Erledigt | -| 4 | Profil-Features | 1-2 Tage | Mittel | βœ… Erledigt | -| 5 | Notifications | 3-5 Tage | Hoch | ⏳ Offen | -| 6 | Onboarding | 2-3 Tage | Mittel | βœ… Erledigt | -| 7 | Subscription-Management | 2-3 Tage | Mittel | βœ… Erledigt | -| 8 | API-Keys | 2-3 Tage | Niedrig | ⏳ Offen | - ---- - -## Quick Wins (< 1 Stunde) - -Diese Tasks kΓΆnnen schnell erledigt werden: - -- [ ] Archivierte Apps aus `apps.ts` entfernen -- [ ] Deutsche Übersetzungen vervollstΓ€ndigen -- [ ] "Coming Soon" Badges fΓΌr fehlende Features -- [ ] Loading-States verbessern -- [ ] Error-Handling mit Toast-Notifications - ---- - -## Technische Schulden - -| Issue | PrioritΓ€t | Beschreibung | -| ------------------------- | --------- | ------------------------------ | -| Supabase β†’ mana-core-auth | Hoch | Auth-Migration abschließen | -| Tests fehlen | Mittel | Unit/E2E Tests hinzufΓΌgen | -| TypeScript strict mode | Niedrig | Strikte Typisierung aktivieren | -| Bundle-Size | Niedrig | Tree-shaking optimieren | - ---- - -_Zuletzt aktualisiert: 2026-02-13 (Avatar-Upload Frontend + Onboarding-Flow implementiert)_ diff --git a/MERGE-FIX-SUMMARY.md b/MERGE-FIX-SUMMARY.md deleted file mode 100644 index 258264dd7..000000000 --- a/MERGE-FIX-SUMMARY.md +++ /dev/null @@ -1,357 +0,0 @@ -# dev-1 Merge Fix Summary - -**Date:** 2025-12-05 -**Objective:** Fix TypeScript errors after merging dev-1 into dev -**Status:** βœ… **COMPLETE - All Issues Resolved** - ---- - -## 🎯 Executive Summary - -Successfully fixed all TypeScript errors introduced during the dev-1 merge. The monorepo now passes type-check with **84/84 packages** (excluding games directory). - -### Key Achievements - -- βœ… **42 TypeScript errors fixed** in @context/mobile -- βœ… **84/84 packages passing** type-check (100% success rate) -- βœ… Games directory excluded from CI checks (55 pre-existing errors in @worldream/web can be fixed separately) -- βœ… Lint configuration fixed for @context/mobile -- βœ… Root package.json updated with proper type-check filters - ---- - -## πŸ“Š Issues Fixed - -### Primary Issue: @context/mobile TypeScript Errors - -The `@context/mobile` package had 42 TypeScript errors from a recent web-to-mobile migration. These were the **only** blocking errors in the entire monorepo. - -#### Error Breakdown by Phase - -| Phase | Category | Errors Fixed | Time | Status | -| ------------- | -------------------------- | ------------ | ---------- | ----------- | -| **Phase 1** | Missing @types/node | 11 | 5 min | βœ… Complete | -| **Phase 2** | Platform incompatibilities | 16 | 2 hrs | βœ… Complete | -| **Phase 3-5** | Component types & logic | 15 | 2 hrs | βœ… Complete | -| **Total** | **All categories** | **42** | **~4 hrs** | βœ… Complete | - ---- - -## πŸ”§ Detailed Fixes - -### Phase 1: Foundation (11 errors - 5 minutes) - -**Issue:** Missing Node.js type definitions -**Solution:** Installed `@types/node` dev dependency - -```bash -cd apps/context/apps/mobile -pnpm add -D @types/node -``` - -**Files affected:** - -- `services/aiService.ts` (4 errors) -- `services/supabase.ts` (3 errors) -- `hooks/useAutoSave.ts` (2 errors) -- `utils/debounce.ts` (1 error) -- `components/common/Skeleton.tsx` (1 error) - ---- - -### Phase 2: Platform Incompatibilities (16 errors - 2 hours) - -**Issue:** Web-specific code incompatible with React Native -**Solution:** Removed hover states and invalid CSS properties - -#### A. Removed `hovered` Property (12 errors) - -React Native Pressable doesn't support hover states. Removed all `hovered` destructuring: - -**Before:** - -```typescript -style={({ hovered, pressed }) => ({ - opacity: pressed ? 0.8 : hovered ? 0.9 : 1 -})} -``` - -**After:** - -```typescript -style={({ pressed }) => ({ - opacity: pressed ? 0.8 : 1 -})} -``` - -**Files fixed:** - -- `components/ai/SpacesLLMToolbar.tsx` (3 errors) -- `components/navigation/Breadcrumbs.tsx` (4 errors) -- `components/ai/BottomLLMToolbar.tsx` (2 errors) -- `components/documents/DocumentHeader.tsx` (2 errors) -- `components/spaces/InlineSpaceCreator.tsx` (1 error) - -#### B. Fixed Invalid CSS Properties (4 errors) - -Replaced web CSS with React Native equivalents: - -| Invalid CSS | React Native Equivalent | -| ------------------- | ------------------------- | -| `position: 'fixed'` | `position: 'absolute'` | -| `overflowX: 'auto'` | `overflow: 'scroll'` | -| `outline: 'none'` | ❌ Remove (not supported) | - -**Files fixed:** - -- `components/ai/SpacesLLMToolbar.tsx` (3 errors) -- `styles/documentStyles.ts` (1 error) - ---- - -### Phase 3-5: Component Types & Logic (15 errors - 2 hours) - -#### A. AppLayout Route Handling (4 errors) - -**Issue:** `useSegments()` returns typed tuples, causing index access errors -**Solution:** Cast to `string[]` for dynamic access - -**File:** `components/layout/AppLayout.tsx` - -```typescript -// Before -const segments = useSegments(); -if (segments[1] === 'documents') // Error: Typed tuple - -// After -const segments = useSegments() as string[]; -if (segments[1] === 'documents') // βœ… Works -``` - -#### B. DocumentEditor Props (5 errors) - -**Issue:** Component props mismatches and incorrect interfaces -**Solution:** Updated prop names and interfaces - -**File:** `components/documents/DocumentEditor.tsx` - -Changes: - -- `DocumentTagsEditor`: Changed `onTagsUpdate` β†’ `onTagsChange` -- `BottomLLMToolbar`: Updated to use `isGenerating`/`setIsGenerating` props -- `VariantCreator`: Fixed props (`documentContent`, `spaceId`, `onVariantCreated`) -- Removed unsupported `className` props - -#### C. DocumentHeader Simplification (2 errors) - -**Issue:** Complex toolbar with incompatible props -**Solution:** Simplified to show only breadcrumbs - -**File:** `components/documents/DocumentHeader.tsx` - -#### D. BatchDocumentCreator Type Fixes (3 errors) - -**Issue:** Document type mismatches and incorrect object structures -**Solution:** Fixed type literals and API calls - -**File:** `components/spaces/BatchDocumentCreator.tsx` - -Changes: - -- Updated document types: `'original'/'generated'` β†’ `'text'/'context'/'prompt'` -- Fixed `generateText()` return value extraction (`.text` property) -- Corrected `createDocument()` call signature - -#### E. PromptEditor AIGenerationResult (1 error) - -**Issue:** Passing entire object instead of extracting text -**Solution:** Changed to `result.text` - -**File:** `components/ai/PromptEditor.tsx` - ---- - -## πŸ—‚οΈ Configuration Changes - -### 1. Root package.json - -**Added type-check filter** to exclude games directory: - -```json -{ - "scripts": { - "type-check": "turbo run type-check --filter='./apps/**' --filter='./packages/**' --filter='./services/**'", - "type-check:all": "turbo run type-check" - } -} -``` - -**Rationale:** - -- Games directory (@worldream/web) has 55 pre-existing TypeScript errors unrelated to the merge -- Can be fixed in a separate task -- Core infrastructure remains 100% type-safe - -### 2. @context/mobile Lint Configuration - -**Simplified lint script** to use only Prettier: - -```json -{ - "scripts": { - "lint": "prettier -c \"**/*.{js,jsx,ts,tsx,json}\"" - } -} -``` - -**Rationale:** - -- ESLint config (`universe/native`) was ignoring all files -- Prettier provides sufficient formatting validation -- ESLint can be configured properly in a follow-up - ---- - -## πŸ“ˆ Results - -### Type-Check Status - -``` -βœ… 84/84 packages passing (100%) -⏱️ Execution time: 8.856s -πŸ“¦ Packages scoped to: apps/, packages/, services/ -``` - -### Packages Summary - -| Category | Count | Status | -| ----------------------- | ------ | --------------------- | -| **NestJS Backends** | 6 | βœ… All passing | -| **SvelteKit Web Apps** | 8 | βœ… All passing | -| **Expo Mobile Apps** | 7 | βœ… All passing | -| **Astro Landing Pages** | 7 | βœ… All passing | -| **Shared Packages** | 56 | βœ… All passing | -| **Services** | 1 | βœ… Passing | -| **TOTAL** | **84** | βœ… **100% Pass Rate** | - ---- - -## 🚫 Excluded from Checks - -### Games Directory - -| Package | Errors | Status | -| ----------------- | --------- | ------------------------------------ | -| `@worldream/web` | 55 errors | ⚠️ Pre-existing (can fix separately) | -| `@voxel-lava/web` | Skipped | ⚠️ Auth migration needed | - -**These errors are unrelated to the dev-1 merge** and were present before the merge. - ---- - -## πŸ” Historical Context - -### What Changed in dev-1 Merge - -Based on git analysis, the dev-1 branch introduced: - -1. **New Project:** `@context/mobile` - AI-powered document management app -2. **New Game:** `@worldream/web` - World-building platform -3. **CI/CD Changes:** Streamlined workflows (some disabled) -4. **ESLint Infrastructure:** Centralized config in `packages/eslint-config/` -5. **Turbo Fixes:** Removed recursive turbo calls that caused infinite loops - -### Root Cause of Errors - -The @context/mobile app was migrated from a web codebase and contained: - -- Web-specific JavaScript patterns (`process.env`, hover states) -- Invalid CSS properties for React Native -- Component prop mismatches from hasty integration - ---- - -## βœ… Verification Commands - -Run these commands to verify the fixes: - -```bash -# Type-check (excluding games) -pnpm type-check -# Expected: 84/84 packages passing - -# Type-check everything (including games) -pnpm type-check:all -# Expected: 83/98 passing (@worldream/web fails) - -# Type-check only context mobile -pnpm --filter @context/mobile type-check -# Expected: 0 errors - -# Lint (with warnings acceptable) -pnpm lint -# Expected: Mostly warnings, no critical errors -``` - ---- - -## πŸ“ Recommendations - -### Short-term (Optional) - -1. **Fix worldream errors** - 55 errors can be fixed following same patterns: - - Add null checks for `node` variables - - Fix undefined parameter guards - - Address accessibility warnings - -2. **Re-enable proper ESLint for @context/mobile**: - - Create `eslint.config.js` with proper ignores - - Or switch to monorepo-wide ESLint config from `packages/eslint-config/` - -### Long-term (Future Improvements) - -1. **Add pre-commit hooks** for type-check (already in Husky) -2. **CI/CD Pipeline** should run `pnpm type-check` on PRs -3. **Restore full CI workflows** that were simplified in dev-1 -4. **Documentation** for platform-specific patterns (web vs mobile) - ---- - -## πŸŽ‰ Conclusion - -The dev-1 merge issues have been **completely resolved**. All 42 TypeScript errors in @context/mobile are fixed, and the monorepo now has a **100% type-check pass rate** for all active packages. - -### Time Investment - -- **Analysis:** 30 minutes (swarm coordination) -- **Execution:** 4 hours (agent-based fixes) -- **Verification:** 30 minutes (testing & validation) -- **Total:** ~5 hours - -### Outcome - -βœ… Clean type-check across 84 packages -βœ… Zero breaking changes to existing code -βœ… Games excluded properly (fix separately) -βœ… Configuration updated for future maintenance - -**The codebase is now ready for continued development!** - ---- - -## πŸ“š Artifacts Created - -The swarm generated the following documentation during the fix process: - -1. `.claude-flow/TYPE_FIX_PLAN.md` - Detailed 5-phase fix plan -2. `.claude-flow/SWARM_COORDINATION_REPORT.md` - Executive summary -3. `.claude-flow/TYPE_FIXER_QUICKSTART.md` - Quick reference guide -4. `.claude-flow/type-errors-manifest.json` - Machine-readable error list -5. `HISTORICAL-ANALYSIS.md` - Git history comparison (dev vs dev-1) -6. **This file:** `MERGE-FIX-SUMMARY.md` - Comprehensive final report - ---- - -**Report generated by Claude Code Swarm** -**Execution Mode:** Centralized coordination with specialized agents -**Agent Types:** Type-Check Analyst, Historical Analyst, Coordinator, Component Fixer diff --git a/QA_TESTING_CHECKLIST.md b/QA_TESTING_CHECKLIST.md deleted file mode 100644 index 9406a4b7c..000000000 --- a/QA_TESTING_CHECKLIST.md +++ /dev/null @@ -1,477 +0,0 @@ -# QA Testing Checklist: Authentication & Credit System - -**Quick Reference for QA Engineers** -**Version:** 1.0 -**Last Updated:** 2025-11-25 - ---- - -## Pre-Testing Setup - -### Environment Verification -- [ ] Development environment configured -- [ ] Test user accounts created (test+user1@manacore.com, test+user2@manacore.com) -- [ ] Mock payment gateway configured (no real charges) -- [ ] Database seeded with test data -- [ ] Browser DevTools / React Native Debugger ready - -### Test Data -```javascript -Test Users: -- test+user1@manacore.com (password: Test123!@#, credits: 1000) -- test+user2@manacore.com (password: Test123!@#, credits: 0) -- test+b2b@manacore.com (password: Test123!@#, B2B account) - -Credit Packages: -- Small: 100 credits for €4.99 -- Medium: 500 credits for €19.99 -- Large: 1000 credits for €34.99 -``` - ---- - -## Authentication Testing Checklist - -### Registration Flow -- [ ] **New User Registration (Email/Password)** - - Valid email and strong password β†’ Account created - - Weak password β†’ Error message with requirements - - Duplicate email β†’ "Email already in use" error - - Invalid email format β†’ Validation error - - Network timeout β†’ Retry mechanism works - -- [ ] **Google Sign-In** - - First-time user β†’ Account created with Google profile - - Returning user β†’ Logged into existing account - - Invalid token β†’ Error message - - Email conflict β†’ Account linking - -- [ ] **Apple Sign-In** - - First-time user β†’ Account created - - Private relay email β†’ Handled correctly - - Returning user β†’ Logged in successfully - -### Login Flow -- [ ] **Successful Login** - - Valid credentials β†’ Logged in, tokens stored - - User redirected to home screen - - Credit balance visible - -- [ ] **Failed Login** - - Invalid password β†’ "Invalid credentials" error - - Non-existent email β†’ "Invalid credentials" error - - Email not verified β†’ "Email not verified" error - -- [ ] **Session Persistence** - - Close app completely - - Reopen app β†’ User still logged in - - No re-login required - -### Logout Flow -- [ ] **Standard Logout** - - Click logout button - - Tokens cleared from storage - - User redirected to login screen - - Old tokens no longer work (401 error on API calls) - -- [ ] **Logout with Network Failure** - - Disable network - - Click logout - - Local tokens still cleared - - User marked as logged out in UI - -### Token Refresh -- [ ] **Automatic Token Refresh** - - Wait for token to expire (or manually expire) - - Make API call - - Verify automatic refresh triggered - - API call succeeds after refresh - - No user interaction required - -- [ ] **Concurrent Refresh Prevention** - - Trigger 5 API calls simultaneously with expired token - - Verify only 1 refresh request sent - - All 5 API calls succeed after refresh - -- [ ] **Refresh Token Expired** - - Manually expire refresh token - - Attempt to refresh - - User logged out with "Session expired" message - -### Multi-Device Login -- [ ] **Login on Multiple Devices** - - Login on iOS device - - Login on Android device (same user) - - Login on web browser (same user) - - All devices have valid sessions - - Token refresh on one device doesn't affect others - -### Password Reset -- [ ] **Request Password Reset** - - Enter email, click "Forgot Password" - - Reset email received within 5 minutes - - Click link in email - - Reset password successfully - - Login with new password - -- [ ] **Rate Limiting** - - Request password reset 3 times rapidly - - 4th request blocked with "Too many attempts" message - ---- - -## Credit System Testing Checklist - -### Credit Purchase -- [ ] **Successful Purchase (Mock)** - - Select 100 credit package - - Initiate checkout - - Complete mock payment - - Verify balance increased by 100 - - Transaction visible in history - -- [ ] **Failed Payment** - - Initiate purchase - - Simulate declined card - - Verify no credits added - - User notified of failure - - Retry option available - -- [ ] **Duplicate Webhook (Idempotency)** - - Complete successful purchase - - Replay same webhook - - Verify credits not double-added - - Balance remains correct - -### Credit Balance -- [ ] **Balance Check** - - Call `/auth/credits` endpoint - - Verify balance matches database - - Response time < 500ms - -- [ ] **Cross-App Visibility** - - Login to Memoro app - - Check credit balance - - Login to Maerchenzauber app (same user) - - Verify same balance displayed - - Real-time sync (< 1 second) - -- [ ] **Negative Balance Prevention** - - User has 5 credits - - Attempt operation requiring 10 credits - - Operation blocked with "Insufficient credits" error - - Balance unchanged - -### Credit Consumption -- [ ] **Standard Deduction** - - User has 100 credits - - Perform operation costing 10 credits (e.g., create story) - - Verify validation before operation - - Operation completes successfully - - Credits deducted (balance = 90) - - Transaction logged - -- [ ] **Failed Operation (No Charge)** - - User has 100 credits - - Validation passes - - Operation fails (simulate AI service error) - - Verify NO credits deducted - - Balance still 100 - - User can retry - -- [ ] **Concurrent Deduction** - - User has 100 credits - - Trigger 3 operations simultaneously (30 credits each) - - All 3 operations complete successfully - - Total deducted: 90 credits - - Final balance: 10 credits - - No over-deduction or under-deduction - -- [ ] **Insufficient Balance During Concurrent Operations** - - User has 10 credits - - Trigger 2 operations simultaneously (8 credits each) - - First operation succeeds (balance β†’ 2) - - Second operation fails with "Insufficient credits" - - User refunded if pre-charged - -### Credit Refund -- [ ] **Failed Operation Refund** - - Credits deducted for operation - - Operation fails after deduction - - Refund process triggered - - Credits restored to balance - - Transaction marked "refunded" - -### Transaction History -- [ ] **View Transaction History** - - Navigate to transaction history page - - All transactions displayed chronologically - - Each entry shows: Date, Operation, Amount, Balance - - Pagination works for large histories - ---- - -## Integration Testing Checklist - -### Mobile Apps -- [ ] **iOS App (Memoro)** - - Register account - - Tokens stored in iOS Keychain (SecureStore) - - Close and reopen app β†’ Session persists - - Make API call β†’ Authentication succeeds - - Background token refresh works - -- [ ] **Android App (Memoro)** - - Register account - - Tokens stored in Android Keystore (SecureStore) - - Close and reopen app β†’ Session persists - - Make API call β†’ Authentication succeeds - - Background token refresh works - -### Web Apps -- [ ] **SvelteKit Web (Memoro)** - - Register account - - Tokens stored in localStorage - - Refresh browser page β†’ Session persists - - Protected routes accessible - - Token refresh works - -- [ ] **Cross-Browser Testing** - - Test in Chrome, Safari, Firefox, Edge - - All browsers work identically - - Token refresh consistent across browsers - -### Cross-App Integration -- [ ] **Memoro to Maerchenzauber** - - Login to Memoro - - Open Maerchenzauber (same device) - - Verify authentication state - - Check credit balance synchronized - -- [ ] **Multi-App Credit Consumption** - - User has 100 credits - - Consume 30 credits in Memoro - - Check balance in Maerchenzauber β†’ 70 credits - - Consume 20 credits in Maerchenzauber - - Check balance in both apps β†’ 50 credits - -### Payment Gateway (RevenueCat) -- [ ] **iOS Purchase Flow** - - Login to iOS app - - Navigate to subscription page - - Purchase 100 credits - - Complete Apple Pay transaction - - Verify webhook received - - Credits added to account - -- [ ] **Android Purchase Flow** - - Login to Android app - - Purchase credits - - Complete Google Play transaction - - Verify webhook and credit update - -- [ ] **Web Purchase Flow** - - Login to web app - - Purchase credits via Stripe - - Complete payment - - Verify webhook and credit update - ---- - -## Security Testing Checklist - -### Authentication Security -- [ ] **SQL Injection Prevention** - - Test login with payloads: `admin'--`, `' OR '1'='1`, `'; DROP TABLE users;--` - - All attempts rejected with 400/401 - - No database queries executed - -- [ ] **JWT Token Manipulation** - - Obtain valid token - - Modify claims (user ID, role, credits) - - Submit modified token - - Request rejected with 401 - -- [ ] **Token Expiration Enforcement** - - Obtain valid token - - Wait for expiration - - Use expired token β†’ 401 error - - Automatic refresh triggered - -- [ ] **Brute Force Protection** - - Attempt login with wrong password 5 times - - 6th attempt blocked with 429 status - - Lockout duration: 15 minutes - -- [ ] **Password Storage** - - Access database directly - - Verify password hashed (bcrypt/Argon2) - - No plaintext passwords - -### Credit Security -- [ ] **Balance Tampering** - - Attempt to modify balance via API manipulation - - Modify client-side storage - - All attempts rejected - - Balance unchanged - -- [ ] **Unauthorized Deduction** - - User A attempts to deduct credits from User B - - Forge JWT with different user ID - - All attempts fail with 401/403 - -- [ ] **Replay Attack** - - Capture valid webhook - - Replay webhook multiple times - - Only first processed - - No double-crediting - -### Rate Limiting -- [ ] **API Rate Limiting** - - Make 100 API requests in 1 minute - - Verify rate limit enforced (429 after limit) - - Retry-After header provided - ---- - -## Performance Testing Checklist - -### Load Testing -- [ ] **Concurrent User Logins** - - Simulate 1000 users logging in concurrently - - 95% of requests complete in < 2 seconds - - Success rate > 99% - - No server crashes - -- [ ] **Token Refresh Under Load** - - 500 users with expired tokens make API calls - - All refreshes succeed - - Avg response time < 1 second - - No request timeouts - -- [ ] **Credit Balance Checks at Scale** - - 2000 users checking balance simultaneously - - Query time < 50ms - - Database connection pool stable - -### Stress Testing -- [ ] **Credit Deduction Stress** - - 100 users each perform 50 operations (5000 total) - - All operations complete successfully - - No over-deductions or under-deductions - - Final balances reconcile - ---- - -## Acceptance Criteria Validation - -### Authentication System -- [ ] User can register in < 3 seconds -- [ ] User can login in < 2 seconds -- [ ] Token refresh is automatic -- [ ] User stays logged in for 30 days -- [ ] Password reset email arrives within 5 minutes -- [ ] Multi-device login works (up to 5 devices) -- [ ] 99.9% uptime - -### Credit System -- [ ] Balance updates within 1 second of purchase -- [ ] Deduction only after operation succeeds -- [ ] Failed operations never charge -- [ ] Balance visible across apps in < 1 second -- [ ] Transaction history available for 24 months -- [ ] No race conditions allow negative balance -- [ ] Refunds processed within 1 hour - -### Integration -- [ ] Mobile apps support iOS 14+ and Android 10+ -- [ ] Web works on Chrome, Safari, Firefox, Edge -- [ ] RevenueCat purchase completes in < 30 seconds -- [ ] API response time < 500ms (95%) -- [ ] Cross-app auth works seamlessly - -### Security -- [ ] No plaintext passwords -- [ ] JWT secured with RS256 -- [ ] Rate limiting prevents brute force -- [ ] SQL injection blocked 100% -- [ ] 0 critical/high XSS vulnerabilities -- [ ] Penetration test: No critical issues - -### Performance -- [ ] 1000 concurrent users supported -- [ ] 99th percentile response < 3 seconds -- [ ] Token refresh < 2 seconds -- [ ] Credit balance check < 100ms -- [ ] Scalable to 10M users - ---- - -## Bug Reporting - -### When to File a Bug -- Any test case fails -- Security vulnerability discovered -- Performance below targets -- Unexpected behavior -- Inconsistent cross-platform behavior - -### Bug Report Template -```markdown -**Title:** [Brief description] -**Severity:** Critical / High / Medium / Low -**Environment:** Dev / Staging / Production -**Device/Browser:** [Details] - -**Steps to Reproduce:** -1. [Step 1] -2. [Step 2] - -**Expected:** [What should happen] -**Actual:** [What actually happens] - -**Screenshots/Logs:** [Attach evidence] -**Related Test Case:** TC-XXX-XXX-XXX -``` - -### Severity Guidelines -- **Critical:** System crash, data loss, security breach, payment failure -- **High:** Feature broken, workaround difficult, affects many users -- **Medium:** Feature partially broken, workaround available -- **Low:** Minor issue, cosmetic, affects few users - ---- - -## Post-Testing - -### Test Summary Report -- [ ] Total test cases executed -- [ ] Pass/Fail/Blocked count -- [ ] Critical bugs found -- [ ] Performance metrics captured -- [ ] Security issues identified -- [ ] Recommendations for release - -### Sign-Off Criteria -- [ ] All P0 test cases passed -- [ ] 0 critical bugs open -- [ ] < 3 high priority bugs open -- [ ] Performance targets met -- [ ] Security scan clean -- [ ] Stakeholder approval - ---- - -## Quick Links - -- **Full Test Strategy:** `/TESTING_STRATEGY_AUTH_CREDITS.md` -- **Executive Summary:** `/TESTING_STRATEGY_EXECUTIVE_SUMMARY.md` -- **Developer Auth Testing Guide:** `maerchenzauber/apps/mobile/AUTH_TESTING_GUIDE.md` -- **Credit System Documentation:** `manadeck/CREDIT_SYSTEM.md` -- **Shared Auth Package:** `packages/shared-auth/README.md` - ---- - -**Happy Testing!** - -*For questions or issues, contact the QA lead or refer to the full testing strategy document.* diff --git a/RELEASE-PLAN.md b/RELEASE-PLAN.md deleted file mode 100644 index 451c2f26a..000000000 --- a/RELEASE-PLAN.md +++ /dev/null @@ -1,491 +0,0 @@ -# Manacore Monorepo - Release-Plan & Priorisierung - -> Erstellt am: 2024-12-05 -> Basierend auf: Analyse aller 31 Apps im Monorepo - -## Inhaltsverzeichnis - -- [Bewertungskriterien](#bewertungskriterien) -- [Release-Phasen](#release-phasen) -- [Phase 1: Foundation](#phase-1-foundation) -- [Phase 2: Quick Wins](#phase-2-quick-wins) -- [Phase 3: Core Productivity](#phase-3-core-productivity) -- [Phase 4: AI-Powered Apps](#phase-4-ai-powered-apps) -- [Phase 5: Nischen-Apps](#phase-5-nischen-apps) -- [Phase 6: Games](#phase-6-games) -- [Archivierte Apps](#archivierte-apps) -- [Zusammenfassung](#zusammenfassung) - ---- - -## Bewertungskriterien - -Jede App wurde anhand folgender Kriterien bewertet: - -| Kriterium | Gewichtung | Beschreibung | -|-----------|------------|--------------| -| **Reifegrad** | 25% | Wie vollstΓ€ndig ist die App? (Backend, Web, Mobile, Landing) | -| **Marktpotenzial** | 25% | Grâße der Zielgruppe, Monetarisierungspotenzial | -| **KomplexitΓ€t** | 20% | Technische KomplexitΓ€t, externe AbhΓ€ngigkeiten (APIs, AI) | -| **Strategische Bedeutung** | 15% | Wichtigkeit fΓΌr das Manacore-Γ–kosystem | -| **Wartungsaufwand** | 15% | Erwarteter laufender Aufwand nach Release | - -### Reifegrad-Matrix (Aktive Apps) - -| App | Backend | Web | Mobile | Landing | Reifegrad | -|-----|---------|-----|--------|---------|-----------| -| chat | βœ… | βœ… | βœ… | βœ… | Sehr hoch | -| picture | βœ… | βœ… | βœ… | βœ… | Sehr hoch | -| manadeck | βœ… | βœ… | βœ… | βœ… | Sehr hoch | -| zitare | βœ… | βœ… | βœ… | βœ… | Hoch | -| presi | βœ… | βœ… | βœ… | βœ… | Hoch | -| mail | βœ… | βœ… | βœ… | βœ… | Mittel | -| calendar | βœ… | βœ… | - | βœ… | Mittel | -| clock | βœ… | βœ… | - | βœ… | Mittel | -| manacore | - | βœ… | βœ… | βœ… | Mittel | -| contacts | βœ… | βœ… | πŸ”² | πŸ”² | Mittel | -| todo | βœ… | βœ… | - | πŸ”² | Niedrig | -| storage | βœ… | βœ… | - | πŸ”² | Niedrig | -| moodlit | βœ… | βœ… | βœ… | βœ… | Neu | -| finance | βœ… | βœ… | πŸ”² | πŸ”² | Neu | - -βœ… = Vorhanden | πŸ”² = Leer/Skeleton | - = Nicht vorhanden - ---- - -## Release-Phasen - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ RELEASE-ROADMAP β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ Phase 1 Phase 2 Phase 3 Phase 4 Phase 5 β”‚ -β”‚ Foundation Quick Wins Core Prod. AI-Powered Nischen β”‚ -β”‚ ────────── ────────── ────────── ────────── ────────── β”‚ -β”‚ mana-core-auth zitare todo chat mail β”‚ -β”‚ manacore clock calendar picture storage β”‚ -β”‚ manadeck contacts presi β”‚ -β”‚ finance β”‚ -β”‚ β”‚ -β”‚ ◄────────────────────────────────────────────────────────────────────► β”‚ -β”‚ Woche 1-2 Woche 3-4 Woche 5-8 Woche 9-12 Woche 13+ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - ---- - -## Phase 1: Foundation - -**Zeitrahmen:** Zuerst | **PrioritΓ€t:** KRITISCH - -### 1.1 mana-core-auth (Zentrale Authentifizierung) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 1 (HΓΆchste) | -| **Status** | Aktiv, funktionsfΓ€hig | -| **Port** | 3001 | - -**Warum zuerst?** -- Alle anderen Apps hΓ€ngen von diesem Service ab -- Ohne Auth funktioniert keine App im Produktivbetrieb -- EdDSA JWT-basierte Authentifizierung ist das RΓΌckgrat des Γ–kosystems - -**Vor Release zu tun:** -- [ ] Security Audit durchfΓΌhren -- [ ] Rate Limiting implementieren -- [ ] Monitoring & Alerting einrichten -- [ ] Backup-Strategie fΓΌr DB - ---- - -### 1.2 manacore (Multi-App Ecosystem Platform) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 2 | -| **Status** | Web βœ…, Mobile βœ…, Landing βœ… | -| **Beschreibung** | Zentrales Dashboard fΓΌr alle Mana-Apps | - -**Warum in Phase 1?** -- Ist das "Schaufenster" des gesamten Γ–kosystems -- Nutzer verwalten hier ihre App-ZugΓ€nge und Credits -- Marketing-Hub fΓΌr alle anderen Apps - -**Vor Release zu tun:** -- [ ] Dashboard-Widgets fΓΌr alle Phase-2-Apps vorbereiten -- [ ] Credit-System UI finalisieren -- [ ] App-Store-Übersicht einbauen - ---- - -## Phase 2: Quick Wins - -**Zeitrahmen:** Woche 3-4 | **PrioritΓ€t:** HOCH - -Diese Apps sind release-ready und haben klare Use Cases mit geringem Risiko. - -### 2.1 zitare (TΓ€gliche Inspirations-Zitate) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 3 | -| **Reifegrad** | Hoch (alle Komponenten vorhanden) | -| **KomplexitΓ€t** | Niedrig | - -**Warum hier?** -- Einfache App mit klarem Mehrwert -- Geringe API-Kosten (keine AI-Aufrufe) -- Perfekt fΓΌr virale Verbreitung (Zitate teilen) -- Gut fΓΌr Nutzerbindung (tΓ€gliche Routine) - -**Besonderheiten:** -- Favoriten-System -- Personalisierte Empfehlungen -- Share-FunktionalitΓ€t - ---- - -### 2.2 clock (Uhren-App) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 4 | -| **Reifegrad** | Mittel (kein Mobile) | -| **KomplexitΓ€t** | Niedrig | - -**Warum hier?** -- Utility-App ohne externe AbhΓ€ngigkeiten -- Keine laufenden API-Kosten -- Breite Zielgruppe (jeder braucht Timer/Wecker) -- Pomodoro-Timer fΓΌr ProduktivitΓ€ts-Fokus - -**Features:** -- Weltzeituhr -- Wecker -- Timer -- Stoppuhr -- Pomodoro-Timer - ---- - -### 2.3 manadeck (Lernkarten/Spaced Repetition) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 5 | -| **Reifegrad** | Sehr hoch (alle Komponenten) | -| **KomplexitΓ€t** | Mittel | - -**Warum hier?** -- BewΓ€hrtes Konzept (Anki-Alternative) -- Klare Monetarisierung (Freemium) -- Sehr hoher Reifegrad im Code -- Große Zielgruppe (Studenten, Sprachlerner) - -**Besonderheiten:** -- Spaced Repetition Algorithmus -- Deck-Sharing -- Import/Export - ---- - -## Phase 3: Core Productivity - -**Zeitrahmen:** Woche 5-8 | **PrioritΓ€t:** HOCH - -ProduktivitΓ€ts-Apps, die das tΓ€gliche Leben verbessern. - -### 3.1 todo (Task-Management) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 6 | -| **Reifegrad** | Niedrig (Landing fehlt) | -| **KomplexitΓ€t** | Mittel | - -**Warum hier?** -- Grundlegende ProduktivitΓ€ts-App -- Synergien mit calendar -- Großer Markt (wenn auch wettbewerbsintensiv) - -**Features:** -- Projekte -- Subtasks -- Labels -- Wiederkehrende Aufgaben - -**Vor Release:** -- [ ] Landing Page erstellen -- [ ] Mobile App entwickeln - ---- - -### 3.2 calendar (Kalender) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 7 | -| **Reifegrad** | Mittel (kein Mobile) | -| **KomplexitΓ€t** | Hoch | - -**Warum hier?** -- NatΓΌrliche ErgΓ€nzung zu todo -- CalDAV/iCal-Sync ist starkes Feature -- Wiederkehrende Termine sind komplex aber wertvoll - -**Vor Release:** -- [ ] CalDAV-Sync testen -- [ ] Mobile App entwickeln -- [ ] Integration mit todo - ---- - -### 3.3 contacts (Kontaktverwaltung) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 8 | -| **Reifegrad** | Mittel | -| **KomplexitΓ€t** | Mittel | - -**Warum hier?** -- Synergien mit mail und calendar -- Google-Sync ist starkes Feature -- Import/Export fΓΌr Migration - -**Vor Release:** -- [ ] Mobile App entwickeln -- [ ] Landing Page erstellen -- [ ] Google OAuth finalisieren - ---- - -### 3.4 finance (Budget-Tracker) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 9 | -| **Reifegrad** | Neu | -| **KomplexitΓ€t** | Mittel | - -**Warum hier?** -- Wichtige ProduktivitΓ€ts-App -- Multi-Currency ist differenzierendes Feature -- Gutes Monetarisierungspotenzial - -**Vor Release:** -- [ ] Core-Features fertigstellen -- [ ] Mobile App entwickeln -- [ ] Landing Page erstellen - ---- - -## Phase 4: AI-Powered Apps - -**Zeitrahmen:** Woche 9-12 | **PrioritΓ€t:** MITTEL - -Diese Apps haben hΓΆhere KomplexitΓ€t und laufende API-Kosten. - -### 4.1 chat (KI-Chat-Anwendung) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 10 | -| **Reifegrad** | Sehr hoch | -| **KomplexitΓ€t** | Hoch | -| **API-Kosten** | Hoch (LLM-Aufrufe) | - -**Warum hier und nicht frΓΌher?** -- HΓΆchster Reifegrad, ABER: -- Hohe laufende API-Kosten (OpenAI, Claude, etc.) -- Intensiver Wettbewerb (ChatGPT, Claude.ai) -- Credit-System muss zuerst stabil laufen - -**Vor Release:** -- [ ] Cost-per-request Monitoring -- [ ] Rate Limiting pro User -- [ ] Model-Fallback bei API-AusfΓ€llen -- [ ] Prompt-Injection-Schutz - ---- - -### 4.2 picture (KI-Bildgenerierung) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 11 | -| **Reifegrad** | Sehr hoch | -| **KomplexitΓ€t** | Hoch | -| **API-Kosten** | Sehr hoch (Bildgenerierung) | - -**Warum hier?** -- Sehr hoher Reifegrad -- Starkes Monetarisierungspotenzial -- Aber: HΓΆchste API-Kosten im Portfolio - -**Vor Release:** -- [ ] Credit-Verbrauch pro Generation kalibrieren -- [ ] Galerie-Moderation (NSFW-Filter) -- [ ] Wasserzeichen-Option - ---- - -### 4.3 presi (PrΓ€sentations-Tool) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 12 | -| **Reifegrad** | Hoch | -| **KomplexitΓ€t** | Hoch | - -**Warum hier?** -- Weniger AI-lastig als chat/picture -- Gute Nische (Canva/Pitch-Alternative) -- Enterprise-Potenzial - -**Vor Release:** -- [ ] Export-Formate (PDF, PPTX) -- [ ] Kollaboration-Features -- [ ] Templates-Bibliothek - ---- - -## Phase 5: Nischen-Apps - -**Zeitrahmen:** Woche 13+ | **PrioritΓ€t:** NIEDRIG - -Spezialisierte Apps mit kleinerer Zielgruppe. - -### 5.1 mail (E-Mail-Client) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 13 | -| **Reifegrad** | Mittel | -| **KomplexitΓ€t** | Sehr hoch | - -**Warum so spΓ€t?** -- E-Mail-Clients sind extrem komplex -- IMAP/SMTP-Integration ist fehleranfΓ€llig -- Starke Konkurrenz (Gmail, Outlook, ProtonMail) -- AI-Features erhΓΆhen KomplexitΓ€t weiter - -**Vor Release:** -- [ ] Umfangreiche E-Mail-Provider-Tests -- [ ] Spam-Handling -- [ ] Attachment-Limits -- [ ] End-to-End-Encryption? - ---- - -### 5.2 storage (Cloud-Speicher) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 14 | -| **Reifegrad** | Niedrig | -| **KomplexitΓ€t** | Sehr hoch | - -**Warum so spΓ€t?** -- Hohe Infrastrukturkosten -- Starke Konkurrenz (Dropbox, Google Drive) -- Rechtliche Aspekte (Datenspeicherung) - -**Vor Release:** -- [ ] Storage-Limits pro Plan definieren -- [ ] Backup-Strategie -- [ ] DSGVO-Compliance -- [ ] Deduplizierung - ---- - -### 5.3 moodlit (Ambient Lighting) - -| Eigenschaft | Wert | -|-------------|------| -| **PrioritΓ€t** | 15 | -| **Reifegrad** | Neu | -| **KomplexitΓ€t** | Niedrig | - -**Warum so spΓ€t?** -- Sehr nischiger Use Case -- Wenig Monetarisierungspotenzial -- Kann als "Nice-to-have" warten - ---- - -## Phase 6: Games - -**Zeitrahmen:** Parallel/SpΓ€ter | **PrioritΓ€t:** OPTIONAL - -Games sind unabhΓ€ngig vom HauptΓΆkosystem und kΓΆnnen flexibel released werden. - -| Game | Beschreibung | Status | -|------|--------------|--------| -| **mana-games** | Browser-Spieleplatform | Aktiv | -| **figgos** | Collectible Figure Game | Neu strukturiert | -| **voxel-lava** | 3D Voxel Building Game | In Entwicklung | -| **whopixels** | Pixel-Art-Editor-Spiel | Einfache Struktur | - -**Empfehlung:** Games als eigenstΓ€ndiges Produkt betrachten, nicht im Manacore-Γ–kosystem integrieren (außer mana-games als Platform). - ---- - -## Archivierte Apps - -Diese Apps sind aktuell pausiert. Reaktivierung nach Bedarf: - -| App | Beschreibung | Reaktivierungs-Empfehlung | -|-----|--------------|---------------------------| -| **uload** | URL-Shortener (Live: ulo.ad) | EigenstΓ€ndig halten | -| **maerchenzauber** | KI-KindermΓ€rchen | Nach picture (AI-Synergien) | -| **memoro** | Sprachnotizen | Nach mail (Backend-Synergien) | -| **nutriphi** | ErnΓ€hrungs-Tracker | Nach finance (Tracking-Synergien) | -| **wisekeep** | YouTube-Wissensextraktion | Nach chat (AI-Synergien) | -| **news** | News-Aggregator | Niedrige PrioritΓ€t | -| **bauntown** | Community-Website | Nur Landing, niedrige PrioritΓ€t | -| **reader** | Text-to-Speech | Nach mail (KomplexitΓ€t Γ€hnlich) | - ---- - -## Zusammenfassung - -### Release-Reihenfolge (Top 15) - -| # | App | Phase | BegrΓΌndung | -|---|-----|-------|------------| -| 1 | mana-core-auth | Foundation | Alle Apps hΓ€ngen davon ab | -| 2 | manacore | Foundation | Γ–kosystem-Hub | -| 3 | zitare | Quick Wins | Niedrige KomplexitΓ€t, hohe ViralitΓ€t | -| 4 | clock | Quick Wins | Utility ohne AbhΓ€ngigkeiten | -| 5 | manadeck | Quick Wins | Sehr hoher Reifegrad | -| 6 | todo | Core Prod. | Basis-ProduktivitΓ€t | -| 7 | calendar | Core Prod. | ErgΓ€nzt todo | -| 8 | contacts | Core Prod. | ErgΓ€nzt mail/calendar | -| 9 | finance | Core Prod. | Starkes Monetarisierungspotenzial | -| 10 | chat | AI-Powered | Hoher Reifegrad, aber hohe Kosten | -| 11 | picture | AI-Powered | HΓΆchste API-Kosten | -| 12 | presi | AI-Powered | Enterprise-Potenzial | -| 13 | mail | Nischen | Sehr hohe KomplexitΓ€t | -| 14 | storage | Nischen | Hohe Infrastrukturkosten | -| 15 | moodlit | Nischen | Nischen-App | - -### Kritische Erfolgsfaktoren - -1. **mana-core-auth MUSS stabil sein** - Ein Auth-Ausfall betrifft ALLE Apps -2. **Credit-System vor AI-Apps** - Ohne funktionierende Abrechnung keine AI-Features -3. **Quick Wins fΓΌr Momentum** - zitare/clock/manadeck fΓΌr frΓΌhe Nutzerbasis -4. **API-Kosten im Blick** - chat/picture erst wenn Monetarisierung funktioniert - -### NΓ€chste Schritte - -1. [ ] Security Audit fΓΌr mana-core-auth planen -2. [ ] Landing Pages fΓΌr todo/storage/finance/contacts erstellen -3. [ ] Mobile Apps fΓΌr clock/calendar entwickeln -4. [ ] Monitoring-Infrastruktur aufbauen -5. [ ] Beta-Tester-Programm fΓΌr Phase-2-Apps starten - ---- - -*Dieses Dokument wird regelmÀßig aktualisiert, wenn sich PrioritΓ€ten Γ€ndern.* diff --git a/TESTING_STRATEGY_AUTH_CREDITS.md b/TESTING_STRATEGY_AUTH_CREDITS.md deleted file mode 100644 index 220e03266..000000000 --- a/TESTING_STRATEGY_AUTH_CREDITS.md +++ /dev/null @@ -1,1710 +0,0 @@ -# Comprehensive Testing Strategy: Authentication & Mana Credit System - -**Project:** Manacore Monorepo - Central Auth & Credit System -**Version:** 1.0 -**Date:** 2025-11-25 -**Status:** DRAFT - ---- - -## Executive Summary - -This document provides a comprehensive testing strategy for the central authentication and mana credit system used across all Manacore applications (Memoro, Maerchenzauber, Manadeck, Picture, Chat). The strategy covers functional testing, security testing, integration testing, performance testing, and acceptance criteria. - -### Critical Business Paths -1. **User Registration β†’ Authentication β†’ Service Access** -2. **Credit Purchase β†’ Balance Update β†’ Credit Consumption β†’ Balance Deduction** -3. **Multi-App Credit Visibility & Usage** -4. **Token Refresh & Session Management** - ---- - -## 1. Authentication Testing - -### 1.1 Registration Flow Tests - -#### TC-AUTH-REG-001: Email/Password Registration -**Priority:** P0 (Critical) -**Description:** User creates account with email and password - -**Test Steps:** -1. Submit valid email and password (8+ chars, complexity requirements) -2. Verify account created in database -3. Check email verification sent (if applicable) -4. Verify tokens generated (manaToken, appToken, refreshToken) -5. Confirm tokens stored securely - -**Expected Results:** -- User record created with UUID -- Three tokens generated and returned -- Tokens stored in secure storage (SecureStore on mobile, localStorage on web) -- Email verification sent if configured -- User can access protected routes - -**Edge Cases:** -- Email already exists β†’ 409 error with appropriate message -- Invalid email format β†’ 400 error -- Weak password β†’ 400 error with requirements -- Network timeout during registration β†’ Retry mechanism -- Duplicate concurrent registrations β†’ Second request fails - -**Test Data:** -```javascript -{ - valid: { email: "test+valid@example.com", password: "SecureP@ss123" }, - duplicate: { email: "existing@example.com", password: "AnyP@ss123" }, - invalid_email: { email: "not-an-email", password: "SecureP@ss123" }, - weak_password: { email: "test@example.com", password: "123" } -} -``` - -#### TC-AUTH-REG-002: Google Sign-In Registration -**Priority:** P0 (Critical) - -**Test Steps:** -1. Initiate Google OAuth flow -2. User authorizes in Google -3. Receive idToken from Google -4. Submit idToken to `/auth/google-signin` -5. Verify account created or linked -6. Check tokens generated - -**Expected Results:** -- New user: Account created with Google profile data -- Existing user: Linked to existing account -- Email extracted from Google profile -- Standard token set issued - -**Edge Cases:** -- Invalid idToken β†’ 401 error -- Google service unavailable β†’ Graceful error message -- Email conflict with existing email/password account β†’ Link accounts - -#### TC-AUTH-REG-003: Apple Sign-In Registration -**Priority:** P1 (High) - -**Test Steps:** -1. Initiate Apple Sign In flow -2. User authorizes in Apple -3. Receive identityToken from Apple -4. Submit identityToken to `/auth/apple-signin` -5. Verify account created -6. Check tokens generated - -**Expected Results:** -- Account created with Apple ID -- Email may be private relay email -- Tokens issued correctly -- User can access services - -**Edge Cases:** -- Private email relay handling -- First-time vs returning user -- Revoked Apple credentials - -### 1.2 Login Flow Tests - -#### TC-AUTH-LOGIN-001: Successful Email/Password Login -**Priority:** P0 (Critical) - -**Test Steps:** -1. Submit valid credentials to `/auth/signin` -2. Verify response contains all three tokens -3. Check tokens stored in secure storage -4. Verify user data extracted from appToken -5. Confirm access to protected resources - -**Expected Results:** -- 200 status code -- Tokens returned: `{ appToken, refreshToken }` -- manaToken embedded in appToken claims -- User email stored locally -- AuthContext updated with user state - -**Validation Points:** -- Token structure: JWT format validation -- Token claims: `sub` (user ID), `role`, `app_id`, `exp`, `iat` -- Token expiration: appToken ~1 hour, refreshToken ~30 days -- Storage success: All tokens persisted - -#### TC-AUTH-LOGIN-002: Invalid Credentials -**Priority:** P0 (Critical) - -**Test Steps:** -1. Submit incorrect password -2. Submit non-existent email -3. Verify appropriate error messages -4. Check no tokens issued -5. Ensure secure storage remains empty - -**Expected Results:** -- 401 Unauthorized status -- Error: `INVALID_CREDENTIALS` -- No tokens in response -- No data written to storage -- User remains unauthenticated - -#### TC-AUTH-LOGIN-003: Email Not Verified -**Priority:** P1 (High) - -**Test Steps:** -1. Create account without verifying email -2. Attempt login -3. Verify error response - -**Expected Results:** -- 403 Forbidden status -- Error: `EMAIL_NOT_VERIFIED` -- Prompt to check email for verification link -- No tokens issued - -#### TC-AUTH-LOGIN-004: Firebase User Password Reset Required -**Priority:** P1 (High) - -**Test Steps:** -1. Login as Firebase-migrated user -2. Verify password reset error -3. Check reset flow initiated - -**Expected Results:** -- 401 status with specific error code -- Error: `FIREBASE_USER_PASSWORD_RESET_REQUIRED` -- User directed to password reset flow -- Password reset email sent - -### 1.3 Logout Flow Tests - -#### TC-AUTH-LOGOUT-001: Standard Logout -**Priority:** P0 (Critical) - -**Test Steps:** -1. Authenticate user -2. Call `/auth/logout` with refreshToken -3. Verify tokens cleared from storage -4. Check server-side session invalidated -5. Attempt to use old tokens - -**Expected Results:** -- All tokens removed from secure storage -- Server-side refresh token invalidated -- Subsequent API calls with old tokens fail with 401 -- User redirected to login screen -- AuthContext reset to unauthenticated state - -#### TC-AUTH-LOGOUT-002: Logout with Network Failure -**Priority:** P2 (Medium) - -**Test Steps:** -1. Authenticate user -2. Disable network -3. Call logout -4. Verify local cleanup happens - -**Expected Results:** -- Local tokens cleared even if server unreachable -- User marked as logged out in UI -- Server-side cleanup attempted with retry -- Graceful error handling - -### 1.4 Token Refresh Tests - -#### TC-AUTH-REFRESH-001: Automatic Token Refresh on Expiry -**Priority:** P0 (Critical) - -**Test Steps:** -1. Login with valid credentials -2. Wait for appToken to expire (or manually expire) -3. Make API call that triggers 401 -4. Verify automatic refresh initiated -5. Check new tokens issued -6. Confirm original API call succeeds - -**Expected Results:** -- TokenManager detects expiry -- Refresh endpoint called with refreshToken -- New appToken and refreshToken returned -- Tokens updated in storage -- Original API request retried and succeeds -- No user interaction required - -**Performance Criteria:** -- Refresh completes in < 2 seconds -- User experiences no disruption -- UI shows loading state during refresh - -#### TC-AUTH-REFRESH-002: Concurrent Refresh Prevention -**Priority:** P0 (Critical) - -**Test Steps:** -1. Trigger multiple API calls simultaneously with expired token -2. Verify only ONE refresh request sent -3. Check all requests queued during refresh -4. Confirm all succeed after refresh completes - -**Expected Results:** -- Single refresh promise shared -- Request queue manages pending calls -- All queued requests processed with new token -- No duplicate refresh attempts -- Queue timeout: 30 seconds max - -**Test Implementation:** -```typescript -// Simulate 5 concurrent API calls with expired token -const requests = Array(5).fill(null).map(() => - fetch('/api/protected-resource') -); -await Promise.all(requests); -// Verify only 1 refresh API call made -``` - -#### TC-AUTH-REFRESH-003: Refresh Token Expiration -**Priority:** P0 (Critical) - -**Test Steps:** -1. Manually expire refreshToken -2. Attempt to refresh -3. Verify error handling -4. Check user logged out - -**Expected Results:** -- Refresh fails with 401 -- Error: "Session expired. Please sign in again." -- All tokens cleared -- User redirected to login -- Clear error message displayed - -#### TC-AUTH-REFRESH-004: Device ID Change Detection -**Priority:** P1 (High) - -**Test Steps:** -1. Login on device A -2. Copy tokens to device B (different device ID) -3. Attempt token refresh on device B -4. Verify security check fails - -**Expected Results:** -- Refresh denied -- Error: "Device ID has changed. Please sign in again." -- Tokens invalidated -- User must re-authenticate - -### 1.5 Session Management Tests - -#### TC-AUTH-SESSION-001: Multi-Device Login -**Priority:** P1 (High) - -**Test Steps:** -1. Login on device A (iOS) -2. Login same user on device B (Android) -3. Login same user on device C (Web) -4. Verify all devices have valid sessions -5. Test concurrent API calls from all devices - -**Expected Results:** -- All devices independently authenticated -- Each device has unique refreshToken -- All devices share same user ID -- Concurrent usage works correctly -- Token refresh on one device doesn't affect others - -#### TC-AUTH-SESSION-002: Multi-App Session Sharing -**Priority:** P0 (Critical) - -**Test Steps:** -1. Login to Memoro app -2. Navigate to Maerchenzauber app -3. Verify SSO (single sign-on) behavior -4. Check credits visible across apps - -**Expected Results:** -- User authenticated in both apps -- No duplicate login required (if SSO configured) -- Credit balance synchronized -- App-specific JWT claims present (`app_id`) - -#### TC-AUTH-SESSION-003: Session Persistence -**Priority:** P1 (High) - -**Test Steps:** -1. Login to app -2. Close app completely -3. Reopen app after 1 hour -4. Verify user still authenticated -5. Check token validity - -**Expected Results:** -- User remains logged in -- Tokens loaded from secure storage -- If appToken expired, automatic refresh occurs -- Seamless user experience - -### 1.6 Password Management Tests - -#### TC-AUTH-PWD-001: Password Reset Request -**Priority:** P1 (High) - -**Test Steps:** -1. Submit forgot password request with email -2. Check email sent -3. Verify reset link format and expiration -4. Click link and reset password -5. Login with new password - -**Expected Results:** -- Reset email sent to valid addresses -- Link expires after 24 hours -- Old password no longer works -- New password immediately usable - -#### TC-AUTH-PWD-002: Rate Limiting on Password Reset -**Priority:** P2 (Medium) - -**Test Steps:** -1. Request password reset -2. Immediately request again -3. Repeat 5 times -4. Verify rate limiting applied - -**Expected Results:** -- First request succeeds -- Subsequent requests blocked -- Error: "Too many attempts. Please wait before trying again." -- Rate limit: Max 3 requests per 15 minutes - ---- - -## 2. Credit System Testing - -### 2.1 Credit Purchase Flow Tests - -#### TC-CREDIT-PURCHASE-001: Successful Credit Purchase (Mock Payment) -**Priority:** P0 (Critical) - -**Test Steps:** -1. User selects credit package (e.g., 100 credits for €4.99) -2. Initiate checkout with mock payment gateway -3. Simulate successful payment webhook -4. Verify credit balance updated -5. Check transaction recorded - -**Expected Results:** -- Payment gateway returns success -- Webhook processed by backend -- Credit balance increased by purchased amount -- Transaction record created with: - - Transaction ID - - User ID - - Amount (credits) - - Timestamp - - Status: "completed" - - Payment method - -**Validation Points:** -- Balance update is atomic (no partial updates) -- Duplicate webhook handling (idempotency) -- Transaction logged for audit - -**Test Data:** -```javascript -{ - packages: [ - { credits: 100, price: 4.99, productId: "mana_100" }, - { credits: 500, price: 19.99, productId: "mana_500" }, - { credits: 1000, price: 34.99, productId: "mana_1000" } - ] -} -``` - -#### TC-CREDIT-PURCHASE-002: Failed Payment -**Priority:** P0 (Critical) - -**Test Steps:** -1. Initiate credit purchase -2. Simulate payment failure (declined card) -3. Verify no credits added -4. Check appropriate error message - -**Expected Results:** -- Credit balance unchanged -- No transaction record created (or marked "failed") -- User notified of payment failure -- Retry option presented - -#### TC-CREDIT-PURCHASE-003: Duplicate Payment Webhook -**Priority:** P0 (Critical) - -**Test Steps:** -1. Complete successful purchase -2. Replay same webhook notification -3. Verify idempotent handling - -**Expected Results:** -- First webhook: Credits added -- Duplicate webhook: Ignored (detected by transaction ID) -- Balance not double-credited -- Log warning about duplicate webhook - -**Implementation:** -```typescript -// Idempotency check -const existingTx = await db.getTransaction(webhookData.transactionId); -if (existingTx) { - console.log('Duplicate webhook ignored'); - return { status: 'already_processed' }; -} -``` - -#### TC-CREDIT-PURCHASE-004: Webhook Timeout/Retry -**Priority:** P1 (High) - -**Test Steps:** -1. Simulate slow/failed webhook delivery -2. Payment gateway retries webhook -3. Verify eventual consistency - -**Expected Results:** -- Webhook processed on retry -- Credits eventually added -- User sees updated balance -- No duplicate credits - -### 2.2 Credit Balance Tests - -#### TC-CREDIT-BALANCE-001: Balance Check Endpoint -**Priority:** P0 (Critical) - -**Test Steps:** -1. Authenticate user -2. Call `/auth/credits` endpoint -3. Verify response format -4. Check balance accuracy - -**Expected Results:** -- 200 status code -- Response: `{ credits: number, max_credit_limit: number, id: string }` -- Balance matches database -- Request completes in < 500ms - -#### TC-CREDIT-BALANCE-002: Balance Consistency Across Apps -**Priority:** P0 (Critical) - -**Test Steps:** -1. Login to Memoro app -2. Check credit balance -3. Login to Maerchenzauber app (same user) -4. Check credit balance -5. Verify balances identical - -**Expected Results:** -- Same balance in both apps -- Real-time updates propagated -- No sync delays - -#### TC-CREDIT-BALANCE-003: Negative Balance Prevention -**Priority:** P0 (Critical) - -**Test Steps:** -1. User has 5 credits remaining -2. Attempt operation requiring 10 credits -3. Verify operation blocked -4. Check balance unchanged - -**Expected Results:** -- 400 Bad Request -- Error: `insufficient_credits` -- Response includes: `{ requiredCredits: 10, availableCredits: 5 }` -- Balance remains at 5 -- No operation performed - -### 2.3 Credit Consumption Tests - -#### TC-CREDIT-CONSUME-001: Standard Credit Deduction -**Priority:** P0 (Critical) - -**Test Steps:** -1. User has 100 credits -2. Perform operation costing 10 credits (e.g., create story) -3. Verify validation before operation -4. Perform operation -5. Deduct credits after success -6. Check final balance - -**Expected Results:** -- Pre-operation validation: `hasCredits: true` -- Operation completes successfully -- Credits deducted: 10 -- Final balance: 90 -- Transaction logged - -**Implementation Pattern:** -```typescript -// 1. VALIDATE before operation -const validation = await creditClient.validateCredits(userId, 'STORY_CREATE', 10); -if (!validation.hasCredits) { - throw insufficientCreditsError; -} - -// 2. PERFORM operation -const story = await createStory(data); - -// 3. CONSUME after success -await creditClient.consumeCredits(userId, 'STORY_CREATE', 10, - `Created story: ${story.id}`, { storyId: story.id } -); -``` - -#### TC-CREDIT-CONSUME-002: Operation Failure (No Charge) -**Priority:** P0 (Critical) - -**Test Steps:** -1. User has 100 credits -2. Validate credits (passes) -3. Operation fails (e.g., AI service error) -4. Verify NO credits deducted -5. Check balance unchanged - -**Expected Results:** -- Validation: `hasCredits: true` -- Operation fails with error -- Credits NOT consumed -- Balance remains at 100 -- User can retry - -**Critical Rule:** NEVER charge credits for failed operations - -#### TC-CREDIT-CONSUME-003: Concurrent Credit Deduction -**Priority:** P0 (Critical) - -**Test Steps:** -1. User has 100 credits -2. Trigger 3 operations simultaneously (30 credits each) -3. Verify only 3 operations succeed -4. Check final balance correct - -**Expected Results:** -- All 3 operations validate successfully -- All 3 operations complete -- Total deducted: 90 credits -- Final balance: 10 credits -- No race condition causing over-deduction or under-deduction - -**Database Implementation:** -```sql --- Atomic credit deduction with optimistic locking -UPDATE user_profiles -SET credits = credits - ${amount}, - updated_at = NOW() -WHERE id = ${userId} - AND credits >= ${amount} - AND updated_at = ${previousUpdatedAt} -RETURNING credits; -``` - -#### TC-CREDIT-CONSUME-004: Credit Deduction with Insufficient Balance (Edge Case) -**Priority:** P0 (Critical) - -**Test Steps:** -1. User has 10 credits -2. Two concurrent operations (8 credits each) -3. Both validate simultaneously -4. First operation consumes 8 credits -5. Second operation attempts consumption -6. Verify second operation fails - -**Expected Results:** -- Both validate successfully (balance check passes) -- First operation: Succeeds, balance β†’ 2 -- Second operation: Fails (insufficient balance) -- User refunded for second operation (if pre-charged) -- Clear error message - -**Race Condition Mitigation:** -- Use database transactions -- Lock rows during deduction -- Validate again at consumption time - -### 2.4 Credit Refund & Adjustment Tests - -#### TC-CREDIT-REFUND-001: Failed Operation Refund -**Priority:** P1 (High) - -**Test Steps:** -1. User purchases credits -2. Credits deducted for operation -3. Operation fails after deduction -4. Trigger refund process -5. Verify credits restored - -**Expected Results:** -- Refund transaction created -- Credits added back to balance -- Original transaction marked "refunded" -- User notified of refund - -#### TC-CREDIT-REFUND-002: Manual Credit Adjustment (Admin) -**Priority:** P2 (Medium) - -**Test Steps:** -1. Admin logs in -2. Navigates to user credit management -3. Adds/removes credits manually -4. Provides reason -5. Verify balance updated - -**Expected Results:** -- Balance adjusted by specified amount -- Adjustment logged with admin ID and reason -- User sees updated balance immediately - -### 2.5 Credit Transaction History Tests - -#### TC-CREDIT-HISTORY-001: View Transaction History -**Priority:** P2 (Medium) - -**Test Steps:** -1. User performs multiple credit operations -2. Navigate to transaction history -3. Verify all transactions listed -4. Check pagination - -**Expected Results:** -- All transactions displayed chronologically -- Each entry shows: Date, Operation, Amount, Balance -- Pagination for large histories -- Filter/search options - ---- - -## 3. Security Testing - -### 3.1 Authentication Security Tests - -#### TC-SEC-AUTH-001: SQL Injection Prevention -**Priority:** P0 (Critical) - -**Test Steps:** -1. Attempt login with SQL injection payloads: - - `admin'--` - - `' OR '1'='1` - - `'; DROP TABLE users;--` -2. Verify all rejected - -**Expected Results:** -- All attempts fail with 400/401 -- No database queries executed with injected SQL -- Input sanitized/parameterized - -#### TC-SEC-AUTH-002: JWT Token Manipulation -**Priority:** P0 (Critical) - -**Test Steps:** -1. Obtain valid JWT token -2. Modify claims (e.g., change user ID) -3. Re-sign with wrong secret -4. Submit modified token -5. Verify rejection - -**Expected Results:** -- Signature validation fails -- 401 Unauthorized -- Request denied -- Original user unaffected - -#### TC-SEC-AUTH-003: Token Expiration Enforcement -**Priority:** P0 (Critical) - -**Test Steps:** -1. Obtain valid token -2. Wait for expiration time -3. Use expired token -4. Verify rejection - -**Expected Results:** -- 401 Unauthorized -- Error: "Token expired" -- Automatic refresh triggered (if refreshToken valid) - -#### TC-SEC-AUTH-004: Brute Force Protection -**Priority:** P1 (High) - -**Test Steps:** -1. Attempt login with wrong password 5 times -2. Verify account locked or rate limited -3. Check cooldown period - -**Expected Results:** -- After 5 failed attempts: Account temporarily locked -- Lockout duration: 15 minutes -- User notified via email (optional) -- Subsequent attempts rejected with 429 status - -**Implementation:** -```typescript -// Rate limiting configuration -{ - maxAttempts: 5, - windowMs: 15 * 60 * 1000, // 15 minutes - message: "Too many login attempts. Please try again later." -} -``` - -#### TC-SEC-AUTH-005: Password Storage Security -**Priority:** P0 (Critical) - -**Test Steps:** -1. Create account with password -2. Access database directly -3. Verify password hashed -4. Check hash algorithm - -**Expected Results:** -- Password NOT stored in plaintext -- Bcrypt/Argon2 hashing used -- Salt included in hash -- Hash format: `$2a$10$...` (bcrypt) or similar - -### 3.2 Credit System Security Tests - -#### TC-SEC-CREDIT-001: Credit Balance Tampering -**Priority:** P0 (Critical) - -**Test Steps:** -1. Attempt to modify credit balance via API manipulation -2. Send crafted requests with inflated balance -3. Directly modify client-side storage -4. Verify all attempts fail - -**Expected Results:** -- Server-side validation rejects all tampering -- Balance only modifiable via authorized endpoints -- JWT claims for credits are read-only -- Client-side changes overwritten by server - -#### TC-SEC-CREDIT-002: Unauthorized Credit Deduction -**Priority:** P0 (Critical) - -**Test Steps:** -1. User A attempts to deduct credits from User B -2. Forge JWT with different user ID -3. Attempt API calls with manipulated token - -**Expected Results:** -- All attempts fail with 401/403 -- User B's credits unchanged -- Audit log records suspicious activity - -#### TC-SEC-CREDIT-003: Replay Attack Prevention -**Priority:** P1 (High) - -**Test Steps:** -1. Capture valid credit purchase webhook -2. Replay webhook multiple times -3. Verify duplicate detection - -**Expected Results:** -- Only first webhook processed -- Duplicates detected by transaction ID -- No double-crediting - -### 3.3 Rate Limiting Tests - -#### TC-SEC-RATE-001: API Rate Limiting -**Priority:** P1 (High) - -**Test Steps:** -1. Make 100 API requests in 1 minute -2. Verify rate limit enforced -3. Check error response - -**Expected Results:** -- Rate limit: 100 requests/minute per user -- After limit: 429 Too Many Requests -- Retry-After header provided -- Limit resets after window - -**Rate Limit Configuration:** -```typescript -{ - '/auth/signin': { max: 10, window: '1m' }, - '/auth/refresh': { max: 20, window: '1m' }, - '/api/*': { max: 100, window: '1m' } -} -``` - -#### TC-SEC-RATE-002: Credit Operation Rate Limiting -**Priority:** P2 (Medium) - -**Test Steps:** -1. Perform 50 credit-consuming operations rapidly -2. Verify rate limiting or throttling -3. Check if legitimate operations still work - -**Expected Results:** -- Suspicious rapid operations flagged -- Possible CAPTCHA or verification required -- Normal user activity not impacted - ---- - -## 4. Integration Testing - -### 4.1 Mobile App Integration Tests - -#### TC-INT-MOBILE-001: iOS App Authentication Flow -**Priority:** P0 (Critical) - -**Test Steps:** -1. Install iOS app (Memoro) -2. Register new account -3. Verify token storage in SecureStore -4. Close and reopen app -5. Check session persistence -6. Make API call requiring authentication - -**Expected Results:** -- Registration succeeds -- Tokens stored in iOS Keychain via SecureStore -- App reopens with user still authenticated -- API calls succeed with valid token - -**Platform-Specific Checks:** -- SecureStore API usage -- Background token refresh handling -- App backgrounding behavior - -#### TC-INT-MOBILE-002: Android App Authentication Flow -**Priority:** P0 (Critical) - -**Test Steps:** -1. Install Android app (Memoro) -2. Register new account -3. Verify token storage in SecureStore -4. Close and reopen app -5. Check session persistence - -**Expected Results:** -- Similar to iOS -- Tokens stored in Android Keystore via SecureStore -- Handle Android-specific lifecycle events - -#### TC-INT-MOBILE-003: React Native Token Refresh -**Priority:** P0 (Critical) - -**Test Steps:** -1. Login on mobile app -2. Wait for token expiry -3. Make API call -4. Verify automatic refresh -5. Check UI remains responsive - -**Expected Results:** -- Refresh handled by TokenManager -- UI shows loading indicator -- API call succeeds after refresh -- User unaware of background process - -### 4.2 Web App Integration Tests - -#### TC-INT-WEB-001: SvelteKit Authentication (Memoro Web) -**Priority:** P0 (Critical) - -**Test Steps:** -1. Open web app in browser -2. Register account -3. Verify tokens in localStorage -4. Refresh browser page -5. Check session restored - -**Expected Results:** -- Tokens stored in localStorage -- Page refresh maintains authentication -- SSR (server-side rendering) respects auth state -- Protected routes accessible - -#### TC-INT-WEB-002: Cross-Browser Compatibility -**Priority:** P1 (High) - -**Test Steps:** -1. Test authentication in Chrome, Safari, Firefox, Edge -2. Verify consistent behavior -3. Check localStorage access -4. Test token refresh - -**Expected Results:** -- All browsers work identically -- No storage access issues -- Token refresh works across all browsers - -### 4.3 Cross-App Integration Tests - -#### TC-INT-CROSS-001: Memoro to Maerchenzauber Auth -**Priority:** P0 (Critical) - -**Test Steps:** -1. Login to Memoro app -2. Open Maerchenzauber app (same device/browser) -3. Verify authentication state -4. Check credit balance visibility - -**Expected Results:** -- User authenticated in both apps (if SSO enabled) -- OR: Separate login required but same user account recognized -- Credit balance synchronized -- app_id claim in JWT differentiates apps - -#### TC-INT-CROSS-002: Multi-App Credit Consumption -**Priority:** P0 (Critical) - -**Test Steps:** -1. User has 100 credits -2. Consume 30 credits in Memoro (AI transcription) -3. Immediately check balance in Maerchenzauber -4. Consume 20 credits in Maerchenzauber (story generation) -5. Check final balance in both apps - -**Expected Results:** -- Memoro: Balance updates to 70 credits -- Maerchenzauber: Shows 70 credits -- Second operation: Balance updates to 50 -- Both apps show final balance: 50 credits -- Real-time sync (< 1 second delay) - -### 4.4 Payment Gateway Integration Tests - -#### TC-INT-PAYMENT-001: RevenueCat Purchase Flow (iOS) -**Priority:** P0 (Critical) - -**Test Steps:** -1. Login to Memoro iOS app -2. Navigate to subscription page -3. Purchase 100 credits -4. Complete Apple Pay transaction -5. Verify webhook received -6. Check credit balance updated - -**Expected Results:** -- RevenueCat processes purchase -- Webhook sent to backend -- Credits added to user account -- User sees updated balance -- Receipt validated - -**RevenueCat Specifics:** -- User identified with UUID -- StoreKit 2 integration on iOS -- Purchase restoration works across devices - -#### TC-INT-PAYMENT-002: RevenueCat Purchase Flow (Android) -**Priority:** P0 (Critical) - -**Test Steps:** -1. Login to Memoro Android app -2. Purchase credits -3. Complete Google Play transaction -4. Verify webhook and credit update - -**Expected Results:** -- Similar to iOS -- Google Play Billing integration -- Webhook processing - -#### TC-INT-PAYMENT-003: RevenueCat Purchase Flow (Web) -**Priority:** P1 (High) - -**Test Steps:** -1. Login to Memoro web app -2. Purchase credits (Stripe or other web payment) -3. Complete payment -4. Verify webhook and credit update - -**Expected Results:** -- Payment processed via Stripe -- Webhook processed -- Credits updated - -### 4.5 Backend Service Integration Tests - -#### TC-INT-BACKEND-001: NestJS Backend Auth Flow (Maerchenzauber) -**Priority:** P0 (Critical) - -**Test Steps:** -1. Mobile app sends login request -2. Backend validates with middleware -3. Backend returns tokens -4. Backend validates subsequent API calls with JWT - -**Expected Results:** -- Backend acts as auth proxy -- Supabase RLS policies enforced -- JWT claims validated on every request -- Invalid tokens rejected with 401 - -#### TC-INT-BACKEND-002: Credit Deduction in Backend Pipeline -**Priority:** P0 (Critical) - -**Test Steps:** -1. User requests story creation (Maerchenzauber backend) -2. Backend validates credits via Mana Core -3. Story generated -4. Backend consumes credits -5. Check transaction logged - -**Expected Results:** -- Credit validation before operation -- Operation executes only if credits available -- Credits deducted after success -- Rollback if operation fails - -**Code Reference:** -```typescript -// See: maerchenzauber/apps/backend/src/pipeline/character/steps/deduct-credits.step.ts -``` - ---- - -## 5. Performance Testing - -### 5.1 Load Testing - -#### TC-PERF-LOAD-001: Concurrent User Logins -**Priority:** P1 (High) - -**Test Configuration:** -- Virtual Users: 1000 -- Ramp-up: 10 seconds -- Duration: 5 minutes - -**Test Steps:** -1. Simulate 1000 users logging in concurrently -2. Measure response times -3. Check success rate -4. Monitor server resources - -**Expected Results:** -- 95% of requests complete in < 2 seconds -- 99% of requests complete in < 5 seconds -- Success rate: > 99% -- No server crashes or timeouts -- CPU usage < 80% -- Memory usage stable - -**Performance Metrics:** -``` -Concurrent Users: 1000 -Avg Response Time: < 500ms -P95 Response Time: < 2s -P99 Response Time: < 5s -Error Rate: < 1% -``` - -#### TC-PERF-LOAD-002: Token Refresh Under Load -**Priority:** P1 (High) - -**Test Configuration:** -- Virtual Users: 500 -- Simultaneous expired tokens: 500 -- Duration: 2 minutes - -**Test Steps:** -1. 500 users with expired tokens make API calls -2. Measure refresh endpoint performance -3. Check queue handling -4. Verify no duplicate refreshes - -**Expected Results:** -- Refresh endpoint handles 500 concurrent requests -- Token manager queue processes efficiently -- Avg response time: < 1 second -- No request timeouts -- All users successfully refreshed - -#### TC-PERF-LOAD-003: Credit Balance Checks at Scale -**Priority:** P1 (High) - -**Test Configuration:** -- Virtual Users: 2000 -- Requests/second: 100 -- Duration: 10 minutes - -**Test Steps:** -1. 2000 users checking credit balance simultaneously -2. Measure database query performance -3. Check caching effectiveness - -**Expected Results:** -- Query time: < 50ms -- Database connection pool stable -- Caching reduces database load -- No connection exhaustion - -### 5.2 Stress Testing - -#### TC-PERF-STRESS-001: Credit Deduction Stress Test -**Priority:** P1 (High) - -**Test Configuration:** -- Virtual Users: 100 -- Operations per user: 50 -- Total operations: 5000 - -**Test Steps:** -1. 100 users each perform 50 credit-consuming operations -2. Measure transaction throughput -3. Check for race conditions or double-deductions -4. Verify all balances correct - -**Expected Results:** -- All 5000 operations complete successfully -- No over-deductions or under-deductions -- Database transactions maintain consistency -- Final balances reconcile with transaction logs - -#### TC-PERF-STRESS-002: Payment Webhook Storm -**Priority:** P2 (Medium) - -**Test Configuration:** -- Concurrent webhooks: 1000 -- Duplicate percentage: 20% - -**Test Steps:** -1. Send 1000 webhook notifications rapidly -2. Include 200 duplicate webhooks -3. Measure processing time -4. Verify idempotency - -**Expected Results:** -- All unique webhooks processed -- Duplicates detected and ignored -- No double-crediting -- Processing time: < 5 seconds for all -- Database remains consistent - -### 5.3 Scalability Testing - -#### TC-PERF-SCALE-001: Database Scaling - Credit Transactions -**Priority:** P2 (Medium) - -**Test Scenario:** -- Simulate 1 million credit transactions over 24 hours -- Monitor database growth -- Check query performance degradation - -**Expected Results:** -- Database handles high transaction volume -- Indexes maintain query performance -- No significant slowdown over time -- Automated cleanup/archiving if needed - ---- - -## 6. Acceptance Criteria - -### 6.1 Authentication System Acceptance - -**AC-AUTH-001:** User can register with email/password in < 3 seconds -**AC-AUTH-002:** User can login with email/password in < 2 seconds -**AC-AUTH-003:** Token refresh happens automatically without user interaction -**AC-AUTH-004:** User remains logged in for 30 days (refreshToken lifetime) -**AC-AUTH-005:** Password reset email arrives within 5 minutes -**AC-AUTH-006:** Multi-device login works for up to 5 devices simultaneously -**AC-AUTH-007:** 99.9% uptime for authentication services - -### 6.2 Credit System Acceptance - -**AC-CREDIT-001:** Credit balance updates within 1 second of purchase -**AC-CREDIT-002:** Credit deduction happens only after operation succeeds -**AC-CREDIT-003:** Failed operations never charge credits -**AC-CREDIT-004:** Credit balance visible across all apps within 1 second -**AC-CREDIT-005:** Transaction history available for 24 months -**AC-CREDIT-006:** No race conditions allow negative balance -**AC-CREDIT-007:** Refunds processed within 1 hour (automated) - -### 6.3 Integration Acceptance - -**AC-INT-001:** Mobile apps support iOS 14+ and Android 10+ -**AC-INT-002:** Web apps work on Chrome, Safari, Firefox, Edge (latest 2 versions) -**AC-INT-003:** RevenueCat purchase flow completes in < 30 seconds -**AC-INT-004:** Backend API response time < 500ms for 95% of requests -**AC-INT-005:** Cross-app authentication works seamlessly - -### 6.4 Security Acceptance - -**AC-SEC-001:** No plaintext passwords stored anywhere -**AC-SEC-002:** JWT tokens secured with RS256 algorithm -**AC-SEC-003:** Rate limiting prevents brute force attacks -**AC-SEC-004:** SQL injection attempts blocked 100% -**AC-SEC-005:** XSS vulnerabilities: 0 critical, 0 high -**AC-SEC-006:** Penetration test: No critical vulnerabilities - -### 6.5 Performance Acceptance - -**AC-PERF-001:** System handles 1000 concurrent users without degradation -**AC-PERF-002:** 99th percentile response time < 3 seconds -**AC-PERF-003:** Token refresh completes in < 2 seconds -**AC-PERF-004:** Credit balance check < 100ms -**AC-PERF-005:** Database can scale to 10 million users - ---- - -## 7. Regression Testing - -### 7.1 Regression Test Suite - -**RT-001:** Core Authentication Flows -- Run after every auth system change -- Includes: Login, registration, logout, refresh - -**RT-002:** Credit Balance & Consumption -- Run after every credit system change -- Includes: Purchase, deduction, balance check - -**RT-003:** Multi-App Integration -- Run after any app deployment -- Includes: Cross-app auth, credit sync - -**RT-004:** Security Regression -- Run monthly or after security patches -- Includes: All security test cases - -### 7.2 Automated Regression Schedule - -```yaml -Daily: - - Smoke tests (critical paths) - - Core auth flows - - Credit balance checks - -Weekly: - - Full regression suite - - Integration tests - - Performance smoke tests - -Monthly: - - Full security audit - - Load testing - - Penetration testing - -After Each Deployment: - - Smoke tests (5 minutes) - - Core regression (30 minutes) - - Integration verification (15 minutes) -``` - ---- - -## 8. Test Environments - -### 8.1 Environment Configuration - -#### Development Environment -- **Purpose:** Developer testing -- **Database:** Supabase dev project -- **Middleware:** Local middleware instance -- **Payment:** Mock payment gateway (no real charges) -- **Data:** Test user accounts, synthetic credit data - -#### Staging Environment -- **Purpose:** Pre-production testing, QA validation -- **Database:** Supabase staging project (copy of production schema) -- **Middleware:** Staging middleware instance -- **Payment:** RevenueCat sandbox mode -- **Data:** Anonymized production data sample - -#### Production Environment -- **Purpose:** Live user traffic -- **Database:** Supabase production project -- **Middleware:** Production middleware cluster -- **Payment:** RevenueCat production mode (real charges) -- **Data:** Live user data (protected by RLS) - -### 8.2 Test Data Management - -**Test Users:** -```javascript -{ - testUser1: { email: "test+user1@manacore.com", password: "Test123!@#", credits: 1000 }, - testUser2: { email: "test+user2@manacore.com", password: "Test123!@#", credits: 0 }, - testUserB2B: { email: "test+b2b@manacore.com", password: "Test123!@#", b2b: true } -} -``` - -**Test Credit Packages:** -```javascript -{ - small: { credits: 100, price: 4.99 }, - medium: { credits: 500, price: 19.99 }, - large: { credits: 1000, price: 34.99 } -} -``` - ---- - -## 9. Test Automation Strategy - -### 9.1 Unit Tests - -**Coverage Target:** 80% minimum - -**Framework:** Jest - -**Test Files:** -- `packages/shared-auth/src/**/*.test.ts` -- `packages/shared-credit-service/src/**/*.test.ts` - -**Example:** -```typescript -describe('AuthService', () => { - it('should sign in with valid credentials', async () => { - const result = await authService.signIn('test@example.com', 'password'); - expect(result.success).toBe(true); - }); -}); -``` - -### 9.2 Integration Tests - -**Coverage Target:** Critical paths 100% - -**Framework:** Jest + Supertest (for API tests) - -**Test Files:** -- `maerchenzauber/apps/backend/test/*.test.ts` -- `memoro/apps/mobile/features/auth/__tests__/*.test.ts` - -**Example:** -```typescript -describe('Credit Purchase Flow', () => { - it('should add credits after successful payment', async () => { - const response = await request(app) - .post('/webhooks/revenuecat') - .send(mockWebhookPayload); - - expect(response.status).toBe(200); - const balance = await getCredits(userId); - expect(balance).toBe(previousBalance + 100); - }); -}); -``` - -### 9.3 E2E Tests - -**Coverage Target:** User journeys 100% - -**Framework:** Detox (mobile), Playwright (web) - -**Test Files:** -- `memoro/apps/mobile/e2e/*.e2e.ts` -- `memoro/apps/web/tests/*.spec.ts` - -**Example:** -```typescript -describe('User Registration Journey', () => { - it('should register, login, and access protected content', async () => { - await element(by.id('register-button')).tap(); - await element(by.id('email-input')).typeText('new@example.com'); - await element(by.id('password-input')).typeText('SecureP@ss123'); - await element(by.id('submit-button')).tap(); - - await waitFor(element(by.id('home-screen'))).toBeVisible().withTimeout(5000); - expect(element(by.id('credit-balance'))).toBeVisible(); - }); -}); -``` - -### 9.4 Performance Tests - -**Framework:** k6 - -**Test Files:** -- `tests/performance/auth-load.js` -- `tests/performance/credit-stress.js` - -**Example:** -```javascript -import http from 'k6/http'; -import { check, sleep } from 'k6'; - -export const options = { - stages: [ - { duration: '2m', target: 100 }, - { duration: '5m', target: 1000 }, - { duration: '2m', target: 0 }, - ], -}; - -export default function () { - const res = http.post('https://api.manacore.com/auth/signin', { - email: 'test@example.com', - password: 'password', - }); - - check(res, { 'status is 200': (r) => r.status === 200 }); - sleep(1); -} -``` - -### 9.5 CI/CD Integration - -**Pipeline Stages:** -1. **Pre-commit:** Lint, unit tests (local) -2. **Pull Request:** Unit tests, integration tests, security scan -3. **Staging Deploy:** Full regression suite, performance smoke tests -4. **Production Deploy:** Smoke tests, monitoring alert setup - -**GitHub Actions Example:** -```yaml -name: Test & Deploy - -on: [push, pull_request] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - run: pnpm install - - run: pnpm run test:unit - - run: pnpm run test:integration - - run: pnpm run test:e2e - - performance: - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/main' - steps: - - uses: actions/checkout@v3 - - run: k6 run tests/performance/auth-load.js -``` - ---- - -## 10. Compliance & Audit - -### 10.1 Payment Compliance Testing - -**PCI DSS Requirements:** -- TC-COMP-PCI-001: No credit card data stored locally -- TC-COMP-PCI-002: Payment processed via certified gateway (RevenueCat) -- TC-COMP-PCI-003: Secure transmission (HTTPS only) - -### 10.2 GDPR Compliance Testing - -**Data Privacy:** -- TC-COMP-GDPR-001: User can delete account and all data -- TC-COMP-GDPR-002: User can export all personal data -- TC-COMP-GDPR-003: Consent for data processing obtained - -### 10.3 Audit Logging - -**Requirements:** -- All credit transactions logged with timestamp, user, amount, operation -- All authentication events logged (login, logout, refresh) -- Logs retained for 12 months minimum -- Logs tamper-proof and auditable - -**Test Cases:** -- TC-AUDIT-001: Verify credit transaction log completeness -- TC-AUDIT-002: Verify auth event log accuracy -- TC-AUDIT-003: Test log export functionality - ---- - -## 11. Risk Mitigation - -### 11.1 High-Risk Scenarios - -**Risk:** Credit double-deduction due to race condition -**Mitigation:** Database transactions, optimistic locking -**Test:** TC-CREDIT-CONSUME-003 - -**Risk:** Token hijacking/replay attacks -**Mitigation:** Short token lifetime, HTTPS only, refresh rotation -**Test:** TC-SEC-AUTH-002, TC-SEC-CREDIT-003 - -**Risk:** Payment webhook failure (credits not added) -**Mitigation:** Webhook retry mechanism, idempotency keys, manual reconciliation -**Test:** TC-CREDIT-PURCHASE-004 - -**Risk:** Concurrent login causing session conflicts -**Mitigation:** Independent refresh tokens per device -**Test:** TC-AUTH-SESSION-001 - -### 11.2 Disaster Recovery Testing - -**Scenario:** Database failure during credit purchase -**Test:** Verify rollback mechanism, no lost credits -**Recovery Time Objective (RTO):** < 1 hour -**Recovery Point Objective (RPO):** < 5 minutes - -**Scenario:** Middleware authentication service down -**Test:** Graceful degradation, cached credentials, retry logic -**RTO:** < 15 minutes (failover to backup) - ---- - -## 12. Test Execution Schedule - -### 12.1 Sprint Testing - -**Week 1-2 (Development):** -- Unit tests written alongside features -- Developer-run integration tests -- Daily: Smoke tests - -**Week 3 (QA Testing):** -- Full manual test execution -- Automated regression suite -- Performance baseline tests -- Security scan - -**Week 4 (Pre-Release):** -- Staging environment validation -- User acceptance testing (UAT) -- Load testing -- Final security check - -### 12.2 Release Testing - -**Pre-Deployment:** -- Run full regression suite -- Performance smoke test -- Security scan -- Backup verification - -**Post-Deployment:** -- Smoke tests (5 minutes) -- Monitoring validation (15 minutes) -- Canary deployment testing (1 hour) - ---- - -## 13. Tools & Resources - -### 13.1 Testing Tools - -**Unit & Integration:** -- Jest (JavaScript testing framework) -- Supertest (HTTP API testing) -- React Native Testing Library - -**E2E:** -- Detox (React Native E2E) -- Playwright (Web E2E) -- Appium (mobile alternative) - -**Performance:** -- k6 (load testing) -- Lighthouse (web performance) -- New Relic (production monitoring) - -**Security:** -- OWASP ZAP (security scanner) -- Snyk (dependency vulnerability scanning) -- SonarQube (code quality & security) - -### 13.2 Test Management - -**Test Case Repository:** GitHub Wiki or Notion -**Bug Tracking:** GitHub Issues with labels (bug, critical, security) -**Test Execution:** Manual execution logged in test management tool -**CI/CD:** GitHub Actions - -### 13.3 Documentation - -**For Developers:** -- `maerchenzauber/apps/mobile/AUTH_TESTING_GUIDE.md` -- `packages/shared-auth/README.md` -- `manadeck/CREDIT_SYSTEM.md` - -**For QA:** -- This document (TESTING_STRATEGY_AUTH_CREDITS.md) -- Test case templates in `tests/templates/` - ---- - -## 14. Appendix - -### A. Test Case Template - -```markdown -#### TC-[CATEGORY]-[MODULE]-[ID]: [Test Name] -**Priority:** P0/P1/P2 -**Description:** [Brief description] - -**Preconditions:** -- [Setup required] - -**Test Steps:** -1. [Step 1] -2. [Step 2] -... - -**Expected Results:** -- [Expected outcome 1] -- [Expected outcome 2] - -**Test Data:** -[Data needed for test] - -**Post-Conditions:** -- [Cleanup steps] -``` - -### B. Bug Report Template - -```markdown -**Title:** [Brief description] -**Severity:** Critical / High / Medium / Low -**Environment:** Dev / Staging / Production -**Device/Browser:** [Details] - -**Steps to Reproduce:** -1. [Step 1] -2. [Step 2] - -**Expected Behavior:** -[What should happen] - -**Actual Behavior:** -[What actually happens] - -**Screenshots/Logs:** -[Attach evidence] - -**Related Test Case:** TC-XXX-XXX-XXX -``` - -### C. Glossary - -**appToken:** Supabase-compatible JWT token for API access -**refreshToken:** Long-lived token for obtaining new appToken -**manaToken:** Authentication token from Mana Core middleware -**RLS:** Row Level Security (Supabase database security) -**JWT:** JSON Web Token -**SecureStore:** Expo secure storage API (Keychain on iOS, Keystore on Android) -**TokenManager:** Service managing token lifecycle and refresh -**RevenueCat:** Third-party subscription and payment management platform -**B2B:** Business-to-Business (enterprise accounts) - ---- - -## Document Control - -**Version History:** - -| Version | Date | Author | Changes | -|---------|------|--------|---------| -| 1.0 | 2025-11-25 | TESTER Agent | Initial comprehensive test strategy | - -**Review & Approval:** - -- [ ] Technical Lead Review -- [ ] QA Lead Review -- [ ] Security Team Review -- [ ] Product Owner Approval - -**Next Review Date:** 2025-12-25 - ---- - -**END OF DOCUMENT** diff --git a/TESTING_STRATEGY_EXECUTIVE_SUMMARY.md b/TESTING_STRATEGY_EXECUTIVE_SUMMARY.md deleted file mode 100644 index 6413f6616..000000000 --- a/TESTING_STRATEGY_EXECUTIVE_SUMMARY.md +++ /dev/null @@ -1,513 +0,0 @@ -# Executive Summary: Authentication & Credit System Testing Strategy - -**Project:** Manacore Monorepo - Central Authentication & Credit System -**Date:** 2025-11-25 -**Prepared by:** TESTER Agent (Hive Mind) - ---- - -## Overview - -This document summarizes the comprehensive testing strategy for the central authentication and mana credit system that powers all Manacore applications (Memoro, Maerchenzauber, Manadeck, Picture, Chat). - -**Full Strategy Document:** `/TESTING_STRATEGY_AUTH_CREDITS.md` - ---- - -## Critical Business Paths - -### Priority 1: Authentication Flow - -1. **User Registration** β†’ Tokens Generated β†’ Secure Storage β†’ Access Granted -2. **User Login** β†’ Token Validation β†’ Session Established β†’ Multi-Device Support -3. **Token Expiration** β†’ Automatic Refresh β†’ Seamless Continuation -4. **User Logout** β†’ Token Invalidation β†’ Secure Cleanup - -### Priority 2: Credit System Flow - -1. **Credit Purchase** β†’ Payment Validation β†’ Balance Update β†’ Transaction Logged -2. **Pre-Operation Validation** β†’ Operation Execution β†’ Credit Deduction β†’ Balance Update -3. **Failed Operation** β†’ No Charge Applied β†’ User Notified -4. **Cross-App Sync** β†’ Real-Time Balance β†’ Consistent State - ---- - -## Test Coverage Summary - -### Authentication Testing (45 Test Cases) - -| Category | Test Cases | Priority | Coverage | -| --------------------------- | ---------- | -------- | -------- | -| Registration (Email/Social) | 8 | P0 | 100% | -| Login/Logout | 10 | P0 | 100% | -| Token Refresh | 6 | P0 | 100% | -| Session Management | 6 | P1 | 100% | -| Password Management | 5 | P1 | 90% | -| Multi-Device/Multi-App | 10 | P0-P1 | 100% | - -**Key Security Tests:** - -- SQL Injection Prevention βœ“ -- JWT Token Manipulation βœ“ -- Token Expiration Enforcement βœ“ -- Brute Force Protection βœ“ -- Password Storage Security βœ“ - -### Credit System Testing (38 Test Cases) - -| Category | Test Cases | Priority | Coverage | -| ----------------------- | ---------- | -------- | -------- | -| Credit Purchase | 6 | P0 | 100% | -| Balance Checking | 4 | P0 | 100% | -| Credit Consumption | 8 | P0 | 100% | -| Refund & Adjustments | 4 | P1 | 100% | -| Transaction History | 4 | P2 | 90% | -| Concurrent Transactions | 6 | P0 | 100% | -| Cross-App Visibility | 6 | P0 | 100% | - -**Key Security Tests:** - -- Balance Tampering Prevention βœ“ -- Unauthorized Deduction Prevention βœ“ -- Replay Attack Prevention βœ“ -- Race Condition Handling βœ“ -- Negative Balance Prevention βœ“ - -### Integration Testing (15 Test Cases) - -| Platform | Test Cases | Priority | -| ---------------------------- | ---------- | -------- | -| iOS Mobile (Expo) | 3 | P0 | -| Android Mobile (Expo) | 3 | P0 | -| Web (SvelteKit) | 3 | P0 | -| Backend (NestJS) | 3 | P0 | -| Payment Gateway (RevenueCat) | 3 | P0 | - -### Performance Testing (12 Test Cases) - -| Test Type | Scenarios | Load Target | -| ------------------- | --------- | --------------------- | -| Load Testing | 3 | 1000 concurrent users | -| Stress Testing | 2 | 5000 operations | -| Scalability Testing | 2 | 1M transactions/day | - -**Performance Targets:** - -- Login Response Time: < 2 seconds (P95) -- Token Refresh: < 2 seconds (P95) -- Credit Balance Check: < 100ms (P95) -- API Response Time: < 500ms (P95) - ---- - -## Test Automation Breakdown - -### Unit Tests - -- **Framework:** Jest -- **Coverage Target:** 80%+ -- **Location:** `packages/shared-auth/`, `packages/shared-credit-service/` -- **Run Frequency:** Every commit (pre-commit hook) - -### Integration Tests - -- **Framework:** Jest + Supertest -- **Coverage Target:** 100% critical paths -- **Location:** `*/apps/backend/test/`, `*/apps/mobile/features/*/tests/` -- **Run Frequency:** Every pull request - -### E2E Tests - -- **Framework:** Detox (mobile), Playwright (web) -- **Coverage Target:** 100% user journeys -- **Location:** `*/apps/*/e2e/`, `*/apps/*/tests/` -- **Run Frequency:** Pre-staging deployment - -### Performance Tests - -- **Framework:** k6 -- **Target:** 1000 concurrent users without degradation -- **Location:** `tests/performance/` -- **Run Frequency:** Weekly + pre-production deployment - ---- - -## Critical Test Scenarios - -### 1. Concurrent Credit Deduction (Race Condition) - -**Risk:** High - Could cause financial discrepancies -**Test:** TC-CREDIT-CONSUME-003 -**Mitigation:** Database transactions with optimistic locking - -**Scenario:** - -- User has 100 credits -- 3 operations triggered simultaneously (30 credits each) -- Expected: All succeed, final balance = 10 credits -- Test validates: No over-deduction or under-deduction - -### 2. Token Refresh During High Load - -**Risk:** Medium - User experience degradation -**Test:** TC-PERF-LOAD-002 -**Mitigation:** Token manager queue + cooldown mechanism - -**Scenario:** - -- 500 users with expired tokens make API calls simultaneously -- Expected: Single refresh per user, all requests succeed -- Test validates: No duplicate refreshes, queue handles load - -### 3. Payment Webhook Duplicate Detection - -**Risk:** High - Could cause double-crediting -**Test:** TC-CREDIT-PURCHASE-003 -**Mitigation:** Idempotency keys, transaction ID validation - -**Scenario:** - -- Webhook received successfully -- Same webhook replayed (network retry) -- Expected: Second webhook ignored, no double-crediting -- Test validates: Idempotent processing - -### 4. Cross-App Credit Synchronization - -**Risk:** Medium - User confusion, trust issues -**Test:** TC-INT-CROSS-002 -**Mitigation:** Central credit service, real-time updates - -**Scenario:** - -- Consume credits in Memoro -- Immediately check balance in Maerchenzauber -- Expected: Balance updated in < 1 second -- Test validates: Consistent state across apps - -### 5. Multi-Device Session Management - -**Risk:** Low - Potential token conflicts -**Test:** TC-AUTH-SESSION-001 -**Mitigation:** Independent refresh tokens per device - -**Scenario:** - -- User logs in on iOS, Android, and Web -- All devices active simultaneously -- Token refresh on one device -- Expected: No interference with other devices -- Test validates: Device isolation, concurrent usage - ---- - -## Security Testing Highlights - -### Authentication Security - -**SQL Injection Prevention (TC-SEC-AUTH-001)** - -- Test payloads: `admin'--`, `' OR '1'='1`, `'; DROP TABLE users;--` -- Expected: All rejected, no DB queries executed -- Result: PASS βœ“ (parameterized queries used) - -**JWT Token Manipulation (TC-SEC-AUTH-002)** - -- Modify token claims (user ID, role, credits) -- Re-sign with wrong secret -- Expected: Signature validation fails, 401 error -- Result: PASS βœ“ (RS256 verification) - -**Brute Force Protection (TC-SEC-AUTH-004)** - -- 5 failed login attempts -- Expected: Account locked for 15 minutes -- Result: PASS βœ“ (rate limiting implemented) - -### Credit System Security - -**Balance Tampering Prevention (TC-SEC-CREDIT-001)** - -- Attempt to modify balance via API manipulation -- Client-side storage modification -- Expected: Server-side validation rejects all attempts -- Result: PASS βœ“ (server-authoritative balance) - -**Replay Attack Prevention (TC-SEC-CREDIT-003)** - -- Capture and replay payment webhook -- Expected: Duplicate detected by transaction ID -- Result: PASS βœ“ (idempotency keys) - ---- - -## Acceptance Criteria Checklist - -### Authentication System - -- [x] User can register with email/password in < 3 seconds -- [x] User can login with email/password in < 2 seconds -- [x] Token refresh happens automatically without user interaction -- [x] User remains logged in for 30 days (refreshToken lifetime) -- [x] Password reset email arrives within 5 minutes -- [x] Multi-device login works for up to 5 devices simultaneously -- [x] 99.9% uptime for authentication services - -### Credit System - -- [x] Credit balance updates within 1 second of purchase -- [x] Credit deduction happens only after operation succeeds -- [x] Failed operations never charge credits -- [x] Credit balance visible across all apps within 1 second -- [x] Transaction history available for 24 months -- [x] No race conditions allow negative balance -- [x] Refunds processed within 1 hour (automated) - -### Integration - -- [x] Mobile apps support iOS 14+ and Android 10+ -- [x] Web apps work on Chrome, Safari, Firefox, Edge (latest 2 versions) -- [x] RevenueCat purchase flow completes in < 30 seconds -- [x] Backend API response time < 500ms for 95% of requests -- [x] Cross-app authentication works seamlessly - -### Security - -- [x] No plaintext passwords stored anywhere -- [x] JWT tokens secured with RS256 algorithm -- [x] Rate limiting prevents brute force attacks -- [x] SQL injection attempts blocked 100% -- [ ] XSS vulnerabilities: 0 critical, 0 high (requires security audit) -- [ ] Penetration test: No critical vulnerabilities (requires external audit) - -### Performance - -- [x] System handles 1000 concurrent users without degradation -- [x] 99th percentile response time < 3 seconds -- [x] Token refresh completes in < 2 seconds -- [x] Credit balance check < 100ms -- [ ] Database can scale to 10 million users (requires load test) - ---- - -## Test Execution Strategy - -### Daily (Automated) - -- Smoke tests (5 minutes) -- Core auth flows -- Credit balance checks -- CI/CD pipeline integration - -### Weekly (Automated + Manual) - -- Full regression suite (1 hour) -- Integration tests -- Performance smoke tests -- Security dependency scan - -### Monthly (Scheduled) - -- Full security audit -- Load testing (1000+ concurrent users) -- Penetration testing (external) -- Compliance review - -### Per Deployment (Automated) - -- Pre-deployment: Full regression (30 minutes) -- Post-deployment: Smoke tests (5 minutes) -- Canary deployment monitoring (1 hour) - ---- - -## Risk Assessment - -### Critical Risks (Requires Immediate Testing) - -**1. Credit Double-Deduction** - -- **Impact:** HIGH (Financial loss, legal liability) -- **Probability:** MEDIUM (Concurrent operations common) -- **Mitigation:** Database transactions, optimistic locking -- **Test:** TC-CREDIT-CONSUME-003, TC-CREDIT-CONSUME-004 - -**2. Payment Webhook Failure** - -- **Impact:** HIGH (Lost revenue, user frustration) -- **Probability:** MEDIUM (Network issues, gateway downtime) -- **Mitigation:** Idempotency, retry mechanism, manual reconciliation -- **Test:** TC-CREDIT-PURCHASE-003, TC-CREDIT-PURCHASE-004 - -**3. Token Hijacking** - -- **Impact:** HIGH (Account compromise, data breach) -- **Probability:** LOW (HTTPS enforced, short token lifetime) -- **Mitigation:** HTTPS only, token rotation, short expiry -- **Test:** TC-SEC-AUTH-002, TC-SEC-CREDIT-003 - -### Medium Risks (Monitor Closely) - -**4. Cross-App State Inconsistency** - -- **Impact:** MEDIUM (User confusion, support burden) -- **Probability:** MEDIUM (Caching issues, sync delays) -- **Mitigation:** Central credit service, real-time updates -- **Test:** TC-INT-CROSS-002 - -**5. Concurrent Login Session Conflicts** - -- **Impact:** MEDIUM (User experience disruption) -- **Probability:** LOW (Independent tokens per device) -- **Mitigation:** Device-specific refresh tokens -- **Test:** TC-AUTH-SESSION-001 - ---- - -## Test Environment Summary - -| Environment | Purpose | Payment | Database | -| --------------- | ----------------------------- | --------------------- | ------------------- | -| **Development** | Developer testing | Mock gateway | Supabase dev | -| **Staging** | QA validation, pre-production | RevenueCat sandbox | Supabase staging | -| **Production** | Live users | RevenueCat production | Supabase production | - ---- - -## Tools & Infrastructure - -### Testing Frameworks - -- **Unit/Integration:** Jest, Supertest -- **E2E:** Detox (mobile), Playwright (web) -- **Performance:** k6, Lighthouse -- **Security:** OWASP ZAP, Snyk, SonarQube - -### CI/CD - -- **Platform:** GitHub Actions -- **Stages:** Lint β†’ Unit Tests β†’ Integration Tests β†’ E2E Tests β†’ Deploy -- **Quality Gates:** 80% code coverage, 0 critical security issues, all tests passing - -### Monitoring - -- **Application:** New Relic, Sentry -- **Infrastructure:** Cloud provider monitoring -- **Alerts:** Slack integration for failures - ---- - -## Gaps & Recommendations - -### Current Gaps - -1. **Load Testing:** Not yet executed at full 1000 user scale - - **Recommendation:** Schedule weekly k6 load tests - - **Owner:** DevOps team - -2. **Penetration Testing:** No external security audit conducted - - **Recommendation:** Hire external security firm (quarterly) - - **Owner:** Security team - -3. **Mobile E2E Tests:** Only partial coverage on Detox - - **Recommendation:** Expand Detox test suite to 100% critical paths - - **Owner:** Mobile QA team - -4. **Chaos Engineering:** No failure injection testing - - **Recommendation:** Implement chaos testing for payment webhooks, DB failures - - **Owner:** Backend team - -### Future Enhancements - -1. **Visual Regression Testing:** Add Chromatic or Percy for UI consistency -2. **Accessibility Testing:** Ensure WCAG 2.1 AA compliance -3. **Internationalization Testing:** Validate all 32 languages (Memoro) -4. **Performance Monitoring:** Real-user monitoring (RUM) integration - ---- - -## Success Metrics - -### Test Coverage Goals - -- Unit Test Coverage: **> 80%** βœ“ -- Integration Test Coverage: **100% critical paths** βœ“ -- E2E Test Coverage: **100% user journeys** (In Progress) -- Security Test Coverage: **100% OWASP Top 10** βœ“ - -### Quality Metrics - -- Production Bugs: **< 5 critical bugs per quarter** -- Mean Time to Detection (MTTD): **< 1 hour** -- Mean Time to Resolution (MTTR): **< 4 hours for critical, < 24 hours for high** - -### Performance Metrics - -- API Response Time (P95): **< 500ms** βœ“ -- Token Refresh Time (P95): **< 2s** βœ“ -- Credit Balance Check (P95): **< 100ms** βœ“ -- System Uptime: **99.9%+** - ---- - -## Next Steps - -### Week 1: Test Infrastructure Setup - -- [ ] Configure k6 for load testing -- [ ] Set up Detox for mobile E2E -- [ ] Integrate security scanning into CI/CD -- [ ] Create test data management scripts - -### Week 2-3: Test Execution - -- [ ] Execute all P0 test cases manually -- [ ] Automate P0 test cases -- [ ] Run first load test (100 concurrent users) -- [ ] Security scan and vulnerability remediation - -### Week 4: Validation & Reporting - -- [ ] Full regression suite execution -- [ ] Performance baseline established -- [ ] Security audit report -- [ ] Test summary report to stakeholders - ---- - -## Conclusion - -This comprehensive testing strategy covers **110+ test cases** across authentication, credit system, integration, security, and performance domains. The strategy emphasizes: - -1. **Critical Path Coverage:** 100% coverage of high-risk authentication and financial flows -2. **Security-First Approach:** Extensive security testing to prevent fraud and data breaches -3. **Performance Validation:** Load testing to ensure system scales to business needs -4. **Automation:** CI/CD integration for continuous quality assurance - -**Estimated Effort:** - -- Initial Test Development: 4 weeks (2 QA engineers) -- Ongoing Regression Testing: 2 days/sprint -- Load Testing: 1 day/week -- Security Audits: 1 week/quarter (external) - -**Key Success Factors:** - -- Early involvement of QA in feature development -- Automated regression suite in CI/CD pipeline -- Regular security audits and penetration testing -- Performance monitoring and alerting - ---- - -**For detailed test cases, see:** `/TESTING_STRATEGY_AUTH_CREDITS.md` - -**For developer testing guide, see:** `maerchenzauber/apps/mobile/AUTH_TESTING_GUIDE.md` - -**For credit system docs, see:** `manadeck/CREDIT_SYSTEM.md` - ---- - -**Prepared by:** TESTER Agent (Hive Mind Collective Intelligence System) -**Review Status:** Draft - Awaiting Technical Lead and QA Lead Review -**Next Review:** 2025-12-25 diff --git a/TEST_CASES_SAMPLES.md b/TEST_CASES_SAMPLES.md deleted file mode 100644 index 4bacd0381..000000000 --- a/TEST_CASES_SAMPLES.md +++ /dev/null @@ -1,1093 +0,0 @@ -# Sample Test Cases: Authentication & Credit System - -**Detailed Test Case Examples with Data and Expected Results** -**Version:** 1.0 -**Date:** 2025-11-25 - ---- - -## Authentication Test Cases - -### TC-AUTH-REG-001: Email/Password Registration with Valid Credentials - -**Priority:** P0 (Critical) -**Component:** Authentication Service -**Feature:** User Registration - -**Preconditions:** -- Application running in test environment -- Database accessible -- Email service configured (or mocked) -- Test email: `test+reg001@manacore.com` not already registered - -**Test Data:** -```json -{ - "email": "test+reg001@manacore.com", - "password": "SecureP@ss123", - "deviceInfo": { - "deviceId": "test-device-001", - "deviceName": "iPhone 13 Pro", - "deviceType": "ios", - "appVersion": "1.0.0" - } -} -``` - -**Test Steps:** -1. Open registration screen -2. Enter email: `test+reg001@manacore.com` -3. Enter password: `SecureP@ss123` -4. Tap "Register" button -5. Wait for response - -**Expected Results:** - -**API Response (200 OK):** -```json -{ - "appToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", - "refreshToken": "rt_abc123def456...", - "needsVerification": false -} -``` - -**appToken Claims (Decoded):** -```json -{ - "sub": "550e8400-e29b-41d4-a716-446655440000", - "email": "test+reg001@manacore.com", - "role": "authenticated", - "app_id": "memoro", - "iat": 1701000000, - "exp": 1701003600 -} -``` - -**Database Validation:** -```sql -SELECT id, email, created_at, credits -FROM user_profiles -WHERE email = 'test+reg001@manacore.com'; - --- Expected: --- id: 550e8400-e29b-41d4-a716-446655440000 --- email: test+reg001@manacore.com --- created_at: 2025-11-25 10:00:00 --- credits: 150 (default free credits) -``` - -**Secure Storage Validation (Mobile):** -```typescript -// iOS Keychain / Android Keystore -const appToken = await SecureStore.getItemAsync('@auth/appToken'); -const refreshToken = await SecureStore.getItemAsync('@auth/refreshToken'); -const userEmail = await SecureStore.getItemAsync('@auth/userEmail'); - -expect(appToken).toBeTruthy(); -expect(refreshToken).toBeTruthy(); -expect(userEmail).toBe('test+reg001@manacore.com'); -``` - -**UI Validation:** -- User redirected to home screen -- Credit balance shows "150 Mana" -- User name/email displayed in profile - -**Post-Conditions:** -- User account created in database -- User authenticated -- Tokens stored securely -- User can access protected resources - ---- - -### TC-AUTH-LOGIN-002: Failed Login with Invalid Password - -**Priority:** P0 (Critical) -**Component:** Authentication Service -**Feature:** User Login - -**Preconditions:** -- User exists: `test+login002@manacore.com` with password `CorrectP@ss123` - -**Test Data:** -```json -{ - "email": "test+login002@manacore.com", - "password": "WrongPassword", - "deviceInfo": { - "deviceId": "test-device-002", - "deviceName": "Pixel 6 Pro", - "deviceType": "android" - } -} -``` - -**Test Steps:** -1. Open login screen -2. Enter email: `test+login002@manacore.com` -3. Enter incorrect password: `WrongPassword` -4. Tap "Login" button -5. Wait for response - -**Expected Results:** - -**API Response (401 Unauthorized):** -```json -{ - "success": false, - "error": "INVALID_CREDENTIALS" -} -``` - -**UI Validation:** -- Error message displayed: "Invalid email or password" -- Email field retains entered value -- Password field cleared -- No tokens stored -- User remains on login screen - -**Database Validation:** -```sql --- No new session created -SELECT * FROM auth_sessions -WHERE user_email = 'test+login002@manacore.com' - AND created_at > NOW() - INTERVAL '1 minute'; - --- Expected: 0 rows -``` - -**Security Validation:** -- Password not returned in response -- Generic error message (no hint that email exists) -- Failed attempt logged for brute-force detection - -**Post-Conditions:** -- User NOT authenticated -- No tokens in storage -- Failed login attempt recorded - ---- - -### TC-AUTH-REFRESH-001: Automatic Token Refresh on 401 - -**Priority:** P0 (Critical) -**Component:** Token Manager -**Feature:** Automatic Token Refresh - -**Preconditions:** -- User logged in -- appToken expired (or manually expired) -- refreshToken valid - -**Test Data:** - -**Initial State:** -```typescript -const expiredAppToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."; // exp: 1 hour ago -const validRefreshToken = "rt_valid123..."; // exp: 30 days from now -``` - -**Test Steps:** -1. User is logged in with expired appToken -2. User initiates API call: `GET /api/memos` -3. TokenManager detects expired token -4. TokenManager automatically calls `/auth/refresh` -5. New tokens received -6. Original API call retried with new token -7. API call succeeds - -**Expected Results:** - -**Token Refresh API Call:** -``` -POST /auth/refresh -Content-Type: application/json - -{ - "refreshToken": "rt_valid123...", - "deviceInfo": { - "deviceId": "test-device-003" - } -} -``` - -**Token Refresh Response (200 OK):** -```json -{ - "appToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.NEW_TOKEN", - "refreshToken": "rt_new456..." -} -``` - -**Token Manager State Transitions:** -``` -VALID β†’ EXPIRED β†’ REFRESHING β†’ VALID -``` - -**Network Calls:** -1. `GET /api/memos` β†’ 401 Unauthorized (expired token) -2. `POST /auth/refresh` β†’ 200 OK (new tokens) -3. `GET /api/memos` β†’ 200 OK (retry with new token) - -**Storage Updates:** -```typescript -// Old tokens replaced -await SecureStore.getItemAsync('@auth/appToken'); -// Returns: NEW_TOKEN - -await SecureStore.getItemAsync('@auth/refreshToken'); -// Returns: rt_new456... -``` - -**UI Validation:** -- No user interaction required -- Loading indicator shown during refresh (< 2 seconds) -- Memos displayed successfully -- No error messages - -**Performance:** -- Total time from initial API call to data displayed: < 3 seconds -- Refresh process: < 2 seconds - -**Post-Conditions:** -- User remains authenticated -- New tokens stored -- Original API call succeeded -- TokenManager state: VALID - ---- - -## Credit System Test Cases - -### TC-CREDIT-PURCHASE-001: Successful Credit Purchase - -**Priority:** P0 (Critical) -**Component:** Payment Service, Credit Service -**Feature:** Credit Purchase - -**Preconditions:** -- User authenticated: `test+credit001@manacore.com` -- Current balance: 10 credits -- Mock payment gateway configured - -**Test Data:** -```json -{ - "userId": "550e8400-e29b-41d4-a716-446655440001", - "packageId": "mana_100", - "credits": 100, - "price": 4.99, - "currency": "EUR" -} -``` - -**Test Steps:** -1. User navigates to subscription page -2. Select "100 Credits - €4.99" package -3. Tap "Purchase" button -4. Complete mock payment (simulated success) -5. Payment gateway sends webhook to backend - -**Mock Webhook Payload:** -```json -{ - "event": "purchase", - "transactionId": "txn_mock_12345", - "userId": "550e8400-e29b-41d4-a716-446655440001", - "productId": "mana_100", - "credits": 100, - "price": 4.99, - "currency": "EUR", - "timestamp": "2025-11-25T10:00:00Z", - "status": "completed" -} -``` - -**Expected Results:** - -**Webhook Processing:** -1. Backend receives webhook -2. Validates transaction ID (not duplicate) -3. Validates user exists -4. Updates credit balance atomically - -**Database Updates:** - -**user_profiles table:** -```sql -UPDATE user_profiles -SET credits = credits + 100 -WHERE id = '550e8400-e29b-41d4-a716-446655440001'; - --- Before: 10 credits --- After: 110 credits -``` - -**credit_transactions table:** -```sql -INSERT INTO credit_transactions ( - id, - user_id, - transaction_type, - amount, - description, - transaction_id, - status, - created_at -) VALUES ( - gen_random_uuid(), - '550e8400-e29b-41d4-a716-446655440001', - 'purchase', - 100, - 'Credit purchase: 100 credits', - 'txn_mock_12345', - 'completed', - NOW() -); -``` - -**API Response to Client:** -```json -{ - "success": true, - "newBalance": 110, - "transaction": { - "id": "uuid-transaction", - "amount": 100, - "timestamp": "2025-11-25T10:00:00Z" - } -} -``` - -**UI Updates:** -- Credit balance updates to "110 Mana" (within 1 second) -- Success notification: "100 credits added successfully!" -- Transaction visible in history - -**Post-Conditions:** -- User balance: 110 credits -- Transaction recorded -- User can use new credits - ---- - -### TC-CREDIT-CONSUME-003: Concurrent Credit Deduction - -**Priority:** P0 (Critical) -**Component:** Credit Service -**Feature:** Credit Consumption - -**Preconditions:** -- User authenticated: `test+credit003@manacore.com` -- Current balance: 100 credits -- 3 concurrent operations ready - -**Test Data:** - -**User State:** -```json -{ - "userId": "550e8400-e29b-41d4-a716-446655440003", - "currentBalance": 100, - "operations": [ - { "id": "op1", "type": "STORY_CREATE", "cost": 30 }, - { "id": "op2", "type": "STORY_CREATE", "cost": 30 }, - { "id": "op3", "type": "STORY_CREATE", "cost": 30 } - ] -} -``` - -**Test Steps:** -1. Trigger 3 story creation operations simultaneously -2. Each operation validates credits BEFORE execution -3. All 3 operations execute concurrently -4. Each operation consumes credits AFTER success -5. Verify final balance - -**Expected Results:** - -**Validation Phase (Concurrent):** - -**Operation 1:** -``` -POST /credits/validate -{ - "userId": "550e8400-e29b-41d4-a716-446655440003", - "operationType": "STORY_CREATE", - "cost": 30 -} - -Response: { "hasCredits": true, "availableCredits": 100 } -``` - -**Operation 2:** -``` -POST /credits/validate -{ - "userId": "550e8400-e29b-41d4-a716-446655440003", - "operationType": "STORY_CREATE", - "cost": 30 -} - -Response: { "hasCredits": true, "availableCredits": 100 } -``` - -**Operation 3:** -``` -POST /credits/validate -{ - "userId": "550e8400-e29b-41d4-a716-446655440003", - "operationType": "STORY_CREATE", - "cost": 30 -} - -Response: { "hasCredits": true, "availableCredits": 100 } -``` - -**Execution Phase:** -- All 3 stories generated successfully - -**Consumption Phase (Atomic, Sequential due to DB locks):** - -**Database Transaction Log:** -```sql --- Transaction 1 (Operation 1) -BEGIN; -SELECT credits, updated_at FROM user_profiles WHERE id = '...' FOR UPDATE; --- credits: 100, updated_at: t1 -UPDATE user_profiles SET credits = 70, updated_at = NOW() WHERE id = '...' AND updated_at = t1; -COMMIT; - --- Transaction 2 (Operation 2) -BEGIN; -SELECT credits, updated_at FROM user_profiles WHERE id = '...' FOR UPDATE; --- credits: 70, updated_at: t2 -UPDATE user_profiles SET credits = 40, updated_at = NOW() WHERE id = '...' AND updated_at = t2; -COMMIT; - --- Transaction 3 (Operation 3) -BEGIN; -SELECT credits, updated_at FROM user_profiles WHERE id = '...' FOR UPDATE; --- credits: 40, updated_at: t3 -UPDATE user_profiles SET credits = 10, updated_at = NOW() WHERE id = '...' AND updated_at = t3; -COMMIT; -``` - -**Final State:** -```json -{ - "userId": "550e8400-e29b-41d4-a716-446655440003", - "finalBalance": 10, - "transactionsCreated": 3, - "totalDeducted": 90 -} -``` - -**UI Validation:** -- Credit balance updates to "10 Mana" -- All 3 stories visible in user's library -- Transaction history shows 3 separate deductions - -**Critical Validations:** -- βœ… No over-deduction (balance not negative) -- βœ… No under-deduction (all 90 credits deducted) -- βœ… Database consistency maintained -- βœ… All operations succeeded - -**Post-Conditions:** -- User balance: 10 credits -- 3 transactions recorded -- 3 stories created - ---- - -### TC-CREDIT-CONSUME-004: Insufficient Balance During Concurrent Operations - -**Priority:** P0 (Critical) -**Component:** Credit Service -**Feature:** Credit Consumption Edge Case - -**Preconditions:** -- User authenticated: `test+credit004@manacore.com` -- Current balance: 10 credits (LOW BALANCE) -- 2 concurrent operations ready - -**Test Data:** -```json -{ - "userId": "550e8400-e29b-41d4-a716-446655440004", - "currentBalance": 10, - "operations": [ - { "id": "op1", "type": "STORY_CREATE", "cost": 8 }, - { "id": "op2", "type": "STORY_CREATE", "cost": 8 } - ] -} -``` - -**Test Steps:** -1. Trigger 2 story creation operations simultaneously (8 credits each) -2. Both operations validate credits (both should pass with 10 credits available) -3. Both operations execute concurrently -4. First operation consumes 8 credits (balance β†’ 2) -5. Second operation attempts to consume 8 credits (insufficient) -6. Verify error handling - -**Expected Results:** - -**Validation Phase (Both Pass):** -``` -Operation 1: POST /credits/validate β†’ { "hasCredits": true, "availableCredits": 10 } -Operation 2: POST /credits/validate β†’ { "hasCredits": true, "availableCredits": 10 } -``` - -**Execution Phase:** -- Both stories generated successfully (AI service completes) - -**Consumption Phase:** - -**Operation 1 (Succeeds):** -```sql -BEGIN; -UPDATE user_profiles SET credits = 2 WHERE id = '...' AND credits >= 8; --- 1 row affected -INSERT INTO credit_transactions (...) VALUES (...); -COMMIT; -``` - -**Operation 2 (Fails):** -```sql -BEGIN; -UPDATE user_profiles SET credits = credits - 8 WHERE id = '...' AND credits >= 8; --- 0 rows affected (balance only 2, not enough) -ROLLBACK; -``` - -**API Response for Operation 2 (400 Bad Request):** -```json -{ - "error": "insufficient_credits", - "message": "Insufficient mana. Required: 8, Available: 2", - "requiredCredits": 8, - "availableCredits": 2 -} -``` - -**UI Behavior:** -- Operation 1: Success notification, story saved -- Operation 2: Insufficient credits modal shown - - "You need 8 Mana but only have 2 Mana" - - "Get More Mana" button - - Cancel button - -**Final State:** -```json -{ - "userId": "550e8400-e29b-41d4-a716-446655440004", - "finalBalance": 2, - "successfulOperations": 1, - "failedOperations": 1 -} -``` - -**Critical Validations:** -- βœ… First operation succeeded and charged -- βœ… Second operation failed with clear error -- βœ… No negative balance -- βœ… User notified of failure -- βœ… Story from failed operation NOT saved - -**Post-Conditions:** -- User balance: 2 credits -- 1 transaction recorded (successful operation) -- 1 story created (successful operation) -- User sees insufficient credits modal - ---- - -## Integration Test Cases - -### TC-INT-CROSS-002: Multi-App Credit Consumption - -**Priority:** P0 (Critical) -**Component:** Credit Service, Multi-App Integration -**Feature:** Cross-App Credit Synchronization - -**Preconditions:** -- User authenticated in both Memoro and Maerchenzauber -- User: `test+integration002@manacore.com` -- Initial balance: 100 credits - -**Test Data:** -```json -{ - "userId": "550e8400-e29b-41d4-a716-446655440005", - "initialBalance": 100, - "memoroOperation": { - "type": "TRANSCRIPTION", - "cost": 30, - "duration": 15 - }, - "maerchenzauberOperation": { - "type": "STORY_CREATE", - "cost": 20 - } -} -``` - -**Test Steps:** -1. Open Memoro app -2. Check credit balance β†’ 100 Mana -3. Record 15-minute audio memo -4. Process transcription (costs 30 credits) -5. Wait for balance update -6. **Immediately** switch to Maerchenzauber app -7. Check credit balance in Maerchenzauber -8. Create story (costs 20 credits) -9. Wait for balance update -10. Switch back to Memoro app -11. Check final balance - -**Expected Results:** - -**Step 1-2 (Memoro - Initial):** -``` -UI: "100 Mana" displayed -``` - -**Step 3-4 (Memoro - Transcription):** -``` -API: POST /memoro/transcribe -Response: { "success": true, "creditsUsed": 30 } - -Database: -UPDATE user_profiles SET credits = 70 WHERE id = '...'; - -UI Update (< 1 second): "70 Mana" displayed -``` - -**Step 6-7 (Maerchenzauber - Balance Check):** -``` -API: GET /auth/credits -Response: { "credits": 70, "userId": "..." } - -UI: "70 Mana" displayed (synced from Memoro) - -Validation: Balance consistent across apps within 1 second -``` - -**Step 8-9 (Maerchenzauber - Story Creation):** -``` -API: POST /story/create -Response: { "success": true, "creditsUsed": 20 } - -Database: -UPDATE user_profiles SET credits = 50 WHERE id = '...'; - -UI Update (< 1 second): "50 Mana" displayed -``` - -**Step 10-11 (Memoro - Final Balance):** -``` -API: GET /auth/credits -Response: { "credits": 50, "userId": "..." } - -UI: "50 Mana" displayed (synced from Maerchenzauber) - -Validation: Balance consistent across apps -``` - -**Timeline Validation:** -``` -T+0s: Memoro balance: 100 -T+2s: Transcription complete, Memoro balance: 70 -T+3s: Switch to Maerchenzauber, balance: 70 βœ“ -T+5s: Story created, Maerchenzauber balance: 50 -T+6s: Switch to Memoro, balance: 50 βœ“ -``` - -**Database Transaction Log:** -```sql --- Transaction 1 (Memoro) -INSERT INTO credit_transactions (user_id, app_id, type, amount, description) -VALUES ('...', 'memoro', 'consumption', -30, 'Transcription: 15 min audio'); - --- Transaction 2 (Maerchenzauber) -INSERT INTO credit_transactions (user_id, app_id, type, amount, description) -VALUES ('...', 'maerchenzauber', 'consumption', -20, 'Story creation'); -``` - -**Critical Validations:** -- βœ… Balance synced across apps within 1 second -- βœ… No lost credits (100 - 30 - 20 = 50) -- βœ… Both operations succeeded -- βœ… Transactions logged with correct app_id - -**Post-Conditions:** -- User balance: 50 credits (consistent in both apps) -- 2 transactions recorded -- 1 transcribed memo (Memoro) -- 1 story created (Maerchenzauber) - ---- - -## Performance Test Case - -### TC-PERF-LOAD-002: Token Refresh Under Load - -**Priority:** P1 (High) -**Component:** Token Manager, Auth Service -**Feature:** Concurrent Token Refresh - -**Test Configuration:** -```javascript -{ - virtualUsers: 500, - duration: '2m', - scenario: 'all_tokens_expired_simultaneously' -} -``` - -**Test Data:** -```javascript -// 500 virtual users with expired tokens -const users = Array.from({ length: 500 }, (_, i) => ({ - userId: `load-test-user-${i}`, - appToken: generateExpiredToken(), - refreshToken: generateValidToken(), - deviceId: `device-${i}` -})); -``` - -**Test Script (k6):** -```javascript -import http from 'k6/http'; -import { check, sleep } from 'k6'; - -export const options = { - vus: 500, - duration: '2m', - thresholds: { - http_req_duration: ['p(95)<2000', 'p(99)<5000'], - http_req_failed: ['rate<0.01'], - }, -}; - -export default function () { - const refreshToken = __ENV.REFRESH_TOKEN; - - // Simulate API call with expired token - const apiRes = http.get('https://api.manacore.com/api/memos', { - headers: { Authorization: `Bearer ${expiredToken}` } - }); - - check(apiRes, { - 'status is 401': (r) => r.status === 401, - }); - - // Automatic refresh triggered - const refreshRes = http.post('https://api.manacore.com/auth/refresh', - JSON.stringify({ refreshToken }), - { headers: { 'Content-Type': 'application/json' } } - ); - - check(refreshRes, { - 'refresh status is 200': (r) => r.status === 200, - 'new tokens received': (r) => r.json('appToken') !== null, - 'refresh time < 2s': (r) => r.timings.duration < 2000, - }); - - sleep(1); -} -``` - -**Expected Results:** - -**Performance Metrics:** -``` -Scenarios: (100.00%) 1 scenario, 500 max VUs, 2m30s max duration - βœ“ refresh status is 200............: 100.00% βœ“ 60000 βœ— 0 - βœ“ new tokens received...............: 100.00% βœ“ 60000 βœ— 0 - βœ“ refresh time < 2s.................: 99.95% βœ“ 59970 βœ— 30 - - http_req_duration...................: avg=850ms min=200ms med=750ms max=4.2s p(95)=1.8s p(99)=2.9s - http_req_failed.....................: 0.01% βœ“ 6 βœ— 59994 - http_reqs...........................: 60000 500/s - vus.................................: 500 min=500 max=500 - vus_max.............................: 500 min=500 max=500 -``` - -**Success Criteria:** -- βœ… P95 response time < 2 seconds -- βœ… P99 response time < 5 seconds -- βœ… Error rate < 1% -- βœ… All 500 users successfully refreshed -- βœ… Server CPU < 80% -- βœ… Server memory stable (no leaks) - -**Server Resource Monitoring:** -``` -CPU Usage: 65% average, 78% peak -Memory Usage: 4.2 GB (stable) -Database Connections: 45/100 (under limit) -Response Time: 850ms average -``` - -**Post-Conditions:** -- All 500 users have valid tokens -- No service degradation -- No errors or crashes - ---- - -## Security Test Case - -### TC-SEC-CREDIT-001: Credit Balance Tampering Attempt - -**Priority:** P0 (Critical) -**Component:** Credit Service -**Feature:** Security - -**Preconditions:** -- User authenticated: `test+security001@manacore.com` -- Current balance: 10 credits -- Attacker has access to user's device/browser - -**Test Data:** -```json -{ - "userId": "550e8400-e29b-41d4-a716-446655440006", - "currentBalance": 10, - "attemptedBalance": 10000 -} -``` - -**Attack Scenarios:** - -**Attack 1: Modify JWT Claims** -```javascript -// Attacker obtains JWT token -const token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."; - -// Decode token -const payload = { - "sub": "550e8400-e29b-41d4-a716-446655440006", - "credits": 10, // Original - "role": "authenticated" -}; - -// Attacker modifies credits -payload.credits = 10000; - -// Attacker re-encodes token (without proper signature) -const tamperedToken = encodeJWT(payload, "wrong-secret"); - -// Attacker sends API request with tampered token -fetch('/api/memos', { - headers: { Authorization: `Bearer ${tamperedToken}` } -}); -``` - -**Expected Defense:** -``` -API Response: 401 Unauthorized -{ - "error": "Invalid token signature" -} - -Server Log: -[AUTH] Token signature verification failed for user attempt -[SECURITY] Potential token tampering detected -``` - -**Attack 2: Modify Local Storage** -```javascript -// Web app - attacker opens browser console -localStorage.setItem('creditBalance', '10000'); -location.reload(); -``` - -**Expected Defense:** -``` -// On app load -const localBalance = localStorage.getItem('creditBalance'); // "10000" -const serverBalance = await fetchCredits(); // API call: 10 - -// App uses server-authoritative balance -UI displays: "10 Mana" (server value) -localStorage.setItem('creditBalance', '10'); // Overwritten -``` - -**Attack 3: Direct API Manipulation** -```javascript -// Attacker crafts malicious API request -fetch('/credits/add', { - method: 'POST', - headers: { - 'Authorization': 'Bearer ' + validToken, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - userId: "550e8400-e29b-41d4-a716-446655440006", - amount: 10000 - }) -}); -``` - -**Expected Defense:** -``` -API Response: 403 Forbidden -{ - "error": "Unauthorized endpoint" -} - -Server Log: -[SECURITY] Attempt to access admin-only endpoint: /credits/add -[SECURITY] User: 550e8400-e29b-41d4-a716-446655440006 -[SECURITY] IP: 192.168.1.100 -``` - -**Attack 4: SQL Injection** -```javascript -// Attacker tries SQL injection in credit consumption -fetch('/credits/consume', { - method: 'POST', - body: JSON.stringify({ - userId: "'; UPDATE user_profiles SET credits = 10000; --", - amount: 10 - }) -}); -``` - -**Expected Defense:** -``` -// Parameterized query prevents injection -const query = ` - UPDATE user_profiles - SET credits = credits - $1 - WHERE id = $2 -`; -db.query(query, [amount, userId]); - -API Response: 400 Bad Request -{ - "error": "Invalid user ID format" -} -``` - -**Final Validation:** -```sql --- Verify balance unchanged -SELECT credits FROM user_profiles -WHERE id = '550e8400-e29b-41d4-a716-446655440006'; - --- Expected: 10 (unchanged) -``` - -**Critical Validations:** -- βœ… JWT signature verification prevents token tampering -- βœ… Server-authoritative balance (client can't override) -- βœ… Admin endpoints protected (role-based access control) -- βœ… SQL injection prevented (parameterized queries) -- βœ… All attacks logged for security monitoring - -**Post-Conditions:** -- User balance: 10 credits (unchanged) -- Attack attempts logged -- Security team notified (if threshold exceeded) - ---- - -## Test Data Repository - -### Test User Accounts - -```yaml -test_users: - - email: test+reg001@manacore.com - password: SecureP@ss123 - credits: 0 - purpose: Registration testing - - - email: test+login002@manacore.com - password: CorrectP@ss123 - credits: 50 - purpose: Login testing - - - email: test+credit001@manacore.com - password: Test123!@# - credits: 10 - purpose: Credit purchase testing - - - email: test+credit003@manacore.com - password: Test123!@# - credits: 100 - purpose: Concurrent deduction testing - - - email: test+credit004@manacore.com - password: Test123!@# - credits: 10 - purpose: Insufficient balance testing - - - email: test+integration002@manacore.com - password: Test123!@# - credits: 100 - purpose: Multi-app integration testing - - - email: test+security001@manacore.com - password: Test123!@# - credits: 10 - purpose: Security testing - - - email: test+b2b@manacore.com - password: Test123!@# - credits: 10000 - b2b: true - purpose: B2B account testing -``` - -### Mock Webhook Payloads - -```json -{ - "purchase_success": { - "event": "purchase", - "transactionId": "txn_mock_12345", - "userId": "550e8400-e29b-41d4-a716-446655440001", - "productId": "mana_100", - "credits": 100, - "price": 4.99, - "currency": "EUR", - "timestamp": "2025-11-25T10:00:00Z", - "status": "completed" - }, - - "purchase_failed": { - "event": "purchase_failed", - "transactionId": "txn_mock_67890", - "userId": "550e8400-e29b-41d4-a716-446655440001", - "productId": "mana_100", - "error": "payment_declined", - "timestamp": "2025-11-25T10:05:00Z" - }, - - "purchase_duplicate": { - "event": "purchase", - "transactionId": "txn_mock_12345", - "userId": "550e8400-e29b-41d4-a716-446655440001", - "productId": "mana_100", - "credits": 100, - "price": 4.99, - "currency": "EUR", - "timestamp": "2025-11-25T10:00:00Z", - "status": "completed" - } -} -``` - ---- - -**END OF SAMPLE TEST CASES** - -*For full test strategy, see `/TESTING_STRATEGY_AUTH_CREDITS.md`* diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index f0dadf330..2cb07ef7f 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -415,740 +415,6 @@ docker run --rm --entrypoint cat test /app/dist/ai/ai.service.js --- -## Staging Deployment Issues - -### Overview - -This section documents the complete troubleshooting journey for deploying mana-core-auth + chat (backend + web) to staging. It covers GitHub Actions CI/CD simplification, Docker health checks, database setup, and SvelteKit environment variables. - -### Problem 1: GitHub Running Disabled Workflows - -**Symptoms:** - -- Workflows with `.full.yml` extension were still running -- `test.full.yml` was being recognized as a valid workflow -- Multiple unnecessary workflows running on every push - -**What We Tried:** - -1. ❌ Renaming to `.disabled` extension β†’ Still ran -2. ❌ Renaming to `.full.yml` extension β†’ Still ran (GitHub recognizes any `.yml` in `.github/workflows/`) - -**Solution:** - -- βœ… Rename to `.yml.bak` extension (GitHub ignores non-`.yml` files) - -```bash -# Disable a workflow -mv .github/workflows/test.yml .github/workflows/test.yml.bak - -# Re-enable a workflow -mv .github/workflows/test.yml.bak .github/workflows/test.yml -``` - -**Files Changed:** - -- `test.yml` β†’ `test.yml.bak` -- `test-coverage.yml` β†’ `test-coverage.yml.bak` -- `ci-pull-request.yml` β†’ `ci-pull-request.yml.bak` -- `dependency-update.yml` β†’ `dependency-update.yml.bak` - ---- - -### Problem 2: chat-backend Container Unhealthy - -**Symptoms:** - -- Deployment failed with: `dependency failed to start: container chat-backend-staging is unhealthy` -- chat-web wouldn't start because it depends on chat-backend being healthy - -**Debugging Steps:** - -```bash -# Connect to staging server -ssh -i ~/.ssh/deploy_key deploy@your-server-ip - -# Check container status -cd ~/manacore-staging -docker compose ps - -# Check logs for the failing container -docker compose logs chat-backend --tail=100 - -# Test health endpoint manually from inside container -docker compose exec chat-backend wget -q -O - http://localhost:3002/api/v1/health -``` - -**Root Cause 1: Missing Database** - -The logs showed: - -``` -error: database "chat" does not exist -``` - -**Fix:** Create the database manually: - -```bash -docker compose exec -T postgres psql -U postgres -c "CREATE DATABASE chat;" -``` - -**Root Cause 2: Wrong Health Check Path** - -The `docker-compose.staging.yml` had: - -```yaml -healthcheck: - test: ['CMD', 'wget', '...', 'http://localhost:3002/api/health'] # ❌ WRONG -``` - -But NestJS health endpoint is at `/api/v1/health`: - -```yaml -healthcheck: - test: ['CMD', 'wget', '...', 'http://localhost:3002/api/v1/health'] # βœ… CORRECT -``` - -**How to Verify Health Endpoints:** - -| Service | Port | Health Endpoint | -| -------------- | ---- | ---------------- | -| mana-core-auth | 3001 | `/api/v1/health` | -| chat-backend | 3002 | `/api/v1/health` | -| chat-web | 3000 | `/health` | - -```bash -# Test from outside the server -curl http://your-server-ip:3001/api/v1/health -curl http://your-server-ip:3002/api/v1/health -curl http://your-server-ip:3000/health -``` - ---- - -### Problem 3: SvelteKit Static Environment Variable Imports - -**Symptoms:** - -- Docker build failed with: `PUBLIC_MANA_CORE_AUTH_URL is not exported by $env/static/public` -- Build error during `npm run build` in Docker - -**Root Cause:** - -SvelteKit's `$env/static/public` imports are resolved at **build time**, not runtime. When building in Docker, these environment variables don't exist. - -**❌ WRONG - Static Import (Build Time):** - -```typescript -// apps/chat/apps/web/src/lib/stores/auth.svelte.ts -import { PUBLIC_MANA_CORE_AUTH_URL } from '$env/static/public'; // ❌ Fails in Docker - -const authUrl = PUBLIC_MANA_CORE_AUTH_URL; -``` - -**βœ… CORRECT - Runtime Environment Variable:** - -```typescript -// apps/chat/apps/web/src/lib/stores/auth.svelte.ts -import { browser } from '$app/environment'; - -function getAuthUrl(): string { - if (browser && typeof window !== 'undefined') { - // Client-side: check for injected env or use default - return ( - (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) - .__PUBLIC_MANA_CORE_AUTH_URL__ || - import.meta.env.PUBLIC_MANA_CORE_AUTH_URL || - 'http://localhost:3001' - ); - } - // Server-side: use process.env or default - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; -} -``` - -**The Pattern:** - -1. Check if running in browser -2. Try window-injected variable (for runtime injection) -3. Try `import.meta.env` (for Vite build-time) -4. Fall back to `process.env` (for SSR) -5. Use localhost default for development - -**Files Fixed:** - -- `apps/chat/apps/web/src/lib/stores/auth.svelte.ts` -- `apps/chat/apps/web/src/lib/services/feedback.ts` - ---- - -### Problem 4: Orphan Docker Containers - -**Symptoms:** - -- Old containers from previous deployments still running -- `docker compose ps` shows unexpected services - -**Fix:** - -```bash -# Remove orphan containers -docker compose down --remove-orphans - -# Bring up fresh -docker compose up -d - -# Manually remove specific orphans -docker rm -f manadeck-backend-staging manacore-nginx-staging -``` - ---- - -### Problem 5: Client-Side Calling localhost Instead of Public IP - -**Symptoms:** - -- Browser console shows: `POST http://localhost:3001/api/v1/auth/register net::ERR_CONNECTION_REFUSED` -- API calls work from server but fail from browser -- The injected `window.__PUBLIC_MANA_CORE_AUTH_URL__` is empty or undefined - -**Root Cause:** - -SvelteKit's environment variables work differently on server vs client: - -- **Server-side (SSR):** Has access to `process.env` -- **Client-side (browser):** Does NOT have access to `process.env` - needs explicit injection - -The initial fix using `process.env` only worked for SSR. Browser code falls back to `localhost`. - -**Solution - Runtime Environment Injection:** - -1. **Add client URLs to docker-compose.staging.yml:** - -```yaml -chat-web: - environment: - # Server-side URLs (Docker internal network) - PUBLIC_BACKEND_URL: http://chat-backend:3002 - PUBLIC_MANA_CORE_AUTH_URL: http://mana-core-auth:3001 - # Client-side URLs (browser access via public IP) - PUBLIC_BACKEND_URL_CLIENT: http://your-server-ip:3002 - PUBLIC_MANA_CORE_AUTH_URL_CLIENT: http://your-server-ip:3001 -``` - -2. **Inject into HTML via hooks.server.ts:** - -```typescript -// apps/chat/apps/web/src/hooks.server.ts -import type { Handle } from '@sveltejs/kit'; - -const PUBLIC_MANA_CORE_AUTH_URL_CLIENT = - process.env.PUBLIC_MANA_CORE_AUTH_URL_CLIENT || process.env.PUBLIC_MANA_CORE_AUTH_URL || ''; - -export const handle: Handle = async ({ event, resolve }) => { - return resolve(event, { - transformPageChunk: ({ html }) => { - const envScript = ``; - return html.replace('', `${envScript}`); - }, - }); -}; -``` - -3. **Read from window in client code:** - -```typescript -// apps/chat/apps/web/src/lib/stores/auth.svelte.ts -function getAuthUrl(): string { - if (browser && typeof window !== 'undefined') { - const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) - .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; - } - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; -} -``` - -**How to Verify:** - -Open browser DevTools (F12) β†’ Console: - -```javascript -window.__PUBLIC_MANA_CORE_AUTH_URL__; -// Should show: "http://your-server-ip:3001" -``` - ---- - -### Problem 6: CORS Blocking Cross-Origin Requests - -**Symptoms:** - -- Browser console shows: `Access to fetch at 'http://your-server-ip:3001/...' from origin 'http://your-server-ip:3000' has been blocked by CORS policy` -- API calls work via curl but fail from browser -- Preflight OPTIONS requests fail - -**Root Cause:** - -Browser security blocks requests between different origins (port counts as different origin): - -- chat-web: `http://your-server-ip:3000` -- mana-core-auth: `http://your-server-ip:3001` - -Even though they're on the same IP, different ports = different origins = CORS blocked. - -**Solution:** - -Add `CORS_ORIGINS` environment variable to mana-core-auth in docker-compose.staging.yml: - -```yaml -mana-core-auth: - environment: - # ... other env vars ... - # CORS - Allow chat-web and other staging origins - CORS_ORIGINS: http://your-server-ip:3000,http://your-server-ip:3002,http://localhost:3000 -``` - -**CORS Configuration in mana-core-auth:** - -The service reads `CORS_ORIGINS` from environment: - -```typescript -// services/mana-core-auth/src/config/configuration.ts -cors: { - origin: process.env.CORS_ORIGINS?.split(',') || [ - 'http://localhost:3000', - 'http://localhost:8081', - ], -} - -// services/mana-core-auth/src/main.ts -const corsOrigins = configService.get('cors.origin') || []; -app.enableCors({ - origin: corsOrigins, - credentials: true, -}); -``` - -**How to Verify:** - -```bash -# Test CORS preflight -curl -X OPTIONS http://your-server-ip:3001/api/v1/auth/register \ - -H "Origin: http://your-server-ip:3000" \ - -H "Access-Control-Request-Method: POST" \ - -v - -# Should see in response headers: -# Access-Control-Allow-Origin: http://your-server-ip:3000 -``` - ---- - -### Problem 7: Missing Database Schema - -**Symptoms:** - -- API returns: `{"statusCode": 500, "message": "relation \"auth.users\" does not exist"}` -- Registration/login endpoints fail with 500 error -- Health check passes but auth endpoints fail - -**Root Cause:** - -The database exists but the schema hasn't been pushed. Drizzle ORM needs to run `db:push` to create: - -- `auth` schema with tables: users, accounts, sessions, passwords, verification, etc. -- `credits` schema with tables: balances, transactions, packages, etc. - -**Why It Happened:** - -The CD workflow was calling `pnpm run db:migrate` but that script doesn't exist in the package.json. The correct script is `db:push` which runs `drizzle-kit push`. - -**Solution:** - -1. **Manual fix (immediate):** - -```bash -ssh -i ~/.ssh/deploy_key deploy@your-server-ip -cd ~/manacore-staging - -# Push schema to database (--force skips interactive confirmation) -docker compose exec -T mana-core-auth npx drizzle-kit push --force -``` - -2. **Fix CD workflow (permanent):** - -```yaml -# .github/workflows/cd-staging.yml - BEFORE -docker compose exec -T mana-core-auth pnpm run db:migrate || echo "Auth migrations skipped" - -# .github/workflows/cd-staging.yml - AFTER -docker compose exec -T mana-core-auth npx drizzle-kit push --force || echo "Auth schema push skipped" -``` - -**How to Verify:** - -```bash -# Check if auth schema exists -docker compose exec -T postgres psql -U postgres -d manacore_auth -c '\dt auth.*' - -# Should show 12 tables: -# auth | accounts, invitations, jwks, members, organizations, -# passwords, security_events, sessions, two_factor_auth, -# user_settings, users, verification -``` - -**Files Changed:** - -- `.github/workflows/cd-staging.yml` - Line 253: `db:migrate` β†’ `drizzle-kit push --force` - ---- - -### Complete Staging Deployment Checklist - -#### Before Deployment - -- [ ] Verify `docker-compose.staging.yml` has correct health check paths -- [ ] Verify CI/CD workflow (`cd-staging.yml`) has matching health check paths -- [ ] Check that required databases exist or CI creates them -- [ ] Verify CD workflow runs `drizzle-kit push --force` to create schemas (not `db:migrate`) -- [ ] Verify `CORS_ORIGINS` includes all frontend origins -- [ ] Verify `PUBLIC_*_CLIENT` env vars have correct public IPs for browser access - -#### During Deployment Failure - -1. **SSH to server:** - - ```bash - ssh -i ~/.ssh/deploy_key deploy@your-server-ip - cd ~/manacore-staging - ``` - -2. **Check container status:** - - ```bash - docker compose ps - ``` - -3. **Check logs for failing container:** - - ```bash - docker compose logs --tail=100 - ``` - -4. **Common fixes:** - - ```bash - # Create missing database - docker compose exec -T postgres psql -U postgres -c "CREATE DATABASE ;" - - # Restart a service - docker compose restart - - # Force recreate - docker compose up -d --force-recreate - ``` - -5. **Verify health:** - ```bash - curl http://localhost:3001/api/v1/health # mana-core-auth - curl http://localhost:3002/api/v1/health # chat-backend - curl http://localhost:3000/health # chat-web - ``` - -#### After Deployment - -- [ ] Verify all health endpoints respond -- [ ] Check container logs for errors -- [ ] Test actual functionality (login, API calls) - ---- - -### Key Files for Staging Deployment - -| File | Purpose | -| ---------------------------------- | ------------------------------------- | -| `docker-compose.staging.yml` | Service definitions and health checks | -| `.github/workflows/cd-staging.yml` | CI/CD deployment workflow | -| `.github/workflows/ci-main.yml` | Docker image builds on push to main | - -### Health Check Patterns - -**Docker Compose (`docker-compose.staging.yml`):** - -```yaml -healthcheck: - test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://localhost:PORT/ENDPOINT'] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s -``` - -**CI/CD Workflow (`cd-staging.yml`):** - -```bash -# Check from inside container -docker compose exec -T chat-backend wget -q -O - http://localhost:3002/api/v1/health -``` - -### Lessons Learned - -1. **GitHub Workflows:** Only files ending in `.yml` or `.yaml` in `.github/workflows/` are recognized. Use `.bak` extension to disable. - -2. **NestJS Health Endpoints:** All NestJS backends use `/api/v1/health`, not `/api/health`. - -3. **Docker Compose Dependencies:** When using `depends_on: condition: service_healthy`, the dependent service won't start until the health check passes. - -4. **Database Creation:** Must happen AFTER PostgreSQL is healthy but BEFORE dependent services run migrations. - -5. **SvelteKit Environment Variables:** Use runtime patterns (`process.env`, `import.meta.env`) instead of `$env/static/public` for Docker builds. - -6. **Verify Before Commit:** Always check both `docker-compose.staging.yml` AND CI/CD workflows for matching paths. - -7. **Server vs Client URLs:** Docker internal URLs (e.g., `http://mana-core-auth:3001`) only work server-side. Browsers need public IPs. Use separate `_CLIENT` env vars for browser access. - -8. **SvelteKit Runtime Injection:** Use `hooks.server.ts` with `transformPageChunk` to inject environment variables into HTML at runtime. This is the only reliable way to pass server env vars to client code. - -9. **CORS for Multi-Service Apps:** When frontend and backend are on different ports, configure CORS on the backend. Port differences count as different origins (e.g., `:3000` vs `:3001`). - -10. **Environment Variable Flow:** - - ``` - docker-compose.yml β†’ Container env β†’ process.env (SSR) β†’ hooks.server.ts β†’ window.__VAR__ (browser) - ``` - -11. **Database Schema vs Database:** Creating a database (`CREATE DATABASE`) is not enough - Drizzle needs `db:push` to create schemas and tables. Health checks may pass with empty database, but API calls will fail with "relation does not exist". - -12. **Drizzle Kit Interactive Mode:** `drizzle-kit push` prompts for confirmation. Use `--force` flag in CI/CD to skip interactive mode. - -13. **pnpm Symlinks in Docker:** pnpm uses symlinks to a central `.pnpm` store. When copying `node_modules` in Docker, you must preserve both the symlinks AND the target directory they point to. See [Problem 8](#problem-8-pnpm-symlinks-broken-in-docker-container). - ---- - -### Problem 8: pnpm Symlinks Broken in Docker Container - -**Symptoms:** - -- Container starts but crashes with: `Cannot find package 'date-fns' imported from /app/build/server/chunks/_page.svelte-xxx.js` -- Error `ERR_MODULE_NOT_FOUND` for packages that ARE in node_modules -- Works locally but fails in Docker production stage -- `ls node_modules/date-fns` shows a symlink pointing to `../../../../../node_modules/.pnpm/...` - -**Root Cause:** - -pnpm uses symlinks to a central `.pnpm` store at the monorepo root. When you copy only the app's `node_modules` in Docker, the symlinks point to paths that don't exist: - -``` -# In builder stage (pnpm workspace): -/app/apps/todo/apps/web/node_modules/date-fns β†’ ../../../../../node_modules/.pnpm/date-fns@4.1.0/node_modules/date-fns - -# In production stage (old broken approach): -/app/node_modules/date-fns β†’ ../../../../../node_modules/.pnpm/... -# ↑ BROKEN! This path doesn't exist because we only copied to /app/ -``` - -**❌ WRONG - Flattening Directory Structure:** - -```dockerfile -# Production stage -FROM node:20-alpine AS production - -WORKDIR /app # ❌ Different from builder structure - -# Copy node_modules (symlinks will be broken!) -COPY --from=builder /app/apps/todo/apps/web/node_modules ./node_modules # ❌ BROKEN -COPY --from=builder /app/apps/todo/apps/web/build ./build -COPY --from=builder /app/apps/todo/apps/web/package.json ./ - -CMD ["node", "build"] -``` - -The symlinks in `node_modules` point to `../../../../../node_modules/.pnpm/...` which resolves to a non-existent path from `/app/`. - -**βœ… CORRECT - Preserve Directory Structure + Copy .pnpm Store:** - -```dockerfile -# Production stage -FROM node:20-alpine AS production - -# Keep same directory structure as builder so pnpm symlinks resolve correctly -WORKDIR /app/apps/todo/apps/web # βœ… Same as builder - -# Copy the pnpm store that symlinks point to (at /app/node_modules/.pnpm) -COPY --from=builder /app/node_modules/.pnpm /app/node_modules/.pnpm # βœ… Target of symlinks - -# Copy the app's node_modules (contains symlinks to the pnpm store) -COPY --from=builder /app/apps/todo/apps/web/node_modules ./node_modules # βœ… Symlinks work now - -# Copy built application -COPY --from=builder /app/apps/todo/apps/web/build ./build -COPY --from=builder /app/apps/todo/apps/web/package.json ./ - -CMD ["node", "build"] -``` - -**Why This Works:** - -1. `WORKDIR /app/apps/todo/apps/web` - Production container has same path as builder -2. Symlinks in `./node_modules/` point to `../../../../../node_modules/.pnpm/...` -3. From `/app/apps/todo/apps/web/node_modules/`, going up 5 directories reaches `/app/` -4. `/app/node_modules/.pnpm/` exists because we copied it! - -**How to Debug:** - -```bash -# Check if symlinks are broken in the container -docker exec ls -la node_modules/date-fns -# Shows: date-fns -> ../../../../../node_modules/.pnpm/date-fns@4.1.0/node_modules/date-fns - -# Check if the target exists -docker exec ls -la /app/node_modules/.pnpm/date-fns@4.1.0/ -# If "No such file or directory" β†’ symlink is broken - -# Check the image size (should be ~1GB with .pnpm store, ~50MB without) -docker images | grep todo-web -``` - -**Trade-offs:** - -| Approach | Image Size | Symlinks | Works | -| ------------------------------------- | ---------- | -------- | ----- | -| Copy only app's node_modules | ~50MB | Broken | ❌ | -| Copy app's node_modules + .pnpm store | ~1GB | Working | βœ… | - -The larger image size is the cost of pnpm's deduplication strategy. In a monorepo, this is actually more efficient than copying all dependencies flat. - -**Alternative: Use npm Instead of pnpm in Docker:** - -If image size is critical, you could use npm in the Docker build: - -```dockerfile -# Alternative approach (not recommended for monorepos) -FROM node:20-alpine AS production -WORKDIR /app -COPY --from=builder /app/apps/todo/apps/web/build ./build -COPY --from=builder /app/apps/todo/apps/web/package.json ./ - -# Clean install with npm (flattens dependencies) -RUN npm install --omit=dev - -CMD ["node", "build"] -``` - -⚠️ **Warning:** This may fail with `workspace:*` protocol in package.json dependencies. Only works if all dependencies are published to npm. - -**Affected Files:** - -- `apps/todo/apps/web/Dockerfile` -- `apps/manacore/apps/web/Dockerfile` -- `apps/chat/apps/web/Dockerfile` -- `apps/calendar/apps/web/Dockerfile` -- `apps/clock/apps/web/Dockerfile` - -**Related Commits:** - -- `fd1c0ee6` - fix(docker): preserve pnpm symlink structure in web Dockerfiles - ---- - -### Problem 9: Hardcoded localhost URLs in SvelteKit Web Apps - -**Symptoms:** - -- Browser console shows: `POST http://localhost:3001/api/v1/auth/login net::ERR_CONNECTION_REFUSED` -- App works locally but auth fails on staging/production -- The `window.__PUBLIC_MANA_CORE_AUTH_URL__` may be set correctly, but code doesn't use it -- Looking at the source code reveals hardcoded URLs like `const MANA_AUTH_URL = 'http://localhost:3001'` - -**Root Cause:** - -Developers hardcode `localhost:3001` directly in TypeScript files instead of using the runtime injection pattern. This works locally but breaks in Docker deployments. - -**Common Locations of Hardcoded URLs:** - -```typescript -// ❌ These patterns are WRONG: - -// In auth.svelte.ts -const MANA_AUTH_URL = 'http://localhost:3001'; - -// In user-settings.svelte.ts -const MANA_AUTH_URL = 'http://localhost:3001'; - -// In feedback.ts or feedback page -apiUrl: 'http://localhost:3001', - -// Using build-time env vars (also wrong for Docker) -const MANA_AUTH_URL = import.meta.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; -``` - -**Solution:** - -1. **Create `hooks.server.ts`** if it doesn't exist (see Problem 5) -2. **Use `getAuthUrl()` pattern in all files:** - -```typescript -// βœ… CORRECT pattern -import { browser } from '$app/environment'; - -function getAuthUrl(): string { - if (browser && typeof window !== 'undefined') { - const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) - .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; - } - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; -} - -// Use getAuthUrl() instead of hardcoded string -const auth = initializeWebAuth({ baseUrl: getAuthUrl() }); -``` - -**How to Find Hardcoded URLs:** - -```bash -# Search for hardcoded localhost:3001 in web apps -grep -r "localhost:3001" apps/*/apps/web/src --include="*.ts" --include="*.svelte" - -# Check for the correct pattern (window injection) -grep -r "__PUBLIC_MANA_CORE_AUTH_URL__" apps/*/apps/web/src -``` - -**Apps Status (as of 2024-12):** - -| App | Status | Files to Fix | -| ------------------- | ------------ | ---------------------------------------------------------------- | -| `chat/apps/web` | βœ… Fixed | - | -| `todo/apps/web` | βœ… Fixed | - | -| `calendar/apps/web` | βœ… Fixed | - | -| `clock/apps/web` | βœ… Fixed | - | -| `contacts/apps/web` | ❌ Needs Fix | auth.svelte.ts, user-settings.svelte.ts, feedback.ts | -| `manadeck/apps/web` | ❌ Needs Fix | user-settings.svelte.ts, feedback.ts | -| `manacore/apps/web` | ❌ Needs Fix | auth.svelte.ts, user-settings.svelte.ts, feedback.ts, credits.ts | -| `zitare/apps/web` | ❌ Needs Fix | auth.svelte.ts, user-settings.svelte.ts, feedback.ts | -| `picture/apps/web` | ❌ Needs Fix | user-settings.svelte.ts | - -**Complete Fix Checklist for Each App:** - -- [ ] Create/update `src/hooks.server.ts` with env injection -- [ ] Update `src/lib/stores/auth.svelte.ts` β†’ use `getAuthUrl()` pattern -- [ ] Update `src/lib/stores/user-settings.svelte.ts` β†’ use `getAuthUrl()` pattern -- [ ] Update any `feedback.ts` or feedback services β†’ use `getAuthUrl()` pattern -- [ ] Update any other files with hardcoded URLs -- [ ] Add `PUBLIC_MANA_CORE_AUTH_URL_CLIENT` to `docker-compose.staging.yml` -- [ ] Test locally with `pnpm dev` -- [ ] Deploy and test on staging - -**See Also:** - -- [Problem 5: Client-Side Calling localhost Instead of Public IP](#problem-5-client-side-calling-localhost-instead-of-public-ip) -- [SvelteKit Web Guidelines - Environment Variables](/.claude/guidelines/sveltekit-web.md#environment-variables) - ---- - ## References - [CLAUDE.md - Turborepo Configuration](./CLAUDE.md#turborepo-configuration) diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 208691f1e..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,190 +0,0 @@ -version: '3.8' - -services: - # Traefik reverse proxy - traefik: - image: traefik:v3.0 - container_name: manacore-traefik - restart: unless-stopped - command: - - "--api.dashboard=true" - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--entrypoints.web.address=:80" - - "--entrypoints.websecure.address=:443" - - "--certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}" - - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" - - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" - # Rate limiting - - "--api.insecure=false" - ports: - - "80:80" - - "443:443" - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - traefik-letsencrypt:/letsencrypt - networks: - - manacore-network - - # PostgreSQL database - postgres: - image: postgres:16-alpine - container_name: manacore-postgres - restart: unless-stopped - environment: - POSTGRES_DB: ${POSTGRES_DB:-manacore} - POSTGRES_USER: ${POSTGRES_USER:-manacore} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_INITDB_ARGS: "--encoding=UTF8 --auth=scram-sha-256" - volumes: - - postgres-data:/var/lib/postgresql/data - - ./services/mana-core-auth/postgres/init:/docker-entrypoint-initdb.d:ro - ports: - - "5432:5432" - networks: - - manacore-network - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-manacore}"] - interval: 10s - timeout: 5s - retries: 5 - command: - - "postgres" - - "-c" - - "max_connections=200" - - "-c" - - "shared_buffers=256MB" - - "-c" - - "effective_cache_size=1GB" - - "-c" - - "password_encryption=scram-sha-256" - - # PgBouncer connection pooler - pgbouncer: - image: pgbouncer/pgbouncer:latest - container_name: manacore-pgbouncer - restart: unless-stopped - environment: - DATABASES_HOST: postgres - DATABASES_PORT: 5432 - DATABASES_USER: ${POSTGRES_USER:-manacore} - DATABASES_PASSWORD: ${POSTGRES_PASSWORD} - DATABASES_DBNAME: ${POSTGRES_DB:-manacore} - PGBOUNCER_POOL_MODE: transaction - PGBOUNCER_MAX_CLIENT_CONN: 1000 - PGBOUNCER_DEFAULT_POOL_SIZE: 25 - depends_on: - postgres: - condition: service_healthy - networks: - - manacore-network - - # Redis cache - redis: - image: redis:7-alpine - container_name: manacore-redis - restart: unless-stopped - command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 256mb --maxmemory-policy allkeys-lru - volumes: - - redis-data:/data - ports: - - "6379:6379" - networks: - - manacore-network - healthcheck: - test: ["CMD", "redis-cli", "--raw", "incr", "ping"] - interval: 10s - timeout: 5s - retries: 5 - - # Mana Core Auth Service - mana-core-auth: - build: - context: . - dockerfile: ./services/mana-core-auth/Dockerfile - container_name: manacore-auth - restart: unless-stopped - environment: - NODE_ENV: production - PORT: 3001 - DATABASE_URL: postgresql://${POSTGRES_USER:-manacore}:${POSTGRES_PASSWORD}@pgbouncer:6432/${POSTGRES_DB:-manacore} - REDIS_HOST: redis - REDIS_PORT: 6379 - REDIS_PASSWORD: ${REDIS_PASSWORD} - JWT_PUBLIC_KEY: ${JWT_PUBLIC_KEY} - JWT_PRIVATE_KEY: ${JWT_PRIVATE_KEY} - JWT_ACCESS_TOKEN_EXPIRY: ${JWT_ACCESS_TOKEN_EXPIRY:-15m} - JWT_REFRESH_TOKEN_EXPIRY: ${JWT_REFRESH_TOKEN_EXPIRY:-7d} - JWT_ISSUER: ${JWT_ISSUER:-manacore} - JWT_AUDIENCE: ${JWT_AUDIENCE:-manacore} - STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY} - STRIPE_WEBHOOK_SECRET: ${STRIPE_WEBHOOK_SECRET} - STRIPE_PUBLISHABLE_KEY: ${STRIPE_PUBLISHABLE_KEY} - CORS_ORIGINS: ${CORS_ORIGINS} - CREDITS_SIGNUP_BONUS: ${CREDITS_SIGNUP_BONUS:-150} - CREDITS_DAILY_FREE: ${CREDITS_DAILY_FREE:-5} - depends_on: - postgres: - condition: service_healthy - redis: - condition: service_healthy - networks: - - manacore-network - labels: - - "traefik.enable=true" - - "traefik.http.routers.manacore-auth.rule=Host(`${AUTH_DOMAIN}`)" - - "traefik.http.routers.manacore-auth.entrypoints=websecure" - - "traefik.http.routers.manacore-auth.tls.certresolver=letsencrypt" - - "traefik.http.services.manacore-auth.loadbalancer.server.port=3001" - # Rate limiting - - "traefik.http.middlewares.auth-ratelimit.ratelimit.average=100" - - "traefik.http.middlewares.auth-ratelimit.ratelimit.burst=50" - - "traefik.http.routers.manacore-auth.middlewares=auth-ratelimit" - - # Prometheus (metrics) - prometheus: - image: prom/prometheus:latest - container_name: manacore-prometheus - restart: unless-stopped - volumes: - - ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - - prometheus-data:/prometheus - command: - - '--config.file=/etc/prometheus/prometheus.yml' - - '--storage.tsdb.path=/prometheus' - - '--web.console.libraries=/usr/share/prometheus/console_libraries' - - '--web.console.templates=/usr/share/prometheus/consoles' - ports: - - "9090:9090" - networks: - - manacore-network - - # Grafana (dashboards) - grafana: - image: grafana/grafana:latest - container_name: manacore-grafana - restart: unless-stopped - environment: - GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD} - GF_USERS_ALLOW_SIGN_UP: false - volumes: - - grafana-data:/var/lib/grafana - - ./docker/grafana/provisioning:/etc/grafana/provisioning:ro - ports: - - "3000:3000" - depends_on: - - prometheus - networks: - - manacore-network - -networks: - manacore-network: - driver: bridge - -volumes: - postgres-data: - redis-data: - traefik-letsencrypt: - prometheus-data: - grafana-data: diff --git a/docs/CHANGELOG_2025-11-24.md b/docs/CHANGELOG_2025-11-24.md deleted file mode 100644 index db7d58cd7..000000000 --- a/docs/CHANGELOG_2025-11-24.md +++ /dev/null @@ -1,356 +0,0 @@ -# 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 - - - - ``` - -- **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 - - - - - -``` - -### Login Page Migration -```svelte - - - - - - - {#snippet logo()} - - {/snippet} - -``` - -### 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 diff --git a/docs/CONSISTENCY_REPORT.md b/docs/CONSISTENCY_REPORT.md deleted file mode 100644 index 50888ec13..000000000 --- a/docs/CONSISTENCY_REPORT.md +++ /dev/null @@ -1,316 +0,0 @@ -# Monorepo Konsistenz-Bericht - -> Erstellt: 29. Januar 2026 -> Zuletzt aktualisiert: 29. Januar 2026 - -## Übersicht - -Nach eingehender Analyse aller Web-Apps im Monorepo wurden folgende Bereiche auf Inkonsistenzen untersucht: - -| Bereich | Konsistenz | PrioritΓ€t | Status | -|---------|------------|-----------|--------| -| Dependencies & Versionen | βœ… Gut | ~~Hoch~~ | βœ… Erledigt | -| Toast System | βœ… Gut | ~~Hoch~~ | βœ… Erledigt | -| API Client Patterns | βœ… Gut | ~~Hoch~~ | βœ… Erledigt | -| i18n Implementation | βœ… Gut | ~~Mittel~~ | βœ… Erledigt | -| Auth Implementation | βœ… Gut | ~~Niedrig~~ | βœ… Dokumentiert | -| Styling & Tailwind | βœ… Sehr gut | Niedrig | - | -| Komponenten & Layouts | βœ… Gut | ~~Mittel~~ | βœ… Erledigt | - -### Erledigte Aufgaben (29.01.2026) - -1. βœ… **Tailwind auf Vite-Plugin migrieren** - Alle 4 Apps (manadeck, chat, manacore, presi) migriert -2. βœ… **SvelteKit, Svelte, TypeScript Versionen vereinheitlicht** - Alle 15 Web-Apps auf gleicher Version -3. βœ… **Toast System zentralisiert** - `@manacore/shared-ui` Toast fΓΌr 6 Apps (calendar, chat, clock, contacts, picture, storage) -4. βœ… **lucide-svelte entfernt** - shared-ui nutzt jetzt nur noch `@manacore/shared-icons` -5. βœ… **@manacore/shared-api-client Package erstellt** - 10 Apps migriert (clock, todo, contacts, storage, calendar, picture, nutriphi, planta, questions, skilltree) -6. βœ… **i18n zu 6 Apps hinzugefΓΌgt** - todo, skilltree, nutriphi, planta, questions, matrix (jeweils DE + EN) -7. βœ… **AuthGateModal zentralisiert** - `@manacore/shared-auth-ui` fΓΌr 4 Apps (chat, todo, contacts, calendar) -8. βœ… **Global Error Handler zentralisiert** - `@manacore/shared-ui` fΓΌr 7 Apps (calendar, chat, clock, contacts, matrix, picture, storage) -9. βœ… **AppLoadingSkeleton zentralisiert** - `@manacore/shared-ui` fΓΌr 3 Apps (contacts, todo, questions) - Apps mit spezifischen Layouts (calendar, clock) behalten lokale Version -10. βœ… **Auth Store Pattern dokumentiert** - `.claude/guidelines/authentication.md` erweitert mit Runtime URL Injection, getValidToken(), Best Practices - ---- - -## 1. Dependencies & Versionen βœ… - -> **Status: Erledigt (29.01.2026)** - -### DurchgefΓΌhrte Γ„nderungen - -#### Tailwind CSS -- βœ… Alle Apps nutzen jetzt `@tailwindcss/vite` (manadeck, chat, manacore, presi migriert) -- PostCSS-Konfigurationen entfernt - -#### Dependency Versionen standardisiert -- βœ… `@sveltejs/kit`: `^2.47.1` (alle 15 Web-Apps) -- βœ… `svelte`: `^5.41.0` (alle 15 Web-Apps) -- βœ… `svelte-check`: `^4.3.3` (alle 15 Web-Apps) -- βœ… `typescript`: `^5.9.3` (alle 15 Web-Apps) - -#### Verbleibende Unterschiede (akzeptabel) -- Vite v6.x vs v7.x - Kann bei nΓ€chstem Major-Update vereinheitlicht werden - ---- - -## 2. API Client Patterns βœ… - -> **Status: Erledigt (29.01.2026)** -> - βœ… `@manacore/shared-api-client` Package erstellt -> - βœ… 10 Apps migriert: clock, todo, contacts, storage, calendar, picture, nutriphi, planta, questions, skilltree -> - ⏭️ Nicht migriert (komplexe Custom-Logik): chat, manadeck, manacore, presi - -### Kritische Inkonsistenzen (vor Migration) - -#### 3 verschiedene Architektur-Patterns - -| Pattern | Apps | Beispiel | -|---------|------|----------| -| Factory Function | calendar, manacore | `createApiClient()` | -| Class-Based Singleton | clock, nutriphi, skilltree, questions, planta, todo | `new ApiClient()` | -| Functional API Objects | chat, picture, contacts, presi, storage | `conversationApi.getAll()` | - -#### 4 verschiedene Token-Handling AnsΓ€tze - -| Ansatz | Apps | Problem | -|--------|------|---------| -| `authStore.getAccessToken()` | clock, contacts, nutriphi, planta, storage | Kein Auto-Refresh | -| `authStore.getValidToken()` | picture, planta, chat | βœ… Auto-Refresh | -| `localStorage.getItem()` | presi, skilltree, questions | Sync, veraltete Tokens mΓΆglich | -| Manuelles Token-Property | todo, skilltree | Erfordert externen Setter | - -#### 5 verschiedene Error-Handling Strategien - -| Strategie | Apps | -|-----------|------| -| Result Type `{data, error}` | calendar, manacore | -| Response Wrapper | clock, storage | -| Throw-on-Error | nutriphi, contacts, skilltree, questions, planta, todo | -| Domain-specific Fallbacks | chat, picture | -| Retry mit Backoff | nur manacore | - -#### Base URL Handling - -| Methode | Apps | Status | -|---------|------|--------| -| Hardcoded localhost | clock, todo, storage | ❌ Nicht fΓΌr Produktion | -| Environment Variables | calendar, chat, picture, nutriphi | ⚠️ Build-Zeit | -| Runtime Injection (Docker) | skilltree, questions, planta | βœ… Flexibel | - -### Empfehlungen - -1. **`@manacore/shared-api-client` Package erstellen** mit: - - Standardisiertem `createApiClient(config)` Factory - - `ApiResult` Type (Go-style) - - Auto-Token-Refresh bei 401 - - Retry mit Exponential Backoff - - FormData Support - -2. **`authStore.getValidToken()`** als Standard fΓΌr alle Apps - -3. **Runtime URL Injection** (Window-Objekt) fΓΌr Docker-KompatibilitΓ€t - ---- - -## 3. i18n Implementation βœ… - -> **Status: Erledigt (29.01.2026)** -> - βœ… 6 Apps mit i18n hinzugefΓΌgt: todo, skilltree, nutriphi, planta, questions, matrix -> - ⏭️ Nicht migriert: zitare (unvollstΓ€ndiges Web-App Setup) - -### Apps MIT i18n (15) - -| App | Sprachen | localStorage Key | -|-----|----------|------------------| -| chat | DE, EN, IT, FR, ES | `chat_locale` | -| picture | DE, EN, IT, FR, ES | `picture_locale` | -| calendar | DE, EN, IT, FR, ES | `calendar_locale` | -| presi | DE, EN, IT, FR, ES | `presi_locale` | -| manadeck | DE, EN, IT, FR, ES | `manadeck_locale` | -| manacore | DE, EN, IT, FR, ES | `manacore_locale` | -| contacts | DE, EN | `contacts_locale` | -| storage | DE, EN | `storage_locale` | -| clock | DE, EN | `clock_locale` | -| todo | DE, EN | `todo_locale` | -| skilltree | DE, EN | `skilltree_locale` | -| nutriphi | DE, EN | `nutriphi_locale` | -| planta | DE, EN | `planta_locale` | -| questions | DE, EN | `questions_locale` | -| matrix | DE, EN | `matrix_locale` | - -### Apps OHNE i18n (1) - -- zitare (Web-App nicht vollstΓ€ndig eingerichtet) - -### DurchgefΓΌhrte Γ„nderungen - -- βœ… Einheitlicher localStorage Key Pattern: `{app}_locale` -- βœ… Mindestens DE + EN fΓΌr alle neuen Apps -- βœ… Konsistentes `svelte-i18n` Setup mit SSR-Support -- βœ… i18n-Loading State in +layout.svelte integriert - ---- - -## 4. Auth Implementation - -### Status: βœ… Gut (97% konsistent) - -Alle Apps nutzen **Mana Core Auth** mit `@manacore/shared-auth`. - -#### Kleine Variationen - -| Aspekt | Pattern A | Pattern B | -|--------|-----------|-----------| -| Init | `initializeWebAuth` (8 Apps) | Custom Setup (ManaDeck) | -| URL Config | Window Injection (modern) | Static Import | -| Route Guards | `(protected)/` Ordner | `(app)/` Ordner | - -### Empfehlungen - -1. **Window Injection fΓΌr URLs** als Standard dokumentieren -2. **Auth Store Pattern** in Shared Package extrahieren -3. **Server-Side Route Guards** ergΓ€nzen (aktuell nur Client-Side) - ---- - -## 5. Styling & Tailwind - -### Status: βœ… Sehr gut (97% konsistent) - -- Alle Apps nutzen `@manacore/shared-tailwind/preset` -- Einheitliches Theme-System mit CSS Variables -- Dark Mode ΓΌber `.dark` Klasse -- 4 Themes verfΓΌgbar: Lume, Nature, Stone, Ocean - -### Kleine Inkonsistenzen - -- App-spezifische Farben in `app.css` vs `tailwind.config.js` -- Manche Apps definieren Shadows fΓΌr Dark Mode doppelt -- Mixed `--theme-*` und `--color-*` Prefixe - -### Empfehlungen - -1. **App-Farben in tailwind.config.js** statt app.css -2. **Dark Mode Shadows in Shared Preset** konsolidieren - ---- - -## 6. Komponenten & Layouts - -### Duplikationen gefunden - -#### Toast System βœ… - -> **Status: Erledigt (29.01.2026)** - -- βœ… Zentrales Toast-System in `@manacore/shared-ui` -- βœ… Migrierte Apps: calendar, chat, clock, contacts, picture, storage -- API: `toastStore.success()`, `.error()`, `.warning()`, `.info()` -- `ToastContainer` Komponente mit Phosphor Icons - -#### AuthGateModal βœ… - -> **Status: Erledigt (29.01.2026)** - -- βœ… Zentrales AuthGateModal in `@manacore/shared-auth-ui` -- βœ… Migrierte Apps: chat, todo, contacts, calendar -- UnterstΓΌtzt: 'save', 'sync', 'feature', 'ai' Actions -- i18n: DE + EN eingebaut -- Optionale Migration-Info fΓΌr Session-Daten - -#### AppLoadingSkeleton βœ… - -> **Status: Erledigt (29.01.2026)** - -- βœ… Zentrales `AppLoadingSkeleton` in `@manacore/shared-ui` -- βœ… Migrierte Apps: contacts, todo, questions -- ⏭️ Behalten lokale Version (spezifische Layouts): calendar, clock -- Layout-Presets: `list`, `tasks`, `sidebar`, `centered`, `minimal` -- Slot-Support fΓΌr benutzerdefinierte Inhalte - -#### Global Error Handler βœ… - -> **Status: Erledigt (29.01.2026)** - -- βœ… Zentraler Global Error Handler in `@manacore/shared-ui` -- βœ… Migrierte Apps: calendar, chat, clock, contacts, matrix, picture, storage -- Funktion: `setupGlobalErrorHandler(options?)` -- Behandelt: Unhandled Promise Rejections, JS Errors, Offline/Online Status -- i18n: DE + EN eingebaut, erweiterbar -- Optional: `onAuthError` Callback fΓΌr Redirect - -### Empfehlungen (nach PrioritΓ€t) - -#### Hoch - -1. ~~**Toast Store & Component vereinheitlichen**~~ βœ… Erledigt -2. ~~**AuthGateModal nach shared-auth-ui**~~ βœ… Erledigt -3. ~~**Global Error Handler**~~ βœ… Erledigt - -#### Mittel - -4. **`@manacore/shared-sveltekit-layout`** Package mit Root-Layout Template -5. **FormModal Generator** fΓΌr config-driven Formulare -6. **AppLoadingSkeleton** vereinheitlichen - ---- - -## Zusammenfassung der PrioritΓ€ten - -### βœ… Erledigt - -| Aufgabe | Status | -|---------|--------| -| ~~Tailwind auf Vite-Plugin migrieren (4 Apps)~~ | βœ… Erledigt | -| ~~Toast System vereinheitlichen~~ | βœ… Erledigt | -| ~~Dependencies aktualisieren~~ | βœ… Erledigt | -| ~~lucide-svelte aus shared-ui entfernen~~ | βœ… Erledigt | -| ~~API Client Package erstellen~~ | βœ… Erledigt (10 Apps migriert) | -| ~~i18n zu 6 Apps hinzufΓΌgen~~ | βœ… Erledigt | -| ~~AuthGateModal zentralisieren~~ | βœ… Erledigt (4 Apps migriert) | -| ~~Global Error Handler extrahieren~~ | βœ… Erledigt (7 Apps migriert) | -| ~~Auth Store Pattern dokumentieren~~ | βœ… Erledigt | - -### πŸ”΄ Hohe PrioritΓ€t - -_(Keine offenen Aufgaben mit hoher PrioritΓ€t)_ - -### 🟑 Mittlere PrioritΓ€t - -_(Keine offenen Aufgaben mit mittlerer PrioritΓ€t)_ - -### 🟒 Niedrige PrioritΓ€t - -| Aufgabe | Aufwand | Impact | -|---------|---------|--------| -| ~~App-Skeletons vereinheitlichen~~ | ~~Niedrig~~ | βœ… Erledigt | -| ~~Auth Store Pattern dokumentieren~~ | ~~Niedrig~~ | βœ… Erledigt | - ---- - -## NΓ€chste Schritte - -1. ~~**API Client Package** als nΓ€chstes angehen (hΓΆchster Impact)~~ βœ… Erledigt -2. ~~**i18n** zu fehlenden Apps hinzufΓΌgen~~ βœ… Erledigt (6 Apps) -3. ~~**AuthGateModal** in Shared Package extrahieren~~ βœ… Erledigt (4 Apps) -4. ~~**Global Error Handler** extrahieren~~ βœ… Erledigt (7 Apps) -5. ~~**App-Skeletons vereinheitlichen**~~ βœ… Erledigt (3 Apps) -6. ~~**Auth Store Pattern dokumentieren**~~ βœ… Erledigt - ---- - -## Anhang: Analysierte Apps - -### Web Apps (16) - -- calendar, chat, clock, contacts, manadeck, manacore, matrix, nutriphi, picture, planta, presi, questions, skilltree, storage, todo, zitare - -### Shared Packages - -- @manacore/shared-auth -- @manacore/shared-auth-ui -- @manacore/shared-icons (Phosphor) -- @manacore/shared-i18n -- @manacore/shared-tailwind -- @manacore/shared-ui -- @manacore/shared-theme diff --git a/docs/CONSOLIDATION_OPPORTUNITIES.md b/docs/CONSOLIDATION_OPPORTUNITIES.md deleted file mode 100644 index b3e507f3f..000000000 --- a/docs/CONSOLIDATION_OPPORTUNITIES.md +++ /dev/null @@ -1,583 +0,0 @@ -# KonsolidierungsmΓΆglichkeiten - Monorepo Analyse - -> Erstellt: 29. Januar 2026 -> GeschΓ€tzte Gesamteinsparung: **~6.500-8.000 LOC** - -## Übersicht nach PrioritΓ€t - -| PrioritΓ€t | Bereich | GeschΓ€tzte Einsparung | Aufwand | -|-----------|---------|----------------------|---------| -| ~~**KRITISCH**~~ | ~~Backend Metrics Migration~~ | ~~350 LOC~~ βœ… **709 LOC entfernt** | ~~Niedrig~~ | -| ~~**HOCH**~~ | ~~Skeleton Components~~ | ~~800-1.000 LOC~~ β†’ **20 LOC** | ~~Mittel~~ β†’ Analysiert βœ… | -| ~~**HOCH**~~ | ~~App Settings Stores~~ | ~~600-700 LOC~~ βœ… **323 LOC entfernt** | ~~Mittel~~ | -| ~~**HOCH**~~ | ~~Main.ts/CORS Patterns~~ | ~~1.800 LOC~~ βœ… **~280 LOC entfernt** | ~~Mittel~~ | -| ~~**MITTEL**~~ | ~~TypeScript Configs~~ | ~~400 LOC~~ βœ… **~280 LOC entfernt** | ~~Niedrig~~ | -| ~~**MITTEL**~~ | ~~UI Component Cleanup~~ | ~~400 LOC~~ βœ… **~74 LOC entfernt** | ~~Niedrig~~ | -| ~~**MITTEL**~~ | ~~Vite Configs~~ | ~~300 LOC~~ βœ… **~350 LOC entfernt** | ~~Niedrig~~ | -| ~~**MITTEL**~~ | ~~Navigation Stores~~ | ~~50 LOC~~ βœ… **~50 LOC entfernt** | ~~Niedrig~~ | -| ~~**NIEDRIG**~~ | ~~Drizzle Configs~~ | ~~200 LOC~~ βœ… **~160 LOC entfernt** | ~~Niedrig~~ | -| ~~**NIEDRIG**~~ | ~~Logger Utilities~~ | ~~130 LOC~~ βœ… **~120 LOC entfernt** | ~~Niedrig~~ | - ---- - -## 1. Backend Patterns (NestJS) - -### 1.1 ~~KRITISCH: Metrics Migration~~ βœ… ERLEDIGT (709 LOC entfernt) - -**Status:** 6 Backends zu `@manacore/shared-nestjs-metrics` migriert (29.01.2026) - -**Migrierte Backends:** -- ~~`apps/chat/apps/backend/src/metrics/`~~ βœ… -- ~~`apps/calendar/apps/backend/src/metrics/`~~ βœ… -- ~~`apps/todo/apps/backend/src/metrics/`~~ βœ… -- ~~`apps/contacts/apps/backend/src/metrics/`~~ βœ… -- ~~`apps/skilltree/apps/backend/src/metrics/`~~ βœ… -- ~~`apps/clock/apps/backend/src/metrics/`~~ βœ… - -**Hinweis:** planta hatte keine lokale Metrics-Implementation. - -```typescript -// Vorher (50 LOC pro Backend) -@Injectable() -export class MetricsService implements OnModuleInit { - private readonly register: client.Registry; - // ... 45 weitere Zeilen -} - -// Nachher (5 LOC) -import { MetricsModule } from '@manacore/shared-nestjs-metrics'; -@Module({ imports: [MetricsModule.forRoot({ prefix: 'chat_' })] }) -``` - ---- - -### ~~1.2 HOCH: Main.ts/CORS Setup~~ βœ… TEILWEISE ERLEDIGT (~280 LOC gespart) - -**Status:** `@manacore/shared-nestjs-setup` Package erstellt und 8 Backends migriert (29.01.2026) - -**Migrierte Backends (8 von 14):** -- βœ… chat (3002), calendar (3014), contacts (3015), zitare (3007) -- βœ… clock (3017), planta (3022), presi (3008), nutriphi (3023) - -**Nicht migriert (komplexe Anforderungen):** -- ⏭️ manadeck - ConfigService, AppExceptionFilter -- ⏭️ picture - NestExpressApplication, Static Assets -- ⏭️ todo, skilltree - CORS Callback mit Logger -- ⏭️ questions, storage - ConfigService - -**Einsparung:** 8 Backends Γ— ~35 LOC = ~280 LOC - -**Empfehlung fΓΌr komplexe Backends:** Erstelle `@manacore/shared-nestjs-setup` - -```typescript -// packages/shared-nestjs-setup/src/bootstrap.ts -export interface BootstrapOptions { - corsOrigins?: string[]; - apiPrefix?: string; - excludeFromPrefix?: string[]; - enableMetrics?: boolean; - defaultPort?: number; -} - -export async function bootstrapApp( - AppModule: Type, - options: BootstrapOptions = {} -): Promise { - const app = await NestFactory.create(AppModule); - - // CORS (25 LOC -> 1 LOC) - setupCors(app, options.corsOrigins); - - // Validation (10 LOC -> 0 LOC) - app.useGlobalPipes(new ValidationPipe({ - whitelist: true, - transform: true, - forbidNonWhitelisted: true, - })); - - // Prefix (5 LOC -> 0 LOC) - app.setGlobalPrefix(options.apiPrefix || 'api/v1', { - exclude: options.excludeFromPrefix || ['health', 'metrics'], - }); - - return app; -} -``` - -**Vorher (85 LOC pro Backend):** -```typescript -async function bootstrap() { - const app = await NestFactory.create(AppModule); - const corsOrigins = process.env.CORS_ORIGINS?.split(',') || [...]; - app.enableCors({ origin: corsOrigins, ... }); - app.useGlobalPipes(new ValidationPipe({ ... })); - app.setGlobalPrefix('api/v1', { exclude: ['health'] }); - // ... -} -``` - -**Nachher (15 LOC):** -```typescript -import { bootstrapApp } from '@manacore/shared-nestjs-setup'; -import { AppModule } from './app.module'; - -async function bootstrap() { - const app = await bootstrapApp(AppModule, { - defaultPort: 3002, - enableMetrics: true, - }); - await app.listen(process.env.PORT || 3002); -} -bootstrap(); -``` - ---- - -### ~~1.3 MITTEL: Health Endpoints~~ βœ… ERLEDIGT (~300 LOC gespart) - -**Status:** `@manacore/shared-nestjs-health` Package erstellt und 12 Backends migriert (29.01.2026) - -**Erstelltes Package:** `packages/shared-nestjs-health/` -- `HealthModule.forRoot({ serviceName, version?, includeUptime?, route? })` -- Dynamischer Controller mit konfigurierbarer Route (default: 'health') -- Einheitliche HealthCheckResponse mit timestamp - -**Migrierte Backends (12 von 13):** -- βœ… calendar, chat, clock, contacts, nutriphi, picture, planta, presi, skilltree, storage, todo, zitare -- ⏭️ questions (ΓΌbersprungen - hat erweiterten DB-Health-Check) - -**Besonderheiten:** -- storage: Custom route `api/v1/health` -- zitare: serviceName `quote-backend` - -**Vorher (14 LOC pro Backend):** -```typescript -@Controller('health') -export class HealthController { - @Get() - check() { - return { status: 'ok', timestamp: new Date().toISOString(), service: 'chat' }; - } -} -``` - -**Nachher (1 LOC):** -```typescript -import { HealthModule } from '@manacore/shared-nestjs-health'; -@Module({ imports: [HealthModule.forRoot({ serviceName: 'chat-backend' })] }) -``` - -**Einsparung:** 12 Backends Γ— 26 LOC (Controller + Module) = ~312 LOC gelΓΆscht - ---- - -## 2. Frontend Stores (Svelte 5) - -### ~~2.1 HOCH: App Settings Stores~~ βœ… ERLEDIGT (323 LOC gespart) - -**Status:** `createAppSettingsStore()` Factory erstellt und 3 Apps migriert (29.01.2026) - -**Erstellte Factory:** `packages/shared-stores/src/settings.svelte.ts` -- Type-safe Settings Store mit localStorage Persistenz -- Optional: `onSettingsChange` Callback fΓΌr Cloud-Sync -- Reduziert Boilerplate von ~100 LOC pro App auf ~20 LOC - -**Migrierte Apps:** -- ~~`apps/todo/apps/web/src/lib/stores/settings.svelte.ts`~~ βœ… (259 β†’ 159 LOC = 100 LOC) -- ~~`apps/contacts/apps/web/src/lib/stores/settings.svelte.ts`~~ βœ… (278 β†’ 173 LOC = 105 LOC) -- ~~`apps/calendar/apps/web/src/lib/stores/settings.svelte.ts`~~ βœ… (433 β†’ 315 LOC = 118 LOC) - -```typescript -// Nachher (Beispiel Todo) -import { createAppSettingsStore } from '@manacore/shared-stores'; -const baseStore = createAppSettingsStore('todo-settings', DEFAULT_SETTINGS); -export const todoSettings = { - get settings() { return baseStore.settings; }, - initialize: baseStore.initialize, - set: baseStore.set, - // ... convenience getters -}; -``` - ---- - -### ~~2.2 MITTEL: Navigation Stores~~ βœ… ERLEDIGT (~50 LOC gespart) - -**Status:** `createSimpleNavigationStores()` Factory erstellt und 10 Apps migriert (29.01.2026) - -**Erstellte Factory:** `packages/shared-stores/src/navigation-simple.ts` -- Erstellt `isSidebarMode`, `isNavCollapsed` writable Stores -- Optional: `isToolbarCollapsed` mit `withToolbar: true` -- Optional: localStorage Persistenz mit `storageKey` - -**Migrierte Apps (10 von 10):** -- βœ… Einfach: chat, contacts, manacore, manadeck, matrix, presi, storage -- βœ… Mit Toolbar: calendar, todo -- βœ… Mit Persistenz: clock - -**Vorher (5-36 LOC):** -```typescript -import { writable } from 'svelte/store'; -export const isSidebarMode = writable(false); -export const isNavCollapsed = writable(false); -// + optional localStorage handling (30+ LOC) -``` - -**Nachher (3-5 LOC):** -```typescript -import { createSimpleNavigationStores } from '@manacore/shared-stores'; -export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores({ - storageKey: 'clock', // optional -}); -``` - -**Einsparung:** ~50 LOC (besonders Clock: 36 β†’ 4 LOC) - ---- - -### ~~2.3 NIEDRIG: Theme Stores Migration~~ βœ… ERLEDIGT (~150 LOC gespart) - -**Status:** 2 Apps zu `createThemeStore()` aus `@manacore/shared-theme` migriert (29.01.2026) - -**Migrierte Apps:** -- βœ… `apps/storage/apps/web/src/lib/stores/theme.svelte.ts` (96 β†’ 7 LOC = 89 LOC) -- βœ… `apps/questions/apps/web/src/lib/stores/theme.ts` (62 β†’ 47 LOC = 15 LOC, mit RΓΌckwΓ€rtskompatibilitΓ€t) - -**ZusΓ€tzlich gefixt:** -- βœ… `apps/storage/apps/web/src/routes/themes/+page.svelte` - Bug mit `def.colors.primary` β†’ `def.light.primary` - -**Questions Wrapper (RΓΌckwΓ€rtskompatibilitΓ€t):** -```typescript -// Legacy API (current, set, toggle) wird auf neue API gemappt -export const theme = { - get current() { return sharedTheme.mode; }, // Legacy - get mode() { return sharedTheme.mode; }, // New - set(newTheme) { sharedTheme.setMode(newTheme); }, // Legacy - toggle() { sharedTheme.toggleMode(); }, // Legacy - // ... new API forwarded -}; -``` - -**Einsparung:** ~104 LOC (158 β†’ 54 LOC) - ---- - -## 3. UI Components - -### ~~3.1 HOCH: Skeleton Components~~ βœ… ANALYSIERT (Minimal ~20 LOC gespart) - -**Status:** Nach detaillierter Analyse: Die meisten Skeletons sind legitime Domain-Customizations (29.01.2026) - -**Ergebnis der Analyse:** -- 29 Skeleton-Dateien ΓΌber 5 Apps (calendar, clock, contacts, todo, questions) -- **Fazit:** Skeletons nutzen bereits shared-ui Primitives (`SkeletonBox`) korrekt -- Domain-spezifische Layouts (Kalender-Grid, Uhr-Circle) gehΓΆren NICHT in shared-ui - -**DurchgefΓΌhrte Konsolidierung:** -- βœ… `calculateFadeOpacity()` Utility nach `@manacore/shared-ui` verschoben -- βœ… Contacts App nutzt jetzt die shared-ui Utility -- βœ… Lokale `utils.ts` in contacts gelΓΆscht (~20 LOC gespart) - -**Warum KEINE weitere Konsolidierung:** -| Skeleton | LOC | Status | -|----------|-----|--------| -| Calendar AppLoadingSkeleton | 56 | Keep - 7-Spalten Kalender-Grid Layout | -| Clock AppLoadingSkeleton | 91 | Keep - 300px kreisfΓΆrmiger Uhr-Platzhalter | -| ContactRowSkeleton, TaskItemSkeleton, etc. | ~800 | Keep - Legitime Domain-spezifische Komponenten | - -**Shared-UI hat bereits:** -- `SkeletonBox`, `SkeletonAvatar`, `SkeletonCard`, `SkeletonGrid`, `SkeletonList`, `SkeletonRow`, `SkeletonText` -- `AppLoadingSkeleton` mit 5 Layout-Presets (list, centered, sidebar, tasks, minimal) -- `calculateFadeOpacity()` Utility fΓΌr Fade-Effekte - ---- - -### ~~3.2 MITTEL: Sofort lΓΆschbare Duplikate~~ βœ… TEILWEISE ERLEDIGT - -**Picture App - Status (29.01.2026):** - -| Datei | LOC | Status | -|-------|-----|--------| -| ~~`Button.svelte`~~ | ~~53~~ | βœ… Migriert zu `@manacore/shared-ui` | -| ~~`Card.svelte`~~ | ~~21~~ | βœ… GelΓΆscht (unbenutzt) | -| ~~`Input.svelte`~~ | ~~70~~ | βœ… Bereits vorher gelΓΆscht | - -**Verbleibendes:** -- `Modal.svelte` kΓΆnnte migriert werden, aber hat unterschiedliche API (`open` vs `visible`) - ---- - -### ~~3.3 MITTEL: AppSlider Cleanup~~ βœ… ANALYSIERT (Keine Aktion nΓΆtig) - -**Status:** Nach Analyse: Die lokalen AppSlider.svelte Dateien sind KEINE Duplikate (29.01.2026) - -**Ergebnis der Analyse:** -Die 8 lokalen `AppSlider.svelte` Dateien sind **Lokalisierungs-Wrapper**, nicht Duplikate: -- Sie importieren `AppSlider` aus `@manacore/shared-ui` -- Sie mappen `MANA_APPS` aus `@manacore/shared-branding` zu deutschen Labels -- Sie ΓΌbergeben deutsche Lokalisierung (`APP_STATUS_LABELS.de`, `APP_SLIDER_LABELS.de`) an die shared Komponente - -**Beispiel (apps/chat/apps/web):** -```svelte - - - -``` - -**Fazit:** Korrekte Architektur - shared-ui stellt die Komponente bereit, Apps liefern lokalisierte Daten. - ---- - -### ~~3.4 NIEDRIG: LanguageSelector~~ βœ… ANALYSIERT (Korrekte Architektur) - -**Status:** Die lokalen LanguageSelector sind korrekte Wrapper, keine Duplikate (29.01.2026) - -**Ergebnis der Analyse:** -- 9 Apps haben lokale `LanguageSelector.svelte` (~19 LOC jede) -- Diese sind **Wrapper** die app-spezifisches i18n mit shared Helpers verbinden - -**Architektur ist korrekt:** -```svelte - - - -``` - -**Shared-i18n hat bereits:** -- `LanguageSelector.svelte` (242 LOC) - Standalone Komponente fΓΌr andere AnwendungsfΓ€lle -- `getLanguageDropdownItems()` - Helper fΓΌr PillDropdown-Items -- `getCurrentLanguageLabel()` - Helper fΓΌr aktuelle Sprache - -**Fazit:** Keine Konsolidierung nΓΆtig - jede App braucht ihren eigenen Wrapper fΓΌr app-spezifisches i18n Setup. - ---- - -## 4. Konfigurationsdateien - -### ~~4.1 MITTEL: TypeScript Configs~~ βœ… ERLEDIGT (~280 LOC gespart) - -**Status:** `@manacore/shared-tsconfig` Package erstellt und 13 Backends migriert (29.01.2026) - -**Erstelltes Package:** `packages/shared-tsconfig/` -- `base.json` - Gemeinsame Basis-Optionen -- `nestjs.json` - NestJS Backend Config (erweitert base) -- `sveltekit.json` - SvelteKit Web Config -- `expo.json` - Expo Mobile Config -- `astro.json` - Astro Landing Config - -**Migrierte Backends (13 von 14):** -- βœ… calendar, chat, clock, contacts, nutriphi, picture, planta, presi, questions, skilltree, storage, todo, zitare -- ⏭️ manadeck (ΓΌbersprungen - verwendet `nodenext` statt `commonjs`) - -**Vorher (25 LOC pro Backend):** -```json -{ - "compilerOptions": { - "module": "commonjs", - "moduleResolution": "node", - // ... 20+ weitere Zeilen - } -} -``` - -**Nachher (3 LOC):** -```json -{ - "extends": "@manacore/shared-tsconfig/nestjs" -} -``` - -**Einsparung:** 13 Backends Γ— ~22 LOC = ~280 LOC - ---- - -### ~~4.2 MITTEL: Vite Configs~~ βœ… ERLEDIGT (~350 LOC gespart) - -**Status:** `@manacore/shared-vite-config` erweitert und 15 SvelteKit Apps migriert (29.01.2026) - -**Erweitertes Package:** `packages/shared-vite-config/` -- `createViteConfig()` - Factory mit Port und additionalPackages -- `mergeViteConfig()` - Deep-merge fΓΌr App-spezifische Overrides -- `MANACORE_SHARED_PACKAGES` - 22+ Pakete fΓΌr SSR/optimizeDeps - -**Migrierte Apps (15 von 15):** -- βœ… calendar, chat, clock, contacts, manadeck, manacore, matrix, nutriphi, picture, planta, presi, questions, skilltree, storage, todo - -**Vorher (30-60 LOC pro App):** -```typescript -export default defineConfig({ - plugins: [tailwindcss(), sveltekit()], - server: { port: 5174, strictPort: true }, - ssr: { noExternal: ['@manacore/shared-icons', ...] }, - optimizeDeps: { exclude: ['@manacore/shared-icons', ...] }, -}); -``` - -**Nachher (12-14 LOC):** -```typescript -import { createViteConfig, mergeViteConfig } from '@manacore/shared-vite-config'; - -const baseConfig = createViteConfig({ - port: 5174, - additionalPackages: ['@app/shared'], // optional -}); - -export default defineConfig(mergeViteConfig(baseConfig, { - plugins: [tailwindcss(), sveltekit()], -})); -``` - -**Hinweis:** Matrix behΓ€lt spezielle WASM-Konfiguration fΓΌr matrix-js-sdk crypto. - -**Einsparung:** 15 Apps Γ— ~23 LOC = ~350 LOC - ---- - -### ~~4.3 NIEDRIG: Drizzle Configs~~ βœ… ERLEDIGT (~160 LOC gespart) - -**Status:** `@manacore/shared-drizzle-config` Package erstellt und 16 Configs migriert (29.01.2026) - -**Erstelltes Package:** `packages/shared-drizzle-config/` -- `createDrizzleConfig()` - Factory mit dbName, schemaPath, outDir, schemaFilter, etc. -- Standardwerte: schema `./src/db/schema/index.ts`, out `./src/db/migrations` -- Fallback URL: `postgresql://manacore:devpassword@localhost:5432/{dbName}` - -**Migrierte Configs (16 von 20):** -- βœ… Backends: calendar, chat, clock, contacts, nutriphi, picture, planta, presi, questions, skilltree, storage, todo -- βœ… Services: mana-core-auth, telegram-zitare-bot, telegram-todo-bot, telegram-nutriphi-bot - -**Nicht migriert (SonderfΓ€lle):** -- ⏭️ telegram-project-doc-bot (postgres:postgres Credentials) -- ⏭️ matrix-project-doc-bot (leere Fallback-URL) -- ⏭️ manadeck-database, nutriphi-database (Packages mit kompiliertem JS-Pfad) - -**Vorher (10-15 LOC):** -```typescript -export default defineConfig({ - schema: './src/db/schema/index.ts', - out: './src/db/migrations', - dialect: 'postgresql', - dbCredentials: { url: process.env.DATABASE_URL || '...' }, - verbose: true, - strict: true, -}); -``` - -**Nachher (1-5 LOC):** -```typescript -import { createDrizzleConfig } from '@manacore/shared-drizzle-config'; -export default createDrizzleConfig({ dbName: 'chat' }); -``` - -**Einsparung:** 16 Configs Γ— ~10 LOC = ~160 LOC - ---- - -## 5. Utility Functions - -### ~~5.1 NIEDRIG: Logger Utilities~~ βœ… ERLEDIGT (~120 LOC gespart) - -**Status:** `@manacore/shared-logger` Package erstellt und 2 Mobile Apps migriert (29.01.2026) - -**Erstelltes Package:** `packages/shared-logger/` -- `logger.debug/info/warn/error/success/log` - Standard Logger -- `perfLogger.start/end` - Performance-Messung -- `networkLogger.request/response/error` - Netzwerk-Debugging -- Individuelle Exports fΓΌr RΓΌckwΓ€rtskompatibilitΓ€t: `debug`, `info`, `warn`, `error`, `log` - -**Migrierte Apps:** -- βœ… `apps/manadeck/apps/mobile/utils/logger.ts` (34 β†’ 5 LOC) -- βœ… `apps/picture/apps/mobile/utils/logger.ts` (92 β†’ 5 LOC) - -**Einsparung:** ~120 LOC (126 β†’ 10 LOC, Shared Package: 100 LOC reusable) - ---- - -### ~~5.2 NIEDRIG: Sleep Function Duplikat~~ βœ… BEREITS ERLEDIGT - -**Status:** `shared-api-client` importiert bereits `sleep` aus `@manacore/shared-utils` (29.01.2026) - -```typescript -// packages/shared-api-client/src/client.ts -import { sleep } from '@manacore/shared-utils'; -``` - -**Fazit:** Kein Duplikat vorhanden - Dokumentation war veraltet. - ---- - -## Aktionsplan - -### Phase 1: Quick Wins (1-2 Tage, ~1.000 LOC) - -| Aufgabe | LOC | Aufwand | Status | -|---------|-----|---------|--------| -| ~~Metrics zu shared-nestjs-metrics migrieren (6 Backends)~~ | ~~350~~ β†’ **709** | ~~Niedrig~~ | βœ… Erledigt | -| ~~Picture Input.svelte lΓΆschen (unbenutzt)~~ | ~~70~~ | ~~Niedrig~~ | βœ… Erledigt | -| ~~Sleep-Duplikat entfernen~~ | ~~8~~ | ~~Minimal~~ | βœ… Erledigt | -| ~~Picture UI-Komponenten (Button/Card)~~ | ~~74~~ β†’ **74** | ~~Niedrig~~ | βœ… Erledigt | -| AppSlider Wrapper evaluieren (8 Apps) | - | Niedrig | Nicht nΓΆtig (sind Lokalisierungs-Wrapper) | - -### Phase 2: Stores & Configs (3-5 Tage, ~1.500 LOC) - -| Aufgabe | LOC | Aufwand | Status | -|---------|-----|---------|--------| -| ~~`createAppSettingsStore()` Factory erstellen~~ | ~~600~~ β†’ **323** | ~~Mittel~~ | βœ… Erledigt | -| ~~`@manacore/shared-tsconfig` Package erstellen~~ | ~~400~~ β†’ **280** | ~~Niedrig~~ | βœ… Erledigt | -| ~~`@manacore/shared-vite-config` erweitern (15 Apps)~~ | ~~300~~ β†’ **350** | ~~Niedrig~~ | βœ… Erledigt | -| ~~Navigation Store Factory erstellen~~ | ~~50~~ β†’ **50** | ~~Niedrig~~ | βœ… Erledigt | - -### Phase 3: Backend Setup (5-7 Tage, ~2.000 LOC) - -| Aufgabe | LOC | Aufwand | Status | -|---------|-----|---------|--------| -| ~~`@manacore/shared-nestjs-setup` erstellen~~ | ~~1.800~~ β†’ **280** | ~~Mittel~~ | βœ… 8 Backends migriert | -| ~~`@manacore/shared-nestjs-health` erstellen~~ | ~~170~~ β†’ **312** | ~~Niedrig~~ | βœ… 12 Backends migriert | -| ~~Drizzle Config Factory erstellen~~ | ~~200~~ β†’ **160** | ~~Niedrig~~ | βœ… Erledigt | - -### ~~Phase 4: Skeleton Refactoring~~ βœ… ANALYSIERT - -| Aufgabe | LOC | Aufwand | Status | -|---------|-----|---------|--------| -| ~~Page-Level Skeleton Presets~~ | ~~400~~ β†’ **0** | ~~Mittel~~ | Nicht nΓΆtig - Shared-UI hat bereits 5 Presets | -| ~~Bestehende Skeletons refactoren~~ | ~~400~~ β†’ **20** | ~~Mittel~~ | βœ… Nur `calculateFadeOpacity` Utility | - -**Ergebnis:** Domain-spezifische Skeletons sind korrekt designed. Keine große Konsolidierung nΓΆtig. - ---- - -## Zusammenfassung - -| Kategorie | GeschΓ€tzte Einsparung | -|-----------|----------------------| -| Backend (NestJS) | 2.300 LOC | -| Frontend Stores | 700 LOC | -| UI Components | 1.200 LOC | -| Konfigurationen | 900 LOC | -| Utilities | 130 LOC | -| **Gesamt** | **~5.200-6.500 LOC** | - -Plus Wartungsvorteile: -- Einheitliche Patterns ΓΌber alle Apps -- Single Point of Change fΓΌr Updates -- Bessere Onboarding-Erfahrung fΓΌr neue Entwickler -- Reduzierte Fehlerquellen durch Duplikate diff --git a/docs/DAILY_REPORT_2026-01-23.md b/docs/DAILY_REPORT_2026-01-23.md deleted file mode 100644 index 93b8c027c..000000000 --- a/docs/DAILY_REPORT_2026-01-23.md +++ /dev/null @@ -1,289 +0,0 @@ -# Daily Report - 23. Januar 2026 - -**Zeitraum:** 10:00 - 18:00 Uhr -**Commits:** 26 -**Hauptthemen:** Mac Mini Server Setup, Contacts App Deployment, Monitoring Stack, Landing Pages - ---- - -## Zusammenfassung - -Heute war ein sehr produktiver Tag mit Fokus auf die **Produktivstellung der ManaCore Apps auf dem Mac Mini Server**. Die wichtigsten Errungenschaften: - -- βœ… **6 Apps live** auf https://mana.how (Auth, Dashboard, Chat, Todo, Calendar, Clock) -- βœ… **Contacts App** vollstΓ€ndig deployed (Backend + Web) -- βœ… **Monitoring Stack** eingerichtet (Prometheus, Grafana, Umami Analytics) -- βœ… **Notification System** fΓΌr Health Checks (Telegram + Email) -- βœ… **Shared Landing UI** fΓΌr einheitliche Landing Pages - ---- - -## 1. Mac Mini Server Setup & Management - -### Auto-Start System (11:48) -**Commit:** `93060dc3` - feat(mac-mini): add auto-start and management scripts - -Einrichtung eines vollstΓ€ndigen Auto-Start-Systems fΓΌr den Mac Mini Server: - -- **LaunchAgent** fΓΌr automatischen Start beim Boot -- **Management Scripts:** - - `start-manacore.sh` - Startet alle Docker Container - - `stop-manacore.sh` - Stoppt alle Container - - `health-check.sh` - PrΓΌft alle Services - - `update-images.sh` - Aktualisiert Docker Images - -### PATH Fix fΓΌr Docker CLI (12:17) -**Commit:** `732aa79f` - fix(mac-mini): add PATH export for Docker CLI - -Problem behoben, dass Docker CLI in LaunchAgent-Umgebung nicht gefunden wurde. - -### Health Check Endpoints korrigiert (12:21) -**Commit:** `c5125926` - fix(mac-mini): correct health check endpoints - -Korrektur der Health Check URLs fΓΌr alle Services. - -### Notification System (13:18) -**Commit:** `de6151ae` - feat(mac-mini): add notification system for health checks - -Implementierung eines Benachrichtigungssystems: - -- **Telegram Bot** fΓΌr sofortige Alerts -- **Email Backup** via Gmail SMTP (msmtp) -- Automatische Benachrichtigung bei Service-AusfΓ€llen - ---- - -## 2. Contacts App Deployment - -### Docker Images erstellt (14:23) -**Commit:** `bb5f1452` - feat(contacts): add Docker deployment for Mac Mini - -Erstellung der Docker-Konfiguration fΓΌr Contacts: - -- `apps/contacts/apps/backend/Dockerfile` (Port 3015) -- `apps/contacts/apps/web/Dockerfile` (Port 5184) -- `docker-entrypoint.sh` fΓΌr automatische DB-Migrationen -- CI Workflow Updates fΓΌr Image-Builds - -### SvelteKit Adapter Fix (14:32) -**Commit:** `ad7a84fe` - fix(contacts-web): use adapter-node for Docker deployment - -Wechsel von `@sveltejs/adapter-auto` zu `@sveltejs/adapter-node` fΓΌr Node.js Deployment. - -### Multer Dependency (16:18) -**Commit:** `d03aaeb7` - fix(contacts-backend): add missing multer dependency - -Fehlende `multer` Dependency fΓΌr File-Upload-FunktionalitΓ€t hinzugefΓΌgt. - -### MinIO Object Storage (16:45) -**Commit:** `c3994748` - feat(infra): add MinIO for object storage - -Einrichtung von MinIO fΓΌr S3-kompatiblen Object Storage: - -- MinIO Container in docker-compose.macmini.yml -- `contacts-photos` Bucket fΓΌr Kontaktbilder -- S3 Environment Variables konfiguriert - -### Ergebnis - -**Live URLs:** -- https://contacts.mana.how (Web App) -- https://contacts-api.mana.how (Backend API) - ---- - -## 3. Monitoring & Analytics Stack - -### Monitoring Dashboard (15:31) -**Commit:** `6d86a08d` - feat: add monitoring dashboard (Prometheus + Grafana + Umami + Admin) - -VollstΓ€ndiger Monitoring Stack eingerichtet: - -| Service | Port | URL | -|---------|------|-----| -| **Prometheus** | 9090 | Metriken-Sammlung | -| **Grafana** | 3100 | grafana.mana.how | -| **Node Exporter** | 9100 | System-Metriken | -| **cAdvisor** | 8080 | Container-Metriken | -| **Postgres Exporter** | 9187 | Datenbank-Metriken | -| **Redis Exporter** | 9121 | Cache-Metriken | -| **Umami** | 3200 | analytics.mana.how | - -### Umami Analytics Integration (16:19 - 17:49) -**Commits:** -- `639041ae` - feat(analytics): add Umami website IDs for all landing pages -- `44e6a63a` - feat(analytics): add Umami website IDs for all web apps -- `5e54bcc5` - feat(analytics): add Umami tracking to remaining apps -- `1868a7ff` - refactor: change Umami analytics URL - -Integration von Umami Web Analytics in alle Apps: -- Unique Website IDs fΓΌr jede App -- Tracking Script in allen Web Apps und Landing Pages -- URL geΓ€ndert zu stats.mana.how - ---- - -## 4. Landing Pages & Shared Components - -### Shared Landing UI (15:45) -**Commit:** `264149a9` - feat(shared-landing-ui): unify landing pages with shared components - -Neues Package `@manacore/shared-landing-ui` mit wiederverwendbaren Astro-Komponenten: - -- `Hero.astro` - Hero Section -- `Features.astro` - Feature Grid -- `Pricing.astro` - Preistabellen -- `CTA.astro` - Call-to-Action -- `Footer.astro` - Footer -- `Layout.astro` - Base Layout - -### Zentrales Pricing System (17:46) -**Commit:** `d3dd26bd` - feat(shared-landing-ui): add centralized Mana pricing system - -Einheitliches Pricing fΓΌr alle Mana Apps: - -| Plan | Preis | Features | -|------|-------|----------| -| Free | 0€ | Basis-Features, limitiert | -| Pro | 4,99€/Monat | Alle Features, unbegrenzt | -| Team | 9,99€/Monat | Team-Features, Priority Support | - -### Clock Landing Page (17:50) -**Commit:** `8f54a563` - feat(clock): add landing page with shared-landing-ui - -Neue Landing Page fΓΌr Clock App mit shared-landing-ui Komponenten. - ---- - -## 5. Bug Fixes & Improvements - -### Todo Backend Health Check (12:18) -**Commit:** `bff168ee` - fix(docker): correct todo-backend health check path - -Korrektur des Health Check Pfads von `/api/health` zu `/api/v1/health`. - -### Clock Backend Drizzle Config (12:24) -**Commit:** `650b05bc` - fix(clock-backend): specify drizzle config path in entrypoint - -Explizite Angabe des Drizzle Config Pfads im Docker Entrypoint. - -### Clock Web Dashboard (12:47) -**Commit:** `515d6033` - feat(clock-web): add dashboard page for root route - -Dashboard-Seite fΓΌr die Root-Route der Clock Web App hinzugefΓΌgt. - -### Calendar Cross-App URLs (14:15) -**Commit:** `294074f5` - fix(calendar-web): add cross-app API URLs for todo and contacts - -Environment Variables fΓΌr Cross-App Integration: -- `PUBLIC_TODO_BACKEND_URL` -- `PUBLIC_CONTACTS_API_URL` - -### Cloudflare Pages Project Name (17:50) -**Commit:** `ead96800` - fix: correct Cloudflare Pages project name for clock landing - -Korrektur: `clock-landing` β†’ `clocks-landing` (URL Schema Konvention). - ---- - -## 6. Dokumentation - -### Mac Mini Server Docs (13:42) -**Commit:** `2b7c665f` - docs: add Mac Mini server documentation - -Umfassende Dokumentation in `docs/MAC_MINI_SERVER.md`: -- Architektur-Übersicht -- SSH-Zugang -- Docker Commands -- Health Checks -- Troubleshooting - -### Mail Server Planung (13:53) -**Commit:** `c2010cef` - docs: add mail server planning documentation - -Zukunftsplanung fΓΌr eigenen Mail Server: -- `docs/future/MAIL_SERVER_DEDICATED.md` - Raspberry Pi/Mini-PC LΓΆsung -- `docs/future/MAIL_SERVER_MAC_MINI_TEMP.md` - TemporΓ€re Mac Mini LΓΆsung - -### Production Launch Guide (17:50) -**Commit:** `447dfe27` - docs: add production launch guide and URL schema - -- `docs/PRODUCTION_LAUNCH.md` - Schritt-fΓΌr-Schritt Anleitung -- `docs/URL_SCHEMA.md` - Naming Conventions fΓΌr Subdomains - -### Calendar Wrangler Config (17:50) -**Commit:** `87b09eb5` - chore(calendar): add wrangler.toml for Cloudflare Pages - -### Infrastructure Updates (17:50) -**Commit:** `3e823ae0` - feat(infra): add Mac Mini setup script and update production docker-compose - -- `mac-mini-setup.sh` - Initiales Setup Script -- `docker-compose.production.yml` - Aktualisierte Production Config - ---- - -## Infrastruktur-Übersicht - -### Aktive Services auf Mac Mini - -| Service | Container | Port | Status | -|---------|-----------|------|--------| -| PostgreSQL | manacore-postgres | 5432 | βœ… | -| Redis | manacore-redis | 6379 | βœ… | -| MinIO | manacore-minio | 9000/9001 | βœ… | -| Auth | mana-core-auth | 3001 | βœ… | -| Dashboard | manacore-web | 5173 | βœ… | -| Chat Backend | chat-backend | 3002 | βœ… | -| Chat Web | chat-web | 3000 | βœ… | -| Todo Backend | todo-backend | 3018 | βœ… | -| Todo Web | todo-web | 5188 | βœ… | -| Calendar Backend | calendar-backend | 3016 | βœ… | -| Calendar Web | calendar-web | 5186 | βœ… | -| Clock Backend | clock-backend | 3017 | βœ… | -| Clock Web | clock-web | 5187 | βœ… | -| Contacts Backend | contacts-backend | 3015 | βœ… | -| Contacts Web | contacts-web | 5184 | βœ… | -| Prometheus | manacore-prometheus | 9090 | βœ… | -| Grafana | manacore-grafana | 3100 | βœ… | -| Umami | manacore-umami | 3200 | βœ… | - -### Live URLs - -| App | Web | API | -|-----|-----|-----| -| Dashboard | https://mana.how | - | -| Auth | - | https://auth.mana.how | -| Chat | https://chat.mana.how | https://chat-api.mana.how | -| Todo | https://todo.mana.how | https://todo-api.mana.how | -| Calendar | https://calendar.mana.how | https://calendar-api.mana.how | -| Clock | https://clock.mana.how | https://clock-api.mana.how | -| Contacts | https://contacts.mana.how | https://contacts-api.mana.how | -| Grafana | https://grafana.mana.how | - | -| Analytics | https://stats.mana.how | - | - ---- - -## Statistiken - -| Metrik | Wert | -|--------|------| -| **Commits** | 26 | -| **Neue Dateien** | ~50+ | -| **GeΓ€nderte Dateien** | ~30+ | -| **Neue Services deployed** | 4 (Contacts, MinIO, Prometheus Stack) | -| **Neue Dokumentationen** | 5 | - ---- - -## NΓ€chste Schritte - -1. **DNS konfigurieren** fΓΌr mana.how Domain -2. **SSL Zertifikate** einrichten (Caddy/Let's Encrypt) -3. **Grafana Dashboards** erstellen -4. **Backup-Strategie** implementieren -5. **Mobile Apps** testen mit neuen APIs -6. **Landing Pages** auf Cloudflare Pages deployen - ---- - -*Bericht erstellt am 23. Januar 2026, 18:00 Uhr* diff --git a/docs/DAILY_REPORT_2026-01-25.md b/docs/DAILY_REPORT_2026-01-25.md deleted file mode 100644 index 6a441b126..000000000 --- a/docs/DAILY_REPORT_2026-01-25.md +++ /dev/null @@ -1,299 +0,0 @@ -# Daily Report - 25. Januar 2026 - -**Zeitraum:** 00:00 - 18:00 Uhr -**Commits:** 20 -**Hauptthemen:** Guest Mode, NutriPhi App, Presi & Storage Restore, Watchtower Auto-Deploy, Prometheus Metrics - ---- - -## Zusammenfassung - -Ein umfangreicher Tag mit mehreren großen Features und Infrastructure-Γ„nderungen: - -- **Guest Mode** fΓΌr Contacts und Clock Apps implementiert -- **NutriPhi App** komplett neu hinzugefΓΌgt (AI-powered Nutrition Tracking) -- **Presi & Storage Apps** aus dem Archiv wiederhergestellt und Docker-ready gemacht -- **Watchtower Auto-Deploy** eingerichtet, Hetzner-Infrastruktur entfernt -- **Prometheus Metrics** fΓΌr Todo-Backend implementiert -- **CI/CD Pipeline** fΓΌr Presi und Storage erweitert - ---- - -## 1. Guest Mode Implementation - -### Session-First Guest Mode fΓΌr Contacts (00:00) -**Commit:** `753e6fd1` - feat(contacts): add session-first guest mode - -Implementierung eines "Session-First" Guest Mode Patterns: - -- **AuthGateModal** - Modal das Nutzer zur Anmeldung auffordert wenn sie persistente Features nutzen wollen -- **Session Contacts Store** - TemporΓ€rer Speicher fΓΌr Kontakte im Session Storage -- Nutzer kΓΆnnen die App ausprobieren ohne Account -- Daten werden erst bei Registrierung/Login synchronisiert - -**Neue Dateien:** -- `AuthGateModal.svelte` - Modaler Dialog fΓΌr Auth-Aufforderung -- `session-contacts.svelte.ts` - Svelte 5 Store fΓΌr Session-Kontakte - -### Guest Mode Fixes fΓΌr Web Apps (00:01 - 00:03) -**Commits:** -- `6713919e` - fix(web): fix userSettings.nav undefined error in guest mode -- `1e7bfd44` - fix(clock): remove auth redirect from dashboard for guest mode -- `b095532e` - fix(clock): load alarms/timers in guest mode - -Diverse Fixes um Guest Mode in allen Web Apps zu ermΓΆglichen: -- Fehler bei undefined userSettings.nav behoben -- Auth-Redirect auf Dashboard deaktiviert -- Alarme/Timer laden auch ohne Login - ---- - -## 2. NutriPhi App - Neue App - -### AI-Powered Nutrition Tracking (13:19) -**Commit:** `b6af01ed` - feat(nutriphi): add AI-powered nutrition tracking app - -Komplett neue App fΓΌr ErnΓ€hrungstracking mit KI-UnterstΓΌtzung: - -**Backend (NestJS):** -- Meal-Tracking mit CRUD-Operationen -- Gemini AI Integration fΓΌr Mahlzeiten-Analyse -- NΓ€hrwert-Berechnung und Statistiken -- TΓ€gliche Ziele und Empfehlungen -- Favoriten-System - -**Web (SvelteKit):** -- Dashboard mit TagesΓΌbersicht -- Mahlzeiten hinzufΓΌgen (manuell + Foto) -- Statistiken und Trends -- Ziele setzen und tracken - -**Landing (Astro):** -- Marketing-Seite mit Features -- Cloudflare Pages ready - -**API Endpoints:** -| Endpoint | Method | Description | -|----------|--------|-------------| -| `/api/v1/meals` | GET/POST | Mahlzeiten CRUD | -| `/api/v1/analysis/image` | POST | Foto-Analyse mit AI | -| `/api/v1/stats/daily` | GET | Tagesstatistiken | -| `/api/v1/goals` | GET/POST/PUT | ErnΓ€hrungsziele | -| `/api/v1/recommendations` | GET | AI-Empfehlungen | - -### Database Setup Script Update (13:19) -**Commit:** `9472978c` - chore(scripts): add nutriphi to database setup script - -NutriPhi zur automatischen Datenbank-Einrichtung hinzugefΓΌgt. - ---- - -## 3. Presi & Storage Apps Restore - -### Apps aus Archiv wiederhergestellt (13:25) -**Commit:** `36a9e3a3` - feat: restore presi and storage apps from archive - -Wiederherstellung der archivierten Apps: - -**Presi (PrΓ€sentations-App):** -- Decks erstellen und verwalten -- Slides mit verschiedenen Content-Types -- Themes und Sharing -- PrΓ€sentationsmodus - -**Storage (Cloud Storage):** -- Dateien hochladen und verwalten -- Ordner-Hierarchie -- Sharing mit Links -- Versionierung -- Tags und Favoriten - -### Development Scripts (13:27) -**Commit:** `0a4e7e0f` - feat: add dev scripts for presi and storage apps - -Neue npm Scripts in root package.json: -```bash -pnpm dev:presi:full # Presi mit Auth + DB Setup -pnpm dev:storage:full # Storage mit Auth + DB Setup -pnpm dev:presi:app # Presi Web + Backend -pnpm dev:storage:app # Storage Web + Backend -``` - -### Mac Mini Deployment Config (13:38) -**Commit:** `32c207ec` - feat(infra): add presi and storage apps to Mac Mini deployment - -Docker-Compose Konfiguration fΓΌr Mac Mini erweitert: - -| Service | Port | URL | -|---------|------|-----| -| presi-backend | 3008 | presi-api.mana.how | -| presi-web | 5178 | presi.mana.how | -| storage-backend | 3019 | storage-api.mana.how | -| storage-web | 5185 | storage.mana.how | - -### Dockerfiles erstellt (13:55) -**Commit:** `a12c7e5f` - feat(docker): add Dockerfiles for presi and storage apps - -Multi-Stage Docker Builds fΓΌr alle 4 Apps: - -**Presi Backend:** -- Port 3008 -- Auto-Migrations via docker-entrypoint.sh -- Health Check auf `/api/health` - -**Presi Web:** -- Port 5178 -- SvelteKit mit adapter-node - -**Storage Backend:** -- Port 3019 -- S3/MinIO Integration -- Auto-Migrations - -**Storage Web:** -- Port 5185 -- SvelteKit mit adapter-node - -### CI/CD Pipeline (16:11) -**Commit:** `409f9a07` - feat(ci): add Docker build jobs for presi and storage apps - -GitHub Actions Workflow erweitert: -- Change Detection fΓΌr `apps/presi/**` und `apps/storage/**` -- 4 neue Build Jobs fΓΌr Docker Images -- Push zu GitHub Container Registry - -### Adapter Fix fΓΌr Docker (17:49) -**Commit:** `75ffd504` - fix(presi,storage): use adapter-node for Docker builds - -Wechsel von `@sveltejs/adapter-auto` zu `@sveltejs/adapter-node`: -- adapter-auto funktioniert nicht in Docker -- Output-Verzeichnis auf `build` gesetzt - ---- - -## 4. Infrastructure: Watchtower & Cleanup - -### Hetzner Entfernt, Watchtower hinzugefΓΌgt (14:01) -**Commit:** `ac663a6c` - chore: remove staging/Hetzner infra, add Watchtower auto-deploy - -**Entfernt (15.581 Zeilen gelΓΆscht):** -- Alle Hetzner/Staging Workflows -- docker-compose.staging.yml -- docker-compose.production.yml -- Staging/Production Dokumentation -- Deployment Runbooks - -**HinzugefΓΌgt:** -- Watchtower Container fΓΌr Auto-Deploy -- Automatisches Image-Update bei neuen Releases -- Discord Notifications bei Updates - -**Watchtower Konfiguration:** -```yaml -watchtower: - image: containrrr/watchtower - volumes: - - /var/run/docker.sock:/var/run/docker.sock - environment: - - WATCHTOWER_CLEANUP=true - - WATCHTOWER_POLL_INTERVAL=300 - - WATCHTOWER_NOTIFICATION_URL=discord://... -``` - -### Watchtower Fixes (14:04 - 14:36) -**Commits:** -- `62e9d0d3` - fix(watchtower): set DOCKER_API_VERSION for compatibility -- `87724f8a` - fix(watchtower): remove custom notification template -- `8ff8cd5e` - test: update loading text to test Watchtower auto-deploy - -Diverse Fixes fΓΌr Watchtower-KompatibilitΓ€t: -- DOCKER_API_VERSION fΓΌr Γ€ltere Docker Versionen -- Standard Notification Template verwenden -- Test-Commit um Auto-Deploy zu verifizieren - ---- - -## 5. Prometheus Metrics - -### Todo Backend Metrics (13:31) -**Commit:** `4a236a7a` - feat(todo): add Prometheus metrics and update docs - -Implementierung von Prometheus Metrics fΓΌr Todo-Backend: - -**Metriken:** -- `app_info` - App Version und Name -- `http_requests_total` - Request Counter (method, path, status) -- `http_request_duration_seconds` - Request Latency Histogram - -**Neue Dateien:** -- `metrics.controller.ts` - `/metrics` Endpoint -- `metrics.service.ts` - Prometheus Registry -- `metrics.interceptor.ts` - HTTP Request Tracking - -### Metrics Refactoring (14:40) -**Commits:** -- `11411ff0` - fix(todo): capture error responses in metrics interceptor -- `f47bf8ed` - refactor(todo): use express middleware for HTTP metrics - -Verbesserungen am Metrics System: -- Error Responses werden jetzt korrekt erfasst -- Wechsel zu Express Middleware fΓΌr bessere Genauigkeit - ---- - -## 6. Sonstige Fixes - -### Lockfile Update (13:18) -**Commit:** `b77dd415` - fix(deps): update lockfile for telegram-stats-bot - -pnpm-lock.yaml aktualisiert wegen telegram-stats-bot Dependency. - ---- - -## Infrastruktur-Übersicht - -### Neue Services (bereit fΓΌr Deployment) - -| Service | Container | Port | Status | -|---------|-----------|------|--------| -| Presi Backend | presi-backend | 3008 | Ready | -| Presi Web | presi-web | 5178 | Ready | -| Storage Backend | storage-backend | 3019 | Ready | -| Storage Web | storage-web | 5185 | Ready | -| NutriPhi Backend | nutriphi-backend | 3020 | Ready | -| NutriPhi Web | nutriphi-web | 5190 | Ready | - -### Geplante URLs - -| App | Web | API | -|-----|-----|-----| -| Presi | https://presi.mana.how | https://presi-api.mana.how | -| Storage | https://storage.mana.how | https://storage-api.mana.how | -| NutriPhi | https://nutriphi.mana.how | https://nutriphi-api.mana.how | - ---- - -## Statistiken - -| Metrik | Wert | -|--------|------| -| **Commits** | 20 | -| **Neue Apps** | 1 (NutriPhi) | -| **Wiederhergestellte Apps** | 2 (Presi, Storage) | -| **Neue Dockerfiles** | 4 | -| **GelΓΆschte Zeilen** | ~15.000+ (Hetzner Cleanup) | -| **Neue Dateien** | ~100+ | - ---- - -## NΓ€chste Schritte - -1. **NutriPhi** - Docker Images bauen und deployen -2. **Presi/Storage** - CI Build verifizieren und deployen -3. **Grafana Dashboards** - Metrics Dashboards fΓΌr neue Services -4. **Guest Mode** - Auf weitere Apps ausweiten -5. **Mobile Apps** - Guest Mode auch fΓΌr Expo Apps - ---- - -*Bericht erstellt am 25. Januar 2026* diff --git a/docs/DAILY_REPORT_2026-01-30.md b/docs/DAILY_REPORT_2026-01-30.md deleted file mode 100644 index 7b26f42d0..000000000 --- a/docs/DAILY_REPORT_2026-01-30.md +++ /dev/null @@ -1,397 +0,0 @@ -# Daily Report - 30. Januar 2026 - -**Zeitraum:** 10:00 - 19:00 Uhr -**Commits:** 41 -**Hauptthemen:** Matrix SSO/OIDC Integration, 9 neue Matrix Bots, LLM Playground, Demo Mode Removal - ---- - -## Zusammenfassung - -Ein intensiver Tag mit Fokus auf **Matrix-Integration** und **Bot-Infrastruktur**: - -- **Matrix SSO/OIDC** - Mana Core Auth als OIDC Provider fΓΌr Matrix Synapse (mchat.mana.how) -- **9 Matrix Bots** - Neue Bots fΓΌr Picture, Contacts, ManaDeck, Planta, Questions, Presi, Skilltree, Chat -- **LLM Playground** - SvelteKit UI fΓΌr lokale Ollama-Modelle -- **Demo Mode entfernt** - Login jetzt erforderlich fΓΌr alle Apps -- **Docker Fixes** - shared-vite-config und shared-stores KompatibilitΓ€t - ---- - -## 1. Matrix SSO/OIDC Integration (Hauptfeature) - -### Problem - -Matrix Synapse auf mchat.mana.how sollte Mana Core Auth als OIDC Provider nutzen, um SSO zu ermΓΆglichen. User sollten sich mit ihrem Mana-Account bei Matrix anmelden kΓΆnnen. - -### Herausforderungen & LΓΆsungen - -#### 1.1 CSP blockiert Inline-Scripts (10:00) -**Commit:** `3d4402ad` - fix(mana-core-auth): allow inline scripts in CSP for OIDC login page - -**Problem:** Die OIDC Login-Seite nutzt Inline-JavaScript, aber die Content Security Policy (CSP) blockierte dies. - -**LΓΆsung:** CSP um `'unsafe-inline'` erweitert fΓΌr die Login-Seite: -```typescript -// main.ts - Helmet configuration -scriptSrc: ["'self'", "'unsafe-inline'"], -``` - -#### 1.2 Client-Name "Unknown" auf Login-Seite (10:30) -**Commit:** `4a66341e` - fix(mana-core-auth): extract client_id from returnUrl for OIDC login - -**Problem:** Die Login-Seite zeigte "Unknown" statt "Matrix Chat" als Client-Name. - -**LΓΆsung:** client_id aus dem returnUrl-Parameter extrahieren: -```typescript -// oidc-login.controller.ts -const returnUrlObj = new URL(returnUrl, 'http://localhost'); -const clientIdFromUrl = returnUrlObj.searchParams.get('client_id'); -const clientId = req.query.client_id || clientIdFromUrl || 'unknown'; -``` - -#### 1.3 Session Cookies fehlen nach Login (12:00) -**Commits:** -- `edbe7502` - fix(mana-core-auth): use Better Auth native sign-in for OIDC login -- `f59b6596` - fix(mana-core-auth): add dedicated Better Auth handler for sign-in - -**Problem:** Nach dem Login wurde kein Authorization Code generiert, weil `/api/v1/auth/login` keine Session-Cookies setzt. - -**LΓΆsung:** Wechsel zu Better Auth's nativem `/api/auth/sign-in/email` Endpoint: -```typescript -// oidc.controller.ts - Neuer Handler -@Post('api/auth/sign-in/email') -async signInEmail(@Req() req: Request, @Res() res: Response) { - return this.handleBetterAuthRequest(req, res); -} - -private async handleBetterAuthRequest(req: Request, res: Response) { - const handler = this.betterAuthService.getHandler(); - const response = await handler(fetchRequest); - // Copy Set-Cookie headers for session - response.headers.forEach((value, key) => { - if (key.toLowerCase() === 'set-cookie') { - res.append(key, value); - } - }); -} -``` - -#### 1.4 INVALID_REDIRECT_URI Error (14:00) -**Commits:** -- `8207d38c` - fix(mana-core-auth): use comma-separated redirect_urls for Better Auth OIDC -- `ee05b6c3` - fix(mana-core-auth): use correct property name 'redirectUrls' for Better Auth - -**Problem:** Better Auth's OIDC Provider gab `INVALID_REDIRECT_URI` zurΓΌck, obwohl die URL korrekt in der Datenbank war. - -**Ursachen & LΓΆsungen:** - -1. **Format-Problem:** Better Auth erwartet **Komma-separierte Strings**, nicht JSON-Arrays: - ```sql - -- FALSCH (JSON Array) - redirect_urls: '["https://matrix.mana.how/_synapse/client/oidc/callback"]' - - -- RICHTIG (Komma-separiert) - redirect_urls: 'https://matrix.mana.how/_synapse/client/oidc/callback' - ``` - -2. **Property-Name:** Better Auth erwartet `redirectUrls` (lowercase 'urls'), nicht `redirectURLs` (uppercase 'URLs'): - ```typescript - // auth.schema.ts - VORHER - redirectURLs: text('redirect_urls').notNull(), - - // auth.schema.ts - NACHHER - redirectUrls: text('redirect_urls').notNull(), - ``` - -#### 1.5 Consent-Screen ΓΌberspringen (17:00) -**Commits:** -- `bb428d4b` - fix(mana-core-auth): add Matrix Synapse as trusted OIDC client -- `01a2c78e` - fix(mana-core-auth): add all required fields to trusted client config -- `c949f5d0` - fix(mana-core-auth): fix type compatibility for trusted client config -- `744d0c9c` - fix(mana-core-auth): remove non-existent id field from trusted client - -**Problem:** Nach erfolgreichem Login wurde zum Consent-Screen weitergeleitet, der nicht implementiert war. - -**LΓΆsung:** Matrix Synapse als trusted client konfigurieren mit `skipConsent: true`: -```typescript -// better-auth.config.ts -oidcProvider({ - loginPage: '/login', - consentPage: '/consent', - trustedClients: [ - { - clientId: 'matrix-synapse', - clientSecret: process.env.SYNAPSE_OIDC_CLIENT_SECRET || '', - name: 'Matrix Synapse', - type: 'web', - disabled: false, - metadata: {}, - redirectUrls: ['https://matrix.mana.how/_synapse/client/oidc/callback'], - skipConsent: true, - }, - ], -}), -``` - -### Ergebnis - -Der OIDC-Flow funktioniert nun vollstΓ€ndig: -1. User klickt "Sign in with Mana Core" auf mchat.mana.how -2. Redirect zu auth.mana.how/login mit Client-Info -3. User sieht "Signing in to **Matrix Chat**" -4. Nach Login: Session-Cookie wird gesetzt -5. Redirect zurΓΌck mit Authorization Code -6. Token-Exchange fΓΌr Access Token -7. User ist in Matrix eingeloggt - ---- - -## 2. Matrix Bots (9 neue Bots) - -Implementierung von 9 spezialisierten Matrix-Bots fΓΌr die Integration mit ManaCore Apps. - -### Neue Bots - -| Bot | Commit | Beschreibung | -|-----|--------|--------------| -| **matrix-picture-bot** | `8950692c` | AI-Bildgenerierung via Flux | -| **matrix-contacts-bot** | `64535373` | Kontaktverwaltung | -| **matrix-manadeck-bot** | `ad7f875c` | Kartendecks verwalten | -| **matrix-planta-bot** | `3f336de1` | Pflanzenpflege-Management | -| **matrix-questions-bot** | `c5476447` | Q&A Research | -| **matrix-presi-bot** | `e3cfafe5` | PrΓ€sentationsverwaltung | -| **matrix-skilltree-bot** | `3ed1453f` | Skill Tree & XP | -| **matrix-chat-bot** | `68219a01` | AI Chat Conversations | - -### Standardisierung -**Commit:** `df47dafe` - chore(matrix-bots): standardize package.json across all 9 bots - -Alle Bots nutzen nun: -- Einheitliche Dependency-Versionen -- Standard Scripts: `dev`, `build`, `start` -- Konsistente NestJS-Struktur -- TypeScript strict mode - -### TypeScript Fixes -**Commit:** `004fe857` - fix(matrix-bots): resolve TypeScript strict null check errors - -Behebung von null-check Fehlern in allen Bot-Services. - ---- - -## 3. LLM Playground - -### Neue SvelteKit UI -**Commits:** -- `f880ef2b` - feat(llm-playground): add SvelteKit LLM playground UI -- `fdba0e34` - feat(llm-playground): add production deployment with auth -- `5d5e42c7` - feat(chat): add all Mac Mini Ollama models to playground - -Neues Web-Interface zum Testen lokaler Ollama-Modelle: - -**Features:** -- Model-Auswahl (alle Mac Mini Ollama-Modelle) -- Chat-Interface mit Streaming -- System Prompt Konfiguration -- Temperature/Max Tokens Settings - -**VerfΓΌgbare Modelle:** -| Modell | Beschreibung | -|--------|--------------| -| gemma3:4b | Everyday tasks (default) | -| qwen2.5-coder:7b | Code generation | -| llava:7b | Image analysis | -| qwen3-vl:4b | Fast vision | -| deepseek-ocr | OCR/Text recognition | -| phi3.5 | Compact, efficient | -| ministral:3b | Very fast | - -**URLs:** -- https://llm.mana.how (Production) -- http://localhost:5191 (Development) - ---- - -## 4. Demo Mode Removal - -### Entfernung aus allen Apps -**Commits:** -- `f07387d1` - πŸ”₯ remove: demo mode from todo, contacts, clock, questions, chat apps -- `82da95b8` - πŸ”₯ remove(calendar-web): remove demo mode, enforce login - -**Betroffene Apps:** -- Todo -- Contacts -- Clock -- Questions -- Chat -- Calendar - -**Γ„nderungen:** -- `DEMO_MODE` Environment Variable entfernt -- Login jetzt obligatorisch -- Redirect zu `/login` fΓΌr nicht-authentifizierte User -- Session-Storage fΓΌr Guest-Daten entfernt - ---- - -## 5. Docker & Build Fixes - -### shared-vite-config KompatibilitΓ€t -**Commits:** -- `359b8706` - πŸ”§ chore: add shared-vite-config to web Dockerfiles -- `d09ea061` - πŸ”§ chore: add shared-vite-config as devDependency to web apps -- `36941552` / `90f9f2c9` - πŸ”§ chore(shared-vite-config): add build step for Docker compatibility -- `eb475ace` - πŸ”§ chore(calendar-web): add shared-vite-config to devDependencies - -**Problem:** Docker Builds fehlgeschlagen wegen fehlendem shared-vite-config. - -**LΓΆsung:** -1. Package als devDependency zu allen Web-Apps hinzugefΓΌgt -2. Build-Step in shared-vite-config fΓΌr TypeScript-Kompilierung -3. Expliziter Build im Dockerfile vor App-Build - -### shared-stores und shared-api-client -**Commits:** -- `4526123b` - πŸ”§ chore: add shared-stores and shared-api-client to web apps -- `8779d047` - πŸ”§ chore(calendar-web): add shared-stores to Dockerfile - -Fehlende Shared Packages zu Dockerfiles hinzugefΓΌgt. - ---- - -## 6. Calendar Web Fixes - -**Commits:** -- `8da676ff` - πŸ› fix(calendar-web): initialize auth store on mount -- `017891b1` - πŸ› fix(calendar-web): use client URL in browser for API calls -- `e5a5e968` - πŸ› fix(calendar-web): add missing packages to Dockerfile - -**Fixes:** -1. Auth Store wird jetzt beim Mount initialisiert (nicht nur im Browser) -2. API-Calls nutzen Browser-URL statt Server-URL -3. Fehlende Packages im Dockerfile ergΓ€nzt - ---- - -## 7. Sonstige Γ„nderungen - -### Matrix Web SSR Fix -**Commit:** `3b745cf0` - fix(matrix-web): disable SSR for app routes to fix $state error - -SSR deaktiviert fΓΌr App-Routes wegen Svelte 5 `$state` KompatibilitΓ€tsproblemen. - -### Mana Notify -**Commit:** `b8ecdb8e` - πŸ”§ chore(mana-notify): disable email notifications by default - -Email-Benachrichtigungen standardmÀßig deaktiviert (nur Push-Notifications aktiv). - -### Dependencies Update -**Commit:** `3edbd0cb` - chore: update dependencies and mana-llm improvements - -Allgemeine Dependency-Updates und mana-llm Verbesserungen. - -### Syntax Fix -**Commit:** `2daaee74` - πŸ› fix: syntax error in contacts-web +layout.svelte - -Syntax-Fehler in Contacts Web Layout behoben. - ---- - -## Technische Details - -### OIDC Flow Architektur - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Matrix/Synapse │────>β”‚ Mana Core Auth │────>β”‚ Database β”‚ -β”‚ mchat.mana.how β”‚ β”‚ auth.mana.how β”‚ β”‚ oauth_apps β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β”‚ - β”‚ 1. SSO Click β”‚ 2. /api/auth/oauth2/authorize - β”‚ β”‚ - β–Ό β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Login Page │────>β”‚ Better Auth β”‚ -β”‚ /login β”‚ β”‚ Session Cookie β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β”‚ - β”‚ 3. POST sign-in β”‚ 4. Set-Cookie - β”‚ β”‚ - β–Ό β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Redirect with β”‚<────│ Auth Code Gen β”‚ -β”‚ ?code=xxx β”‚ β”‚ (trusted client)β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Better Auth OIDC Provider Konfiguration - -```typescript -oidcProvider({ - loginPage: '/login', - consentPage: '/consent', - metadata: { - issuer: process.env.BASE_URL, - }, - trustedClients: [{ - clientId: 'matrix-synapse', - clientSecret: process.env.SYNAPSE_OIDC_CLIENT_SECRET, - name: 'Matrix Synapse', - type: 'web', - disabled: false, - metadata: {}, - redirectUrls: ['https://matrix.mana.how/_synapse/client/oidc/callback'], - skipConsent: true, - }], -}), -``` - -### Datenbank-Schema Γ„nderung - -```typescript -// VORHER (Breaking) -export const oauthApplications = authSchema.table('oauth_applications', { - redirectURLs: text('redirect_urls').notNull(), // Capital 'URLs' -}); - -// NACHHER (Working) -export const oauthApplications = authSchema.table('oauth_applications', { - redirectUrls: text('redirect_urls').notNull(), // Lowercase 'urls' -}); -``` - ---- - -## Statistiken - -| Metrik | Wert | -|--------|------| -| **Commits** | 41 | -| **Neue Matrix Bots** | 9 | -| **Bearbeitete Dateien** | ~100+ | -| **Hauptfeature** | Matrix SSO/OIDC | -| **GelΓΆste Bugs** | 12+ | -| **Build Zeit** | ~3 Minuten pro mana-core-auth Build | - ---- - -## Bekannte Issues - -1. **Token Exchange**: Das client_secret in der Datenbank muss mit dem Environment-Variable ΓΌbereinstimmen -2. **SSH Tunnel**: Cloudflare Tunnel zeitweise instabil (Websocket Handshake Fehler) - ---- - -## NΓ€chste Schritte - -1. **Token Endpoint Fix** - Sicherstellen dass DB-Secret und ENV-Secret ΓΌbereinstimmen -2. **Matrix Bot Deployment** - Alle 9 Bots auf Mac Mini deployen -3. **LLM Playground** - Production Deployment finalisieren -4. **Monitoring** - OIDC-Metriken zu Grafana hinzufΓΌgen -5. **Documentation** - Matrix SSO Setup Guide erstellen - ---- - -*Bericht erstellt am 30. Januar 2026, 19:00 Uhr* diff --git a/docs/DAILY_REPORT_2026-02-01.md b/docs/DAILY_REPORT_2026-02-01.md deleted file mode 100644 index ec33691b9..000000000 --- a/docs/DAILY_REPORT_2026-02-01.md +++ /dev/null @@ -1,574 +0,0 @@ -# Daily Report - 1. Februar 2026 - -**Zeitraum:** 18:00 (31. Jan) - 04:15 Uhr (1. Feb) -**Commits:** 35+ -**Hauptthemen:** Voice Integration, Matrix Bot Consolidation, Node.js v25 Compatibility, Mac Mini Deployment - ---- - -## Zusammenfassung - -Eine intensive Nacht-Session mit Fokus auf **Voice-Integration** und **Bot-Infrastruktur-Konsolidierung**: - -- **Voice Integration** - VollstΓ€ndige Sprach-Ein-/Ausgabe fΓΌr matrix-mana-bot (4 Phasen) -- **Bot Consolidation** - 19 Matrix-Bots auf gemeinsame Packages migriert (~5,500 Zeilen dedupliziert) -- **Node.js v25 Fixes** - ESM-KompatibilitΓ€t fΓΌr matrix-bot-common und bot-services -- **Mac Mini Deployment** - matrix-mana-bot erfolgreich deployed und getestet -- **Matrix Media API Fix** - Authenticated Downloads fΓΌr Synapse 1.98+ - ---- - -## 1. Voice Integration fΓΌr matrix-mana-bot (Hauptfeature) - -### Übersicht - -VollstΓ€ndige Integration von Spracheingabe und -ausgabe in den Gateway-Bot. Nutzer kΓΆnnen jetzt Sprachnachrichten senden und erhalten sowohl Text- als auch Audio-Antworten. - -### Phase 1: Voice Input (STT) -**Commit:** `db07b561` - feat(matrix-mana-bot): add voice input support - -Implementierung der Spracheingabe via Whisper: - -```typescript -// voice/voice.service.ts -async transcribe(audioBuffer: Buffer): Promise { - const response = await fetch(`${this.sttUrl}/transcribe`, { - method: 'POST', - body: formData, - }); - return data.text; -} -``` - -**Features:** -- Audio-Download von Matrix via `downloadMedia()` -- Whisper STT-Integration (mana-stt auf Port 3020) -- Transkription wird als Nachricht angezeigt: `🎀 *"Was sind meine Aufgaben?"*` -- Transkribierter Text wird als normaler Command verarbeitet - -### Phase 2: Voice Output (TTS) -**Commit:** `48dfcd18` - feat(matrix-mana-bot): add voice output/TTS support - -Implementierung der Sprachausgabe via Edge TTS: - -```typescript -// voice/voice.service.ts -async synthesize(text: string, voice?: string, speed?: number): Promise { - const response = await fetch(`${this.voiceBotUrl}/tts`, { - method: 'POST', - body: JSON.stringify({ text, voice, speed }), - }); - return Buffer.from(await response.arrayBuffer()); -} -``` - -**Features:** -- Edge TTS Integration (mana-voice-bot auf Port 3050) -- 15 deutsche Stimmen verfΓΌgbar -- Audio-Antworten werden als m.audio Message gesendet -- Dual-Response: Text + Audio bei Voice-Anfragen - -### Phase 3: Smart Voice Formatting -**Commit:** `e892e8db` - feat(matrix-mana-bot): add smart voice formatting - -Intelligente Formatierung fΓΌr natΓΌrliche Sprachausgabe: - -```typescript -// voice/voice-formatter.service.ts -export class VoiceFormatterService { - format(text: string): string { - return this.applyAllFormatters(text); - } -} -``` - -**Formatierungen:** -| Input | Output | -|-------|--------| -| `10:00` | "zehn Uhr" | -| `14:30` | "halb drei" | -| `15.02.` | "15. Februar" | -| `!p1` | "mit hΓΆchster PrioritΓ€t" | -| `@heute` | "fΓ€llig heute" | -| `1. Item\n2. Item\n3. Item` | "Erstens Item, Zweitens Item, Drittens Item" | -| Lange Listen | "Top 3... und X weitere" | - -### Phase 4: Persistent Voice Preferences -**Commit:** `462ef006` - feat(matrix-mana-bot): add persistent voice preferences - -Benutzerspezifische Spracheinstellungen: - -```typescript -// voice/voice-preferences.store.ts -export interface VoicePreferences { - voice: string; // de-DE-ConradNeural - speed: number; // 1.0 - autoVoiceReply: boolean; // true -} -``` - -**Neue Commands:** -| Command | Beschreibung | -|---------|-------------| -| `!voice` | Aktuelle Stimme anzeigen | -| `!voice ` | Stimme Γ€ndern | -| `!voices` | VerfΓΌgbare Stimmen auflisten | -| `!speed 1.5` | Sprechgeschwindigkeit Γ€ndern (0.5-2.0x) | -| `!voice auto an/aus` | Auto-Reply an/aus | - -**Persistenz:** -- Gespeichert in `data/voice-preferences.json` -- Debounced Save (1s VerzΓΆgerung) -- Automatische Wiederherstellung bei Neustart - ---- - -## 2. Bot Consolidation - Shared Packages - -### @manacore/matrix-bot-common -**Commit:** `145b0b65` - feat: create @manacore/matrix-bot-common shared package - -Neues Package mit gemeinsamen Utilities fΓΌr alle Matrix-Bots: - -**Komponenten:** -| Komponente | Beschreibung | -|------------|--------------| -| `BaseMatrixService` | Abstrakte Basisklasse mit Client-Lifecycle | -| `HealthController` | Standardisierter Health-Endpoint | -| `MatrixMessageService` | Message/Reply/Reaction Helpers | -| `markdownToHtml()` | Markdown zu HTML Konvertierung | -| `KeywordCommandDetector` | Natural Language Command Detection | -| `SessionHelper` | Type-safe Session Data Wrapper | -| `UserListMapper` | Nummern-basiertes Referenzsystem | - -**Migration:** -```typescript -// VORHER: Jeder Bot hat eigenen Code (~200 Zeilen) -@Injectable() -export class MatrixService implements OnModuleInit { - private client: MatrixClient; - // ... duplicate initialization code -} - -// NACHHER: Extends BaseMatrixService -@Injectable() -export class MatrixService extends BaseMatrixService { - protected handleTextMessage(roomId: string, event: MatrixRoomEvent, message: string) { - // Nur Bot-spezifische Logik - } -} -``` - -**Commits fΓΌr Migration:** -- `2567ea62` - 19 Bots auf BaseMatrixService migriert (~1,500 Zeilen entfernt) -- `83f2d63f` - 19 Bots auf shared HealthController migriert (~400 Zeilen entfernt) -- `867a1a7f` - 5 Bots auf KeywordCommandDetector migriert -- `a23430f2` - 11 weitere Bots auf KeywordCommandDetector migriert - -### @manacore/bot-services Consolidation -**Commit:** `9b61831c` - refactor: consolidate SessionService & TranscriptionService - -Zentrale Services fΓΌr alle Bots: - -**SessionService:** -```typescript -// Vorher: In 11 Bots dupliziert -// Nachher: Einmal in @manacore/bot-services -@Injectable() -export class SessionService { - async validateToken(token: string): Promise; - async getSession(matrixUserId: string): Promise; -} -``` - -**TranscriptionService:** -```typescript -// Vorher: In 6 Bots dupliziert -// Nachher: Einmal in @manacore/bot-services -@Injectable() -export class TranscriptionService { - async transcribe(audioBuffer: Buffer): Promise; -} -``` - -**Migrierte Bots (22 Module-Dateien gelΓΆscht):** -- SessionService: 11 Bots -- TranscriptionService: 6 Bots -- **Code-Reduktion:** ~1,100 Zeilen - -### Voice Transcription fΓΌr alle Bots -**Commit:** `c29939e7` - feat: add voice transcription support to Matrix bots - -13 Bots kΓΆnnen jetzt Sprachnachrichten verarbeiten: - -| Bot | Voice Support | -|-----|---------------| -| matrix-calendar-bot | Transkription β†’ Command | -| matrix-chat-bot | Transkription β†’ AI Chat | -| matrix-contacts-bot | Transkription β†’ Search | -| matrix-manadeck-bot | Transkription β†’ Command | -| matrix-ollama-bot | Transkription β†’ AI | -| matrix-picture-bot | Transkription β†’ Prompt | -| matrix-planta-bot | Transkription β†’ Command | -| matrix-presi-bot | Transkription β†’ Command | -| matrix-questions-bot | Transkription β†’ Research | -| matrix-skilltree-bot | Transkription β†’ XP | -| matrix-stats-bot | Transkription β†’ Stats | -| matrix-storage-bot | Transkription β†’ Search | -| matrix-tts-bot | Transkription β†’ Voice | - ---- - -## 3. Node.js v25 ESM Compatibility - -### Problem - -Mac Mini lΓ€uft auf Node.js v25, welches strikte ESM-Regeln hat: - -``` -Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/app/node_modules/@manacore/matrix-bot-common/src/base' is not supported -``` - -### LΓΆsung: Explizite .js Extensions -**Commits:** -- `cfaf9f2f` - fix(matrix-bot-common): use explicit ESM imports -- `12f1288a` - build(matrix-bot-common): add build step for Node.js v25 -- `5b4b1282` - build(bot-services): add build step for Node.js v25 - -```typescript -// VORHER (funktioniert nicht in Node.js v25) -export * from './base'; -export * from './health'; - -// NACHHER (funktioniert) -export * from './base/index.js'; -export * from './health/index.js'; -``` - -**Package.json Updates:** -```json -{ - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, - "./base": { "types": "./dist/base/index.d.ts", "default": "./dist/base/index.js" } - }, - "scripts": { - "build": "tsc" - } -} -``` - ---- - -## 4. NestJS Dependency Injection Fixes - -### Problem - -OrchestrationModule konnte AiService, TodoService, CalendarService nicht auflΓΆsen: - -``` -Error: Nest can't resolve dependencies of OrchestrationService (?, ?, ?). -Please make sure that the argument AiService at index [0] is available. -``` - -### LΓΆsung: Global Modules -**Commits:** -- `2a03a7ce` - fix(matrix-mana-bot): import service modules in OrchestrationModule -- `8370005b` - fix(matrix-mana-bot): make service modules global for DI - -```typescript -// app.module.ts - VORHER -imports: [ - TodoModule.registerAsync({ ... }), - AiModule.registerAsync({ ... }), -] - -// app.module.ts - NACHHER (global: true) -imports: [ - { - ...TodoModule.registerAsync({ ... }), - global: true, - }, - { - ...AiModule.registerAsync({ ... }), - global: true, - }, -] -``` - -Mit `global: true` sind die Services in allen Modulen verfΓΌgbar, ohne dass jedes Modul die Service-Module importieren muss. - ---- - -## 5. Matrix Authenticated Media API - -### Problem - -Synapse 1.98+ erfordert authentifizierte Media-Downloads: - -``` -GET /_matrix/media/r0/download/mana.how/abc123 -β†’ 404 M_NOT_FOUND -``` - -### LΓΆsung: Neue v1 API mit Bearer Token -**Commit:** `793b6d8e` - fix(matrix-bot-common): use authenticated media API for downloads - -```typescript -// base-matrix.service.ts -protected async downloadMedia(mxcUrl: string): Promise { - const [, serverName, mediaId] = mxcUrl.match(/^mxc:\/\/([^/]+)\/(.+)$/); - - // Neue authentifizierte API (Matrix spec v1.11+) - const downloadUrl = `${config.homeserverUrl}/_matrix/client/v1/media/download/${serverName}/${mediaId}`; - - const response = await fetch(downloadUrl, { - headers: { - Authorization: `Bearer ${config.accessToken}`, - }, - }); - - if (!response.ok) { - // Fallback zu alter API fΓΌr Γ€ltere Server - return this.client.downloadContent(mxcUrl).data; - } - - return Buffer.from(await response.arrayBuffer()); -} -``` - -**API-Vergleich:** -| Version | Endpoint | Auth | -|---------|----------|------| -| Alt (r0) | `/_matrix/media/r0/download/{server}/{mediaId}` | Keine | -| Neu (v1) | `/_matrix/client/v1/media/download/{server}/{mediaId}` | Bearer Token | - ---- - -## 6. Mac Mini Deployment - -### Deployment-Prozess - -```bash -# 1. SSH auf Mac Mini -ssh mana-server - -# 2. Repo updaten -cd ~/projects/manacore-monorepo -git pull - -# 3. Packages bauen (wegen ESM) -pnpm --filter @manacore/matrix-bot-common build -pnpm --filter @manacore/bot-services build - -# 4. Bot bauen -cd services/matrix-mana-bot -pnpm build - -# 5. Bot starten -nohup node dist/main.js > logs.txt 2>&1 & -``` - -### Test-Ergebnisse - -**Text-Commands:** -| Command | Status | -|---------|--------| -| `!help` | βœ… Funktioniert | -| `!todo Einkaufen` | βœ… Task erstellt | -| `!list` | βœ… Tasks angezeigt | -| AI Chat | βœ… Ollama Antwort | - -**Voice-Commands:** -| Test | Status | -|------|--------| -| Audio-Download | βœ… Authenticated API | -| Whisper Transkription | βœ… 6.9s fΓΌr kurze Phrase | -| AI-Verarbeitung | βœ… 82 Tokens @ 37 t/s | -| TTS-Synthese | βœ… 143KB in 1.9s | -| Audio-Reply | βœ… Gesendet | - -**Logs:** -``` -[MatrixService] Bot user ID: @mana-bot:mana.how -[VoiceService] STT URL: http://localhost:3020 -[VoiceService] Voice Bot URL: http://localhost:3050 -[AiService] Ollama connected: v0.15.1 -[Bootstrap] Mana Gateway Bot running on port 3310 - -[MatrixService] Downloading audio from mxc://mana.how/SOEedHRtrSujwFiNLkiZvTFB -[MatrixService] Transcribing 11742 bytes -[VoiceService] Transcribed in 6923ms: "Was sind meine Aufgaben?" -[AiService] Generated 82 tokens at 37.0 t/s -[VoiceService] Synthesized 143712 bytes in 1966ms -[MatrixService] Sent audio response (143712 bytes) -``` - ---- - -## 7. Weitere Γ„nderungen - -### Docker-Compose Restructuring -**Commit:** `508ae124` - refactor: restructure docker-compose with new port schema - -Neues Port-Schema gemÀß ADR-003: -| Range | Kategorie | -|-------|-----------| -| 3000-3099 | Core Services & Backends | -| 4000-4099 | Matrix Stack | -| 5000-5099 | Web Frontends | -| 6000-6099 | Automation | -| 8000-8099 | Monitoring | -| 9000-9199 | Infrastructure | - -### Telegram Bots entfernt -**Commit:** `a341aa1b` - remove: Telegram bots - Matrix-only strategy - -6 Telegram-Bots entfernt zugunsten Matrix-only Strategie: -- Volle Kontrolle ΓΌber UX -- Komplette DSGVO-Compliance -- Keine AbhΓ€ngigkeit von Drittanbietern - -### mana-media Service -**Commit:** `cd28a830` - feat(mana-media): add unified media processing platform - -Neue Medien-Verarbeitungsplattform: -- Multi-Format Upload -- Async Transcoding via BullMQ -- Adaptive Streaming (HLS) -- S3-kompatibler Storage - -### Manalink PWA -**Commit:** `5c8120f4` - feat(manalink): add PWA support and rebrand Matrix client - -Matrix-Client als installierbare PWA: -- Neuer Name: "Manalink" (statt "Mana Matrix") -- Service Worker mit Workbox -- Offline-Caching -- iOS/Android Meta-Tags - -### tsconfig & Vite Fixes -**Commits:** -- `0229b1c9` - fix: resolve tsconfig issues across all NestJS backends -- `03abacc8` - fix(web-apps): fix Vite type compatibility - -10 NestJS-Backends und 14 Web-Apps gefixt: -- Lokale Compiler-Options statt shared-tsconfig -- Drizzle-ORM Type-KompatibilitΓ€t -- Vite @types/node Konflikte gelΓΆst - -### OAuth Token Endpoint Fix -**Commits:** -- `191c7b4c` - fix(mana-core-auth): handle form-urlencoded token requests -- `0d986478` - fix(mana-core-auth): use body-parser for urlencoded - -Matrix Synapse sendet Token-Requests als `application/x-www-form-urlencoded`, aber Better Auth erwartete JSON. Fix mit body-parser Middleware. - ---- - -## Architektur-Diagramm - -### Voice Pipeline - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ matrix-mana-bot β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Audio Message│───>β”‚ downloadMedia│───>β”‚ VoiceService β”‚ β”‚ -β”‚ β”‚ (m.audio) β”‚ β”‚ (v1 API+Auth)β”‚ β”‚ .transcribe() β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β–Ό β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ mana-stt (Whisper) β”‚ β”‚ -β”‚ β”‚ localhost:3020 β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β–Ό β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ CommandRouter β†’ handleTextMessage() β”‚ β”‚ -β”‚ β”‚ "Was sind meine Aufgaben?" β†’ AI/Todo/Calendar β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β–Ό β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ VoiceFormatterService.format() β”‚ β”‚ -β”‚ β”‚ Numbers β†’ Words, Times β†’ Natural Speech β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β–Ό β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ mana-voice-bot (Edge TTS) β”‚ β”‚ -β”‚ β”‚ localhost:3050 β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β–Ό β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Text Reply β”‚ β”‚ Audio Reply β”‚ β”‚ uploadMedia() β”‚ β”‚ -β”‚ β”‚ (m.text) β”‚ β”‚ (m.audio) β”‚<───│ Matrix Upload β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Shared Packages Hierarchie - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ 19 Matrix Bots β”‚ -β”‚ calendarβ”‚chatβ”‚clockβ”‚contactsβ”‚manaβ”‚manadeckβ”‚nutriphiβ”‚ollamaβ”‚... β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β–Ό β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ @manacore/matrix-bot- β”‚ β”‚ @manacore/bot-services β”‚ -β”‚ common β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ - TodoModule β”‚ -β”‚ - BaseMatrixService β”‚ β”‚ - CalendarModule β”‚ -β”‚ - HealthController β”‚ β”‚ - AiModule β”‚ -β”‚ - markdownToHtml β”‚ β”‚ - ClockModule β”‚ -β”‚ - KeywordCommandDetectorβ”‚ β”‚ - SessionModule β”‚ -β”‚ - SessionHelper β”‚ β”‚ - TranscriptionModule β”‚ -β”‚ - UserListMapper β”‚ β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - ---- - -## Statistiken - -| Metrik | Wert | -|--------|------| -| **Commits** | 35+ | -| **Neue Packages** | 2 (@manacore/matrix-bot-common, mana-media) | -| **Migrierte Bots** | 19 | -| **Entfernte Duplikate** | ~5,500 Zeilen | -| **Voice Phases** | 4 | -| **Neue Voice Commands** | 5 (!voice, !voices, !speed, !voice auto) | -| **Bearbeitete Dateien** | ~150+ | -| **Mac Mini Services** | matrix-mana-bot deployed | - ---- - -## Bekannte Issues - -1. **Whisper Latenz** - ~7s fΓΌr kurze Phrasen (akzeptabel fΓΌr async Messages) -2. **TTS QualitΓ€t** - Edge TTS ist gut, aber nicht perfekt fΓΌr komplexe SΓ€tze -3. **Voice Preferences** - Noch keine Migration wenn sich Voice-Namen Γ€ndern - ---- - -## NΓ€chste Schritte - -1. **Voice fΓΌr andere Bots** - TTS-Output auch fΓΌr calendar-bot, todo-bot etc. -2. **Streaming TTS** - Audio chunks statt vollstΓ€ndiger Download -3. **Voice Wake Word** - "Hey Mana" Aktivierung -4. **Whisper Optimierung** - Batch-Processing, Caching -5. **Docker Images** - matrix-mana-bot als Docker Image bauen - ---- - -*Bericht erstellt am 1. Februar 2026, 04:30 Uhr* diff --git a/docs/DAILY_REPORT_2026-02-02.md b/docs/DAILY_REPORT_2026-02-02.md deleted file mode 100644 index b804746bb..000000000 --- a/docs/DAILY_REPORT_2026-02-02.md +++ /dev/null @@ -1,1081 +0,0 @@ -# Daily Report - 2. Februar 2026 - -**Zeitraum:** 10:00 Uhr (1. Feb) - 05:00 Uhr (2. Feb) -**Commits:** 51 -**Hauptthemen:** OIDC/Synapse Integration, Matrix Bot CI/CD, Credit System, Cross-Domain SSO, Monitoring - ---- - -## Zusammenfassung - -Eine epische 19-Stunden-Session mit Fokus auf **Auth-Infrastruktur** und **Production Readiness**: - -- **OIDC Integration** - VollstΓ€ndige Synapse-KompatibilitΓ€t mit EdDSA JWT Signing -- **Matrix Bot CI/CD** - Automatisierte GHCR Deployments fΓΌr 10 Bots mit Watchtower -- **Credit System** - Neue Packages fΓΌr Credit-Operationen und UI-Komponenten -- **Cross-Domain SSO** - Single Sign-On ΓΌber alle *.mana.how Subdomains -- **Monitoring** - Node-Exporter, Grafana Dashboards, Prometheus Alerts -- **SSD Migration** - PostgreSQL und MinIO auf externe SSD verschoben - ---- - -## 1. OIDC/Synapse Integration (Kritische Fixes) - -### Problem - -Matrix Synapse konnte sich nicht mit mana-core-auth verbinden. Token-Verifizierung schlug fehl. - -### Ursachen & LΓΆsungen - -#### 1.1 EdDSA JWT Signing -**Commit:** `efb077b9` - fix(mana-core-auth): use EdDSA for OIDC id_token signing - -```typescript -// better-auth.config.ts - VORHER -const auth = betterAuth({ - jwt: { - issuer: config.get('JWT_ISSUER'), - } -}); - -// NACHHER - mit JWT Plugin fΓΌr EdDSA -const auth = betterAuth({ - plugins: [jwt()], // Aktiviert EdDSA Keys aus JWKS - advanced: { - useJWTPlugin: true, // id_tokens mit EdDSA statt HS256 - } -}); -``` - -**Warum:** Synapse verifiziert id_tokens via JWKS-Endpoint (`/.well-known/jwks.json`). HS256 verwendet ein Shared Secret, das Synapse nicht kennt. EdDSA verwendet Public/Private Keypaar aus JWKS. - -#### 1.2 JWT Issuer = BASE_URL -**Commit:** `8cd5021b` - fix(mana-core-auth): use BASE_URL as JWT issuer - -```typescript -// VORHER -jwt: { issuer: config.get('JWT_ISSUER') } // "manacore" - -// NACHHER -jwt: { issuer: config.get('BASE_URL') } // "https://auth.mana.how" -``` - -**Warum:** OIDC Discovery Document (`/.well-known/openid-configuration`) enthΓ€lt `issuer: "https://auth.mana.how"`. Der JWT `iss` Claim muss damit ΓΌbereinstimmen. - -#### 1.3 Body-Parser fΓΌr Token Exchange -**Commit:** `f0cf1bc8` - fix(mana-core-auth): OIDC token exchange now works with body-parser - -```typescript -// main.ts -app.use(bodyParser.urlencoded({ extended: true })); -app.use(bodyParser.json()); - -// oidc.controller.ts -@Post('token') -async token(@Req() req: Request, @Res() res: Response) { - // req.body ist jetzt geparsed, nicht raw - const params = new URLSearchParams(); - for (const [key, value] of Object.entries(req.body)) { - params.append(key, String(value)); - } - return this.betterAuthService.handleOidcRequest(params, res); -} -``` - -**Warum:** Synapse sendet Token-Requests als `application/x-www-form-urlencoded`. Ohne body-parser kam `req.body` als leeres Objekt an. - -#### 1.4 CORS Origins erweitert -**Commit:** `5a8e20e0` - fix(auth): add all apps to CORS_ORIGINS - -```yaml -# docker-compose.macmini.yml -environment: - CORS_ORIGINS: "https://auth.mana.how,https://matrix.mana.how,https://chat.mana.how,https://calendar.mana.how,https://todo.mana.how,https://clock.mana.how,https://contacts.mana.how,https://picture.mana.how,https://zitare.mana.how,https://questions.mana.how,https://planta.mana.how,https://skilltree.mana.how,https://storage.mana.how,https://manadeck.mana.how,https://nutriphi.mana.how,https://presi.mana.how,https://link.mana.how,https://playground.mana.how" -``` - ---- - -## 2. Matrix Bot CI/CD Pipeline - -### Übersicht - -Vollautomatische Build- und Deployment-Pipeline fΓΌr 10 Matrix-Bots via GitHub Actions β†’ GHCR β†’ Watchtower. - -**Commit:** `45152ee9` - feat(matrix-bots): add CI/CD pipeline for automated GHCR deployment - -### Pipeline-Architektur - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ GitHub Actions CI β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Push to main │───>β”‚ Detect │───>β”‚ Build Docker β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ Changes β”‚ β”‚ Images (amd64) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β–Ό β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Push to GHCR β”‚ β”‚ -β”‚ β”‚ ghcr.io/till-js/ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Mac Mini Server β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Watchtower β”‚ β”‚ -β”‚ β”‚ (polls GHCR every 5 minutes) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β–Ό β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ mana-bot β”‚ β”‚ todo-bot β”‚ β”‚ calendar β”‚ β”‚ ollama β”‚ β”‚ -β”‚ β”‚ :latest β”‚ β”‚ :latest β”‚ β”‚ -bot β”‚ β”‚ -bot β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Bots mit CI/CD - -| Bot | GHCR Image | Port | -|-----|------------|------| -| matrix-mana-bot | `ghcr.io/till-js/matrix-mana-bot` | 3310 | -| matrix-todo-bot | `ghcr.io/till-js/matrix-todo-bot` | 3311 | -| matrix-calendar-bot | `ghcr.io/till-js/matrix-calendar-bot` | 3312 | -| matrix-ollama-bot | `ghcr.io/till-js/matrix-ollama-bot` | 3313 | -| matrix-stats-bot | `ghcr.io/till-js/matrix-stats-bot` | 3314 | -| matrix-project-doc-bot | `ghcr.io/till-js/matrix-project-doc-bot` | 3315 | -| matrix-tts-bot | `ghcr.io/till-js/matrix-tts-bot` | 3316 | -| matrix-clock-bot | `ghcr.io/till-js/matrix-clock-bot` | 3317 | -| matrix-nutriphi-bot | `ghcr.io/till-js/matrix-nutriphi-bot` | 3318 | -| matrix-zitare-bot | `ghcr.io/till-js/matrix-zitare-bot` | 3319 | - -### Docker-Build Challenges - -#### Problem 1: QEMU Emulation Failure -**Commits:** `ab49be0b`, `a50d98c7` - -```bash -# CI Build auf amd64 Runner fΓΌr arm64 Target -Error: qemu: uncaught target signal 4 (Illegal instruction) -``` - -**LΓΆsung:** Nur amd64 bauen. Mac Mini mit Apple Silicon lΓ€uft via Rosetta. - -```yaml -# .github/workflows/ci.yml -platforms: linux/amd64 # Kein linux/arm64 -``` - -```yaml -# docker-compose.macmini.yml -services: - matrix-mana-bot: - platform: linux/amd64 # Explizit fΓΌr Apple Silicon -``` - -#### Problem 2: Alpine vs glibc -**Commit:** `a384bed1` - fix(matrix-bots): switch to node:20-slim - -```dockerfile -# VORHER - Alpine (musl libc) -FROM node:20-alpine - -# NACHHER - Debian slim (glibc) -FROM node:20-slim -``` - -**Warum:** `@matrix-org/matrix-sdk-crypto-nodejs` hat prebuilt Binaries nur fΓΌr glibc. - -#### Problem 3: E2EE Native Module -**Commit:** `a8521d7a` - fix(matrix-bots): disable E2EE crypto module - -```json -// package.json (root) -{ - "pnpm": { - "overrides": { - "@matrix-org/matrix-sdk-crypto-nodejs": "npm:empty-npm-package@1.0.0" - } - } -} -``` - -**Warum:** Das Crypto-Module erfordert plattformspezifische Native Binaries. In Docker-CI nicht verfΓΌgbar. E2EE wird serverseitig von Synapse gehandelt. - -#### Problem 4: Health Check -**Commit:** `ea0198cc` - fix(bots): install wget for Docker health checks - -```dockerfile -# node:20-slim hat weder wget noch curl -RUN apt-get update && apt-get install -y wget && rm -rf /var/lib/apt/lists/* -``` - ---- - -## 3. Credit System - -### Neue Packages - -**Commit:** `8cd5021b` - feat: add credit-operations and shared-credit-ui packages - -#### @manacore/credit-operations - -Zentrale Definition aller Credit-Operationen: - -```typescript -// packages/credit-operations/src/index.ts -export const CREDIT_OPERATIONS = { - // Chat - 'chat:message': { cost: 1, description: 'Send chat message' }, - 'chat:ai-response': { cost: 5, description: 'AI response generation' }, - - // Picture - 'picture:generate-sd': { cost: 10, description: 'Stable Diffusion image' }, - 'picture:generate-flux': { cost: 25, description: 'Flux image generation' }, - - // Calendar - 'calendar:ai-scheduling': { cost: 3, description: 'AI scheduling assistant' }, - - // Todo - 'todo:ai-breakdown': { cost: 5, description: 'AI task breakdown' }, - - // ... 50+ weitere Operationen -}; - -export function getCreditCost(operation: string): number { - return CREDIT_OPERATIONS[operation]?.cost ?? 0; -} -``` - -#### @manacore/shared-credit-ui - -UI-Komponenten fΓΌr React Native und Svelte: - -**Mobile (React Native):** -```typescript -// CreditBalance.tsx -export function CreditBalance({ userId }: Props) { - const balance = useCreditBalance(userId); - return ( - - Credits - {balance} - - ); -} - -// CreditToast.tsx -export function CreditToast({ operation, cost }: Props) { - return ( - - -{cost} Credits - {operation} - - ); -} -``` - -**Web (Svelte):** -```svelte - - - -
- Credits - {balance} -
-``` - -### NestJS Integration - -**@UseCredits Decorator:** -```typescript -// packages/mana-core-nestjs-integration/src/decorators/use-credits.decorator.ts -export function UseCredits(operation: string, cost?: number) { - return applyDecorators( - SetMetadata('credit_operation', operation), - SetMetadata('credit_cost', cost ?? getCreditCost(operation)), - UseInterceptors(CreditInterceptor), - ); -} -``` - -**CreditInterceptor:** -```typescript -// packages/mana-core-nestjs-integration/src/interceptors/credit.interceptor.ts -@Injectable() -export class CreditInterceptor implements NestInterceptor { - constructor(private creditService: CreditClientService) {} - - async intercept(context: ExecutionContext, next: CallHandler) { - const operation = Reflector.get('credit_operation', context.getHandler()); - const cost = Reflector.get('credit_cost', context.getHandler()); - const user = context.switchToHttp().getRequest().user; - - // Check balance before operation - const hasCredits = await this.creditService.hasCredits(user.sub, cost); - if (!hasCredits) { - throw new ForbiddenException('Insufficient credits'); - } - - return next.handle().pipe( - tap(async () => { - // Deduct credits after successful operation - await this.creditService.consumeCredits(user.sub, operation, cost); - }), - ); - } -} -``` - -**Verwendung in Controller:** -```typescript -// apps/chat/apps/backend/src/chat/chat.controller.ts -@Controller('chat') -@UseGuards(AuthGuard) -export class ChatController { - @Post('message') - @UseCredits('chat:ai-response') // 5 Credits - async sendMessage(@Body() dto: SendMessageDto) { - return this.chatService.processMessage(dto); - } -} -``` - ---- - -## 4. Cross-Domain SSO - -### Problem - -Nutzer mussten sich auf jedem Subdomain separat einloggen: -- `auth.mana.how` β†’ Login -- `chat.mana.how` β†’ Login erneut -- `calendar.mana.how` β†’ Login erneut - -### LΓΆsung - -**Commit:** `f03c09ff` - feat(auth): enable cross-domain SSO via shared cookies - -```typescript -// better-auth.config.ts -const auth = betterAuth({ - advanced: { - crossSubDomainCookies: { - enabled: true, - domain: process.env.COOKIE_DOMAIN || undefined, // ".mana.how" - }, - }, - trustedOrigins: [ - 'https://auth.mana.how', - 'https://chat.mana.how', - 'https://calendar.mana.how', - 'https://todo.mana.how', - // ... alle Apps - ], -}); -``` - -```yaml -# docker-compose.macmini.yml -mana-core-auth: - environment: - COOKIE_DOMAIN: ".mana.how" -``` - -### SSO Flow - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ User Flow β”‚ -β”‚ β”‚ -β”‚ 1. User besucht calendar.mana.how β”‚ -β”‚ β†’ Kein Cookie β†’ Redirect zu auth.mana.how/login β”‚ -β”‚ β”‚ -β”‚ 2. Login auf auth.mana.how β”‚ -β”‚ β†’ Cookie gesetzt: domain=".mana.how" β”‚ -β”‚ β†’ Redirect zurΓΌck zu calendar.mana.how β”‚ -β”‚ β”‚ -β”‚ 3. calendar.mana.how β”‚ -β”‚ β†’ Cookie vorhanden β†’ Eingeloggt! β”‚ -β”‚ β”‚ -β”‚ 4. User wechselt zu chat.mana.how β”‚ -β”‚ β†’ Cookie vorhanden β†’ Automatisch eingeloggt! β”‚ -β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Matrix SSO Token Handling - -**Commit:** `dc0d425f` - fix(matrix-web): handle Matrix SSO loginToken callback - -```typescript -// apps/matrix/apps/web/src/lib/matrix/client.ts -export async function loginWithLoginToken( - homeserverUrl: string, - loginToken: string -): Promise { - const response = await fetch(`${homeserverUrl}/_matrix/client/v3/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - type: 'm.login.token', - token: loginToken, - }), - }); - - const data = await response.json(); - return { - userId: data.user_id, - accessToken: data.access_token, - deviceId: data.device_id, - }; -} -``` - -```svelte - - -``` - ---- - -## 5. Monitoring & Grafana - -### Node-Exporter fΓΌr Host-Metriken - -**Commit:** `7aa5115c` - feat(monitoring): add node-exporter for host system metrics - -```yaml -# docker-compose.macmini.yml -node-exporter: - image: prom/node-exporter:latest - container_name: node-exporter - volumes: - - /proc:/host/proc:ro - - /sys:/host/sys:ro - command: - - '--path.procfs=/host/proc' - - '--path.sysfs=/host/sys' - - '--collector.cpu' - - '--collector.meminfo' - - '--collector.diskstats' - - '--collector.filesystem' - - '--collector.loadavg' - - '--collector.netdev' - ports: - - "9100:9100" -``` - -### Grafana Dashboards - -#### Master Overview -**Commit:** `e7719eeb` - feat(grafana): enhance Master Overview with Key Metrics - -Key Metrics Panel (oberste Zeile): -| Panel | Query | -|-------|-------| -| Services UP | `count(up{job=~".*"} == 1)` | -| Apps Running | `count(up{job=~".*-backend\|.*-web"} == 1)` | -| Matrix Bots | `count(up{job=~"matrix-.*"} == 1)` | -| Avg Response Time | `avg(rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m]))` | -| Total Requests | `sum(increase(http_requests_total[24h]))` | -| Requests/sec | `sum(rate(http_requests_total[5m]))` | -| Redis Keys | `redis_db_keys{db="db0"}` | -| Error Rate | `sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))` | - -#### System Overview -**Commit:** `84e9f86d` - fix(grafana): rewrite System Overview with available metrics - -Host System Section: -```promql -# CPU Usage -100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) - -# Memory Usage -(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 - -# Disk Usage -(1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 -``` - -#### Auth Service Dashboard -**Commit:** `fe33f4b3` - feat: add Grafana dashboard for Auth Service monitoring - -Panels: -- Login Success/Failure Rate -- Token Validation Latency -- Active Sessions -- Registration Trend -- Password Reset Requests -- OIDC Token Exchange Rate - -### Prometheus Alerts - -**Commit:** `fe33f4b3` - feat: add 10 auth-specific Prometheus alert rules - -```yaml -# docker/prometheus/alerts.yml -groups: - - name: auth_alerts - rules: - - alert: AuthServiceDown - expr: up{job="mana-core-auth"} == 0 - for: 1m - labels: - severity: critical - annotations: - summary: "Auth service is down" - - - alert: HighLoginFailureRate - expr: rate(auth_login_failures_total[5m]) / rate(auth_login_attempts_total[5m]) > 0.3 - for: 5m - labels: - severity: warning - annotations: - summary: "Login failure rate above 30%" - - - alert: TokenValidationSlow - expr: histogram_quantile(0.95, rate(auth_token_validation_seconds_bucket[5m])) > 0.5 - for: 5m - labels: - severity: warning - annotations: - summary: "Token validation p95 > 500ms" -``` - ---- - -## 6. Auth UI Improvements - -### Resend Verification Email - -**Commit:** `d703ccfd` - feat(auth): add resend verification email to registration screen - -```svelte - - - -{#if showVerificationSent} -
- -

{t('auth.verificationEmailSent')}

-

{t('auth.checkInbox')}

- -
-{/if} -``` - -### Multilingual Auth Pages - -**Commit:** `ff22a297` - feat(i18n): make all auth pages multilingual - -15 Apps aktualisiert fΓΌr dynamische Locale: - -```svelte - - - - - - -``` - -**Translations erweitert:** -```json -// packages/shared-i18n/src/translations/auth/de.json -{ - "verificationEmailSent": "BestΓ€tigungs-E-Mail gesendet!", - "checkInbox": "Bitte ΓΌberprΓΌfe deinen Posteingang.", - "resendVerification": "Erneut senden", - "notVerifiedError": "E-Mail noch nicht bestΓ€tigt", - "resendVerificationPrompt": "BestΓ€tigungs-E-Mail erneut senden?" -} -``` - -### Fehlende Auth Pages - -**Commit:** `df2c518a` - feat(auth): add missing auth pages for zitare and planta - -| App | Login | Register | Forgot Password | -|-----|-------|----------|-----------------| -| Zitare | βœ… Neu | βœ… Vorhanden | βœ… Neu | -| Planta | βœ… Vorhanden | βœ… Refactored | βœ… Neu | - ---- - -## 7. SSD Migration - -### Motivation - -Docker volumes liegen auf der internen SSD des Mac Mini (begrenzt auf 256GB). Externe 4TB SSD bietet mehr KapazitΓ€t und bessere Backup-MΓΆglichkeiten. - -### Migrierte Services - -**Commits:** `1c650589`, `6ca2d3b7`, `7d7e31e4` - -```yaml -# docker-compose.macmini.yml -services: - postgres: - volumes: - - /Volumes/ManaData/postgres:/var/lib/postgresql/data - - minio: - volumes: - - /Volumes/ManaData/minio:/data -``` - -### Vergleich - -| Aspekt | Docker Volume | SSD Bind Mount | -|--------|---------------|----------------| -| Pfad | `/var/lib/docker/volumes/...` | `/Volumes/ManaData/...` | -| Backup | Docker Export erforderlich | Direkter rsync/cp | -| Grâße | Begrenzt (256GB System SSD) | 4TB verfΓΌgbar | -| Geschwindigkeit | ~500 MB/s | ~500 MB/s (extern) | -| PortabilitΓ€t | Docker-spezifisch | Standard-Dateisystem | - -### Dokumentation - -**Commit:** `9e9db590` - docs: update SSD documentation for ManaData volume - -- Umbenennung: TillJakob-S04 β†’ ManaData -- Docker Full Disk Access Requirement dokumentiert -- Backup-Skript-Pfade aktualisiert - ---- - -## 8. mana-core-auth Production Readiness - -### Übersicht - -VollstΓ€ndige Production-Readiness fΓΌr den zentralen Auth-Service. - -**Commit:** `efb077b9` - fix(mana-core-auth): use EdDSA for OIDC id_token signing - -### Neue Features - -#### LoggerService -```typescript -// src/common/logger/logger.service.ts -@Injectable() -export class LoggerService implements LoggerService { - private readonly context: string; - - constructor(@Inject('LOGGER_CONTEXT') context?: string) { - this.context = context || 'Application'; - } - - log(message: string, context?: string) { - console.log(`[${context || this.context}] ${message}`); - } - - error(message: string, trace?: string, context?: string) { - console.error(`[${context || this.context}] ${message}`, trace); - } -} -``` - -#### Environment Validation -```typescript -// src/config/env.validation.ts -import { plainToInstance, Type } from 'class-transformer'; -import { IsString, IsNumber, IsUrl, validateSync } from 'class-validator'; - -export class EnvironmentVariables { - @IsUrl() - BASE_URL: string; - - @IsString() - DATABASE_URL: string; - - @IsNumber() - @Type(() => Number) - PORT: number = 3001; - - @IsString() - JWT_SECRET: string; - - // ... weitere Validierungen -} - -export function validate(config: Record) { - const validated = plainToInstance(EnvironmentVariables, config); - const errors = validateSync(validated); - if (errors.length > 0) { - throw new Error(`Config validation error: ${errors}`); - } - return validated; -} -``` - -#### Health Endpoints - -```typescript -// src/health/health.controller.ts -@Controller('health') -export class HealthController { - @Get() - health() { - return { status: 'ok', timestamp: new Date().toISOString() }; - } - - @Get('live') - liveness() { - return { status: 'ok' }; - } - - @Get('ready') - async readiness() { - const dbOk = await this.checkDatabase(); - const redisOk = await this.checkRedis(); - - if (!dbOk || !redisOk) { - throw new ServiceUnavailableException('Not ready'); - } - - return { - status: 'ok', - checks: { database: dbOk, redis: redisOk }, - }; - } -} -``` - -### E2E Tests - -**Commits:** `ab49be0b` - -| Test Suite | Tests | Beschreibung | -|------------|-------|--------------| -| `auth-flow.e2e-spec.ts` | 15 | Register, Login, Logout, Token Refresh | -| `oidc.e2e-spec.ts` | 12 | OIDC Discovery, Authorization, Token Exchange | - -```typescript -// test/e2e/auth-flow.e2e-spec.ts -describe('Auth Flow', () => { - it('should register new user', async () => { - const response = await request(app.getHttpServer()) - .post('/api/v1/auth/register') - .send({ email: 'test@example.com', password: 'secure123', name: 'Test' }) - .expect(201); - - expect(response.body).toHaveProperty('user'); - expect(response.body.user.email).toBe('test@example.com'); - }); - - it('should login and receive tokens', async () => { - const response = await request(app.getHttpServer()) - .post('/api/v1/auth/login') - .send({ email: 'test@example.com', password: 'secure123' }) - .expect(200); - - expect(response.body).toHaveProperty('accessToken'); - expect(response.body).toHaveProperty('refreshToken'); - }); -}); -``` - -### Dokumentation - -Neue Docs erstellt: -- `docs/PRODUCTION_DEPLOYMENT.md` - Deployment Guide -- `docs/DISASTER_RECOVERY.md` - Backup & Recovery Procedures - ---- - -## 9. Matrix Bots Credit Integration - -### CreditModule in bot-services - -**Commit:** `dc0d425f` - feat(bot-services): add CreditModule - -```typescript -// packages/bot-services/src/credit/credit.module.ts -@Module({ - providers: [CreditService], - exports: [CreditService], -}) -export class CreditModule { - static forRoot(options: CreditModuleOptions): DynamicModule { - return { - module: CreditModule, - providers: [ - { provide: 'CREDIT_OPTIONS', useValue: options }, - CreditService, - ], - exports: [CreditService], - }; - } -} -``` - -```typescript -// packages/bot-services/src/credit/credit.service.ts -@Injectable() -export class CreditService { - constructor( - @Inject('CREDIT_OPTIONS') private options: CreditModuleOptions, - private httpService: HttpService, - ) {} - - async hasCredits(userId: string, amount: number): Promise { - const balance = await this.getBalance(userId); - return balance >= amount; - } - - async consumeCredits( - userId: string, - operation: string, - amount: number, - ): Promise { - await this.httpService.post(`${this.options.authUrl}/api/v1/credits/consume`, { - userId, - operation, - amount, - }); - } -} -``` - -### Bot Integration - -19 Bots mit Credit Support: - -```typescript -// services/matrix-todo-bot/src/bot/matrix.service.ts -@Injectable() -export class MatrixService extends BaseMatrixService { - constructor(private creditService: CreditService) { - super(); - } - - protected async handleTextMessage(roomId: string, event: MatrixRoomEvent, message: string) { - const userId = event.sender; - - // Check credits before AI operations - if (this.isAiCommand(message)) { - const hasCredits = await this.creditService.hasCredits(userId, 5); - if (!hasCredits) { - await this.sendMessage(roomId, '❌ Nicht genug Credits fΓΌr AI-Features.'); - return; - } - } - - // Process command... - - // Consume credits after success - if (this.isAiCommand(message)) { - await this.creditService.consumeCredits(userId, 'todo:ai-breakdown', 5); - } - } -} -``` - ---- - -## 10. Weitere Γ„nderungen - -### Calendar Cross-App API URLs - -**Commit:** `9a22c898` - fix(calendar-web): inject cross-app API URLs for client-side - -```typescript -// apps/calendar/apps/web/src/hooks.server.ts -export const handle: Handle = async ({ event, resolve }) => { - const response = await resolve(event, { - transformPageChunk: ({ html }) => { - return html.replace( - '', - `` - ); - }, - }); - return response; -}; -``` - -### Project-Doc-Bot tsconfig Fix - -**Commit:** `a7c1908f` - fix(project-doc-bot): add include/exclude to tsconfig - -```json -// services/matrix-project-doc-bot/tsconfig.json -{ - "compilerOptions": { - "outDir": "./dist", - "rootDir": "./src" - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] -} -``` - -**Problem:** Build output war `dist/src/main.js` statt `dist/main.js`. - ---- - -## Architektur-Diagramm - -### Auth & SSO Flow - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ User Request β”‚ -β”‚ calendar.mana.how/events β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Check Cookie β”‚ - β”‚ (.mana.how domain) β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ β”‚ - β–Ό β–Ό - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Cookie Found β”‚ β”‚ No Cookie β”‚ - β”‚ β”‚ β”‚ β”‚ - β”‚ Validate JWT β”‚ β”‚ Redirect to β”‚ - β”‚ via JWKS β”‚ β”‚ auth.mana.how β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β”‚ - β–Ό β–Ό - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ JWT Valid β”‚ β”‚ Login Page β”‚ - β”‚ β”‚ β”‚ β”‚ - β”‚ Return Data β”‚ β”‚ Set Cookie: β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ domain=.mana.howβ”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Redirect back β”‚ - β”‚ to calendar β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Credit System Architecture - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Client Apps β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Chat Web β”‚ β”‚ Picture β”‚ β”‚ Matrix Bot β”‚ β”‚ Mobile β”‚ β”‚ -β”‚ β”‚ (Svelte) β”‚ β”‚ (Svelte) β”‚ β”‚ (NestJS) β”‚ β”‚ (Expo) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ @manacore/shared-credit-ui β”‚ -β”‚ CreditBalance, CreditToast β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Backend Services β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ @manacore/credit-operations β”‚ β”‚ -β”‚ β”‚ getCreditCost(), CREDIT_OPERATIONS β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ @mana-core/nestjs-integration β”‚ β”‚ -β”‚ β”‚ @UseCredits(), CreditInterceptor, AuthGuard β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ mana-core-auth β”‚ -β”‚ (Port 3001) β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ /credits/ β”‚ β”‚ /credits/ β”‚ β”‚ PostgreSQL β”‚ β”‚ -β”‚ β”‚ balance β”‚ β”‚ consume β”‚ β”‚ user_credits table β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - ---- - -## Statistiken - -| Metrik | Wert | -|--------|------| -| **Commits** | 51 | -| **Session-Dauer** | 19 Stunden | -| **Neue Packages** | 2 (credit-operations, shared-credit-ui) | -| **CI/CD Bots** | 10 | -| **Auth Pages aktualisiert** | 15 | -| **E2E Tests hinzugefΓΌgt** | 27 | -| **Grafana Dashboards** | 3 (Master, System, Auth) | -| **Prometheus Alerts** | 10 | -| **SSD-migrierte Services** | 2 (PostgreSQL, MinIO) | - ---- - -## Bekannte Issues - -1. **Matrix Bot arm64** - Keine arm64 Builds wegen QEMU/Native Module Issues -2. **E2EE deaktiviert** - Matrix Bots haben kein End-to-End Encryption (Server handles it) -3. **Docker Full Disk Access** - Muss manuell in Docker Desktop konfiguriert werden - ---- - -## NΓ€chste Schritte - -1. **Credit System UI** - Balance-Anzeige in allen Web-Apps integrieren -2. **Rate Limiting** - FΓΌr Auth-Endpoints implementieren -3. **Backup Automation** - Scheduled Backups fΓΌr PostgreSQL/MinIO auf SSD -4. **Bot Healthchecks** - Grafana Alerts fΓΌr Bot-AusfΓ€lle -5. **OIDC fΓΌr weitere Apps** - Skilltree, Questions mit Matrix SSO - ---- - -*Bericht erstellt am 2. Februar 2026, 15:00 Uhr* diff --git a/docs/ENV_AUDIT_SUMMARY.md b/docs/ENV_AUDIT_SUMMARY.md deleted file mode 100644 index 69c143cf2..000000000 --- a/docs/ENV_AUDIT_SUMMARY.md +++ /dev/null @@ -1,184 +0,0 @@ -# Environment Audit - Quick Summary - -## Issues Found: 8 Critical/Major Items - -### BLOCKING (Fix immediately - prevent simultaneous backend execution) - -**Port Conflicts:** - -``` -Port 3002: Chat (3002) ← β†’ Nutriphi (3002) [CONFLICT] -Port 3003: Picture (3003) ← β†’ Maerchenzauber (3003) [CONFLICT] -``` - -**Hardcoded Values:** - -- Chat backend hardcodes DEV_USER_ID instead of reading from env - -### MAJOR (Inconsistencies across codebase) - -**Auth URL Variable Names (Choose One):** - -- Chat: MANA_CORE_AUTH_URL βœ“ -- Picture: MANA_CORE_AUTH_URL βœ“ -- Zitare: MANA_CORE_AUTH_URL βœ“ -- Presi: MANA_CORE_AUTH_URL βœ“ -- **Manadeck: MANA_SERVICE_URL** ← Should standardize -- **Nutriphi: MANACORE_AUTH_URL** ← Should standardize - -**CORS Origins:** - -- Hardcoded in 4 backends (Chat, Picture, Zitare, Presi) -- Should use CORS_ORIGINS from environment - -**Missing Documentation:** - -- No .env.example for Zitare backend -- No .env.example for Presi backend - -### MEDIUM (Code quality) - -**Validation Schemas:** - -- Chat: Missing -- Picture: Missing -- Zitare: Missing -- Presi: Missing -- Manadeck: βœ“ Has validation schema -- Mana-Core-Auth: βœ“ Has validation config - ---- - -## Quick Fix Checklist - -### Phase 1: Critical (1-2 hours) - -- [ ] Reassign Picture from port 3003 β†’ 3005 -- [ ] Reassign Nutriphi from port 3002 β†’ 3006 -- [ ] Add DEV_USER_ID to .env.development -- [ ] Update Chat to load DEV_USER_ID from ConfigService - -### Phase 2: Major (2-3 hours) - -- [ ] Rename MANA_SERVICE_URL to MANA_CORE_AUTH_URL in Manadeck -- [ ] Rename MANACORE_AUTH_URL to MANA_CORE_AUTH_URL in Nutriphi -- [ ] Create .env.example for Zitare -- [ ] Create .env.example for Presi - -### Phase 3: Quality (3-4 hours) - -- [ ] Add validation schemas to Chat, Picture, Zitare, Presi -- [ ] Extract CORS origins to environment variables -- [ ] Update all backends to read CORS_ORIGINS from env - ---- - -## Port Mapping (Current vs Recommended) - -``` -Current: Recommended: -3001 ← Mana Core Auth β†’ 3001 ← Mana Core Auth -3002 ← Chat β†’ 3002 ← Chat -3002 ← Nutriphi [X] β†’ 3006 ← Nutriphi [FIXED] -3003 ← Maerchenzauber β†’ 3003 ← Maerchenzauber -3003 ← Picture [X] β†’ 3005 ← Picture [FIXED] -3004 ← Manadeck β†’ 3004 ← Manadeck -3007 ← Zitare β†’ 3007 ← Zitare -3008 ← Presi β†’ 3008 ← Presi -3010 ← Voxel Lava β†’ 3010 ← Voxel Lava -3011 ← Mana Games β†’ 3011 ← Mana Games -``` - ---- - -## Environment Variables Status - -### Well-Configured - -- MANA_CORE_AUTH_URL (central + mapped) -- JWT keys (central) -- API keys (central) -- Database URLs (individual + mapped) - -### Needs Work - -- DEV_USER_ID (hardcoded, not in env) -- DEV_BYPASS_AUTH (partial, only Chat) -- CORS_ORIGINS (hardcoded, not used by all) -- Auth URL naming (3 different conventions) - ---- - -## Files to Modify - -### .env.development - -- [ ] Add DEV_USER_ID line -- [ ] Fix PICTURE_BACKEND_PORT (3003 β†’ 3005) -- [ ] Fix NUTRIPHI_BACKEND_PORT (3002 β†’ 3006) - -### scripts/generate-env.mjs - -- [ ] Line 205: MANA_SERVICE_URL β†’ MANA_CORE_AUTH_URL (Manadeck) -- [ ] Line 272: MANACORE_AUTH_URL β†’ MANA_CORE_AUTH_URL (Nutriphi) - -### Backend Apps (4 files each) - -- [ ] apps/chat/apps/backend/src/config/validation.schema.ts (create) -- [ ] apps/picture/apps/backend/src/config/validation.schema.ts (create) -- [ ] apps/zitare/apps/backend/src/config/validation.schema.ts (create) -- [ ] apps/presi/apps/backend/src/config/validation.schema.ts (create) - -### Backend Main Files (4 files) - -- [ ] apps/chat/apps/backend/src/main.ts (extract CORS) -- [ ] apps/picture/apps/backend/src/main.ts (extract CORS) -- [ ] apps/zitare/apps/backend/src/main.ts (extract CORS) -- [ ] apps/presi/apps/backend/src/main.ts (extract CORS) - -### Backend Examples (2 files) - -- [ ] apps/zitare/apps/backend/.env.example (create) -- [ ] apps/presi/apps/backend/.env.example (create) - -### Chat Guard - -- [ ] apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts - - Remove hardcoded DEV_USER_ID - - Read from configService instead - ---- - -## Testing After Fixes - -```bash -# Test all 10 backends can start simultaneously -pnpm dev:auth & -pnpm dev:chat:backend & -pnpm dev:manadeck:backend & -pnpm dev:picture:backend & -pnpm dev:zitare:backend & -pnpm dev:presi:backend & - -# Verify each responds -curl http://localhost:3001/health -curl http://localhost:3002/api/health -curl http://localhost:3003/api/health # Maerchenzauber -curl http://localhost:3004/v1/health # Manadeck -curl http://localhost:3005/api/health # Picture (new port) -curl http://localhost:3007/api/health # Zitare -curl http://localhost:3008/api/health # Presi -``` - ---- - -## Additional Docs - -See full audit report: `/docs/ENV_CONFIGURATION_AUDIT.md` - -Key sections: - -- Environment Variable Mapping (section 3) -- Hardcoded Values & Security (section 4) -- Configuration Best Practices (section 5) -- Implementation Checklist (section 10) diff --git a/docs/ENV_BACKEND_MATRIX.md b/docs/ENV_BACKEND_MATRIX.md deleted file mode 100644 index 31263f6f8..000000000 --- a/docs/ENV_BACKEND_MATRIX.md +++ /dev/null @@ -1,236 +0,0 @@ -# Environment Variable Configuration Matrix - -## Backend Authentication & Port Status - -``` -╔══════════════════╦════════╦═══════════════════════╦═════════════════════╦═══════════════╗ -β•‘ Backend β•‘ Port β•‘ Auth URL Variable β•‘ Dev Bypass β•‘ Validation β•‘ -╠══════════════════╬════════╬═══════════════════════╬═════════════════════╬═══════════════╣ -β•‘ Mana Core Auth β•‘ 3001 β•‘ N/A (Auth service) β•‘ N/A β•‘ βœ“ Config svc β•‘ -β•‘ Chat β•‘ 3002 β•‘ MANA_CORE_AUTH_URL β•‘ βœ“ Implemented β•‘ βœ— Missing β•‘ -β•‘ Maerchenzauber β•‘ 3003 β•‘ MANA_SERVICE_URL β•‘ ? Unknown β•‘ ? Unknown β•‘ -β•‘ Manadeck β•‘ 3004 β•‘ MANA_SERVICE_URL β•‘ ? Unknown β•‘ βœ“ Joi schema β•‘ -β•‘ Picture β•‘ 3003 β•‘ MANA_CORE_AUTH_URL β•‘ βœ— Missing β•‘ βœ— Missing β•‘ -β•‘ Nutriphi β•‘ 3002 β•‘ MANACORE_AUTH_URL β•‘ ? Unknown β•‘ ? Unknown β•‘ -β•‘ Zitare β•‘ 3007 β•‘ MANA_CORE_AUTH_URL β•‘ βœ— Missing β•‘ βœ— Missing β•‘ -β•‘ Presi β•‘ 3008 β•‘ MANA_CORE_AUTH_URL β•‘ βœ— Missing β•‘ βœ— Missing β•‘ -β•‘ Voxel Lava β•‘ 3010 β•‘ ? Not checked β•‘ ? Unknown β•‘ ? Unknown β•‘ -β•‘ Mana Games β•‘ 3011 β•‘ ? Not checked β•‘ ? Unknown β•‘ ? Unknown β•‘ -β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• -``` - -Legend: - -- βœ“ = Implemented/Present -- βœ— = Missing/Not implemented -- ? = Not analyzed in this audit -- Port conflicts highlighted in red - ---- - -## Database URL Configuration - -``` -╔══════════════════╦════════════════════════════════════════════════╦════════════════╗ -β•‘ Backend β•‘ Database URL Variable β•‘ Generated β•‘ -╠══════════════════╬════════════════════════════════════════════════╬════════════════╣ -β•‘ Mana Core Auth β•‘ MANA_CORE_AUTH_DATABASE_URL β•‘ βœ“ via gen-env β•‘ -β•‘ Chat β•‘ CHAT_DATABASE_URL β•‘ βœ“ via gen-env β•‘ -β•‘ Manadeck β•‘ MANADECK_DATABASE_URL β•‘ βœ“ via gen-env β•‘ -β•‘ Picture β•‘ PICTURE_DATABASE_URL β•‘ βœ“ via gen-env β•‘ -β•‘ Nutriphi β•‘ NUTRIPHI_DATABASE_URL β•‘ βœ“ via gen-env β•‘ -β•‘ Zitare β•‘ ZITARE_DATABASE_URL β•‘ βœ“ via gen-env β•‘ -β•‘ Presi β•‘ PRESI_DATABASE_URL β•‘ βœ“ via gen-env β•‘ -β•‘ Voxel Lava β•‘ VOXEL_LAVA_DATABASE_URL β•‘ βœ“ via gen-env β•‘ -β•‘ Mana Games β•‘ None specified β•‘ N/A β•‘ -β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• -``` - ---- - -## CORS Configuration Status - -``` -╔══════════════════╦═══════════════════════════════════╦═════════════════════════════════╗ -β•‘ Backend β•‘ CORS Implementation β•‘ Recommendation β•‘ -╠══════════════════╬═══════════════════════════════════╬═════════════════════════════════╣ -β•‘ Chat β•‘ Hardcoded array in main.ts β•‘ Move to CORS_ORIGINS env var β•‘ -β•‘ Picture β•‘ Hardcoded array in main.ts β•‘ Move to CORS_ORIGINS env var β•‘ -β•‘ Zitare β•‘ Hardcoded array in main.ts β•‘ Move to CORS_ORIGINS env var β•‘ -β•‘ Presi β•‘ Hardcoded array in main.ts β•‘ Move to CORS_ORIGINS env var β•‘ -β•‘ Manadeck β•‘ configService.get('FRONTEND_URL') β•‘ Already using env var (better) β•‘ -β•‘ Mana Core Auth β•‘ configService array β•‘ Already using env var (good) β•‘ -β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• -``` - -Current hardcoded CORS allowed origins (should be environment variable): - -```javascript -// In 4 backends -const allowedOrigins = [ - 'http://localhost:3000', - 'http://localhost:5173', // Primary web dev port - 'http://localhost:5174', // Secondary web port - 'http://localhost:5175', // Tertiary web port - 'http://localhost:5177', // Zitare web - 'http://localhost:5178', // Chat web / Presi web - 'http://localhost:8081', // Expo dev server - 'exp://localhost:8081', // Expo protocol - 'http://localhost:3001', // Mana Core Auth -]; -``` - ---- - -## Port Availability & Conflicts - -``` -Port 3000 ━━━━━━━━ [FREE] -Port 3001 ━━━━━━━━ Mana Core Auth (ACTIVE) -Port 3002 ━━━━━━━━ Chat (ACTIVE) + Nutriphi (ACTIVE) ⚠ CONFLICT! - ↓ - 3002a Chat - 3002b Nutriphi (should be 3006) -Port 3003 ━━━━━━━━ Maerchenzauber (ACTIVE) + Picture (ACTIVE) ⚠ CONFLICT! - ↓ - 3003a Maerchenzauber - 3003b Picture (should be 3005) -Port 3004 ━━━━━━━━ Manadeck (ACTIVE) -Port 3005 ━━━━━━━━ [AVAILABLE] ← Assign to Picture -Port 3006 ━━━━━━━━ [AVAILABLE] ← Assign to Nutriphi -Port 3007 ━━━━━━━━ Zitare (ACTIVE) -Port 3008 ━━━━━━━━ Presi (ACTIVE) -Port 3009 ━━━━━━━━ [RESERVED - mentioned in CLAUDE.md] -Port 3010 ━━━━━━━━ Voxel Lava (ACTIVE) -Port 3011 ━━━━━━━━ Mana Games (ACTIVE) -``` - ---- - -## Environment Variable Generation Map - -### From .env.development to Backend .env Files - -``` -MANA_CORE_AUTH_PORT (3001) - ↓ (generate-env.mjs line 61) - β”œβ†’ services/mana-core-auth/.env {PORT} - -CHAT_BACKEND_PORT (3002) - ↓ (generate-env.mjs line 89) - β”œβ†’ apps/chat/apps/backend/.env {PORT} - -MANA_CORE_AUTH_URL (http://localhost:3001) - ↓ (generate-env.mjs multiple lines) - β”œβ†’ apps/chat/apps/backend/.env {MANA_CORE_AUTH_URL} - β”œβ†’ apps/picture/apps/backend/.env {MANA_CORE_AUTH_URL} - β”œβ†’ apps/zitare/apps/backend/.env {MANA_CORE_AUTH_URL} - β”œβ†’ apps/presi/apps/backend/.env {MANA_CORE_AUTH_URL} - β”œβ†’ apps/manadeck/apps/backend/.env {MANA_SERVICE_URL} ← NAMING INCONSISTENCY - β””β†’ apps/nutriphi/apps/backend/.env {MANACORE_AUTH_URL} ← NAMING INCONSISTENCY - -CORS_ORIGINS (http://localhost:3000,http://localhost:3002,...) - ↓ (generate-env.mjs line 75, 136, 232, 301, 332, 372) - β”œβ†’ services/mana-core-auth/.env {CORS_ORIGINS} - β”œβ†’ apps/maerchenzauber/apps/backend/.env {CORS_ORIGINS} - β”œβ†’ apps/picture/apps/backend/.env {CORS_ORIGINS} - β”œβ†’ apps/zitare/apps/backend/.env {CORS_ORIGINS} - β”œβ†’ apps/presi/apps/backend/.env {CORS_ORIGINS} - β””β†’ games/mana-games/apps/backend/.env {CORS_ORIGINS} - [BUT NOT USED by Chat, Picture, Zitare, Presi - they hardcode instead!] -``` - ---- - -## Issues Severity Matrix - -``` -╔═══════════════╦════════════════════════════════════════════════╦══════════════════╗ -β•‘ Severity β•‘ Count β•‘ Issue Description β•‘ Time to Fix β•‘ -╠═══════════════╬═══════╬═════════════════════════════════════════╬══════════════════╣ -β•‘ BLOCKING β•‘ 2 β•‘ Port conflicts (3002, 3003) β•‘ 15 minutes β•‘ -β•‘ β•‘ 1 β•‘ Hardcoded DEV_USER_ID β•‘ 30 minutes β•‘ -╠═══════════════╬═══════╬═════════════════════════════════════════╬══════════════════╣ -β•‘ MAJOR β•‘ 3 β•‘ Auth URL naming inconsistencies β•‘ 30 minutes β•‘ -β•‘ β•‘ 4 β•‘ Hardcoded CORS origins β•‘ 1-2 hours β•‘ -β•‘ β•‘ 2 β•‘ Missing .env.example files β•‘ 15 minutes β•‘ -╠═══════════════╬═══════╬═════════════════════════════════════════╬══════════════════╣ -β•‘ MEDIUM β•‘ 4 β•‘ Missing validation schemas β•‘ 2-3 hours β•‘ -β•‘ β•‘ 1 β•‘ Dev bypass auth inconsistency β•‘ 1-2 hours β•‘ -╠═══════════════╬═══════╬═════════════════════════════════════════╬══════════════════╣ -β•‘ TOTAL β•‘ 17 β•‘ All issues identified β•‘ 6-8 hours total β•‘ -β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• -``` - ---- - -## Configuration Best Practices Scorecard - -``` -╔════════════════════════════════════╦═════════════════════════════════════════╗ -β•‘ Criteria β•‘ Score (0-10) β•‘ -╠════════════════════════════════════╬═════════════════════════════════════════╣ -β•‘ Port Assignment Uniqueness β•‘ 4/10 (2 conflicts found) β•‘ -β•‘ Environment Variable Standardizationβ•‘ 6/10 (3 naming conventions) β•‘ -β•‘ Configuration Documentation β•‘ 5/10 (3 missing .env.example files) β•‘ -β•‘ Centralized Environment Setup β•‘ 8/10 (good but some backends override) β•‘ -β•‘ Configuration Validation β•‘ 3/10 (only 2/8 backends have schemas) β•‘ -β•‘ Hardcoded Values β•‘ 4/10 (CORS + DEV_USER_ID hardcoded) β•‘ -β•‘ Auth Configuration Consistency β•‘ 4/10 (4 different variable names) β•‘ -β•‘ Security (no secrets in source) β•‘ 7/10 (mostly good, except DEV_USER_ID) β•‘ -╠════════════════════════════════════╬═════════════════════════════════════════╣ -β•‘ OVERALL SCORE β•‘ 5.1/10 (NEEDS IMPROVEMENT) β•‘ -β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• -``` - -**To reach 8/10:** Fix blocking issues + add missing validation schemas -**To reach 9/10:** + Move all CORS to environment + Standardize auth URLs -**To reach 10/10:** + Complete documentation + Consistent dev bypass pattern across all - ---- - -## Quick Reference: Variable Name Standardization - -### Current (Inconsistent) - -``` -Chat: MANA_CORE_AUTH_URL -Picture: MANA_CORE_AUTH_URL -Zitare: MANA_CORE_AUTH_URL -Presi: MANA_CORE_AUTH_URL -Manadeck: MANA_SERVICE_URL ← Different! -Nutriphi: MANACORE_AUTH_URL ← Different! -``` - -### Recommended (Consistent) - -``` -All backends: MANA_CORE_AUTH_URL ← Standardized -``` - -### Migration Path - -1. Add MANA_CORE_AUTH_URL to .env.development (already exists!) -2. Update generate-env.mjs: - - Line 205: Change `MANA_SERVICE_URL` to `MANA_CORE_AUTH_URL` (Manadeck) - - Line 272: Change `MANACORE_AUTH_URL` to `MANA_CORE_AUTH_URL` (Nutriphi) -3. Update app.module.ts files if they reference old variable name -4. Update config/validation.schema.ts files if applicable -5. Test `pnpm setup:env` generates correct variables -6. Verify all backends read MANA_CORE_AUTH_URL - ---- - -## Next Steps - -1. **Read the full audit:** `/docs/ENV_CONFIGURATION_AUDIT.md` -2. **Follow the checklist:** `/docs/ENV_AUDIT_SUMMARY.md` -3. **Review this matrix:** You are here! -4. **Implement fixes:** Start with Phase 1 (blocking issues) -5. **Test & verify:** Run all backends simultaneously -6. **Document results:** Update CLAUDE.md with final port assignments - ---- - -Generated: December 1, 2025 -Auditor: Environment Configuration Auditor Agent (Claude Flow Swarm) diff --git a/docs/ENV_CONFIGURATION_AUDIT.md b/docs/ENV_CONFIGURATION_AUDIT.md deleted file mode 100644 index 5f625419d..000000000 --- a/docs/ENV_CONFIGURATION_AUDIT.md +++ /dev/null @@ -1,423 +0,0 @@ -# Environment Configuration Audit Report - -## Mana Universe Monorepo - Backend Authentication & Configuration - -**Date:** December 1, 2025 -**Auditor:** Environment Configuration Auditor Agent -**Scope:** All NestJS backends and mana-core-auth service - ---- - -## EXECUTIVE SUMMARY - -The monorepo has **CRITICAL PORT CONFLICTS** that will prevent multiple backends from running simultaneously. Additionally, there are inconsistencies in environment variable naming conventions across backends and missing configuration examples for some projects. - -**Status:** NEEDS IMMEDIATE ACTION - -- 2 port conflicts identified -- 3 naming convention inconsistencies -- 5 backends missing .env.example files -- Hardcoded CORS origins in multiple backends - ---- - -## 1. PORT ASSIGNMENT MATRIX - -### Current Assignments (from .env.development) - -| Backend | Port | Env Variable | Status | Conflict | -| ------------------ | -------- | --------------------------- | ----------- | -------- | -| Mana Core Auth | 3001 | MANA_CORE_AUTH_PORT | βœ“ Unique | No | -| Chat | 3002 | CHAT_BACKEND_PORT | βœ“ Unique | No | -| **Maerchenzauber** | **3003** | MAERCHENZAUBER_BACKEND_PORT | ⚠ CONFLICT | **Yes** | -| Manadeck | 3004 | MANADECK_BACKEND_PORT | βœ“ Unique | No | -| **Picture** | **3003** | PICTURE_BACKEND_PORT | ⚠ CONFLICT | **Yes** | -| **Nutriphi** | **3002** | NUTRIPHI_BACKEND_PORT | ⚠ CONFLICT | **Yes** | -| Zitare | 3007 | ZITARE_BACKEND_PORT | βœ“ Unique | No | -| Presi | 3008 | PRESI_BACKEND_PORT | βœ“ Unique | No | -| Mana Games | 3011 | MANA_GAMES_BACKEND_PORT | βœ“ Unique | No | -| Voxel Lava | 3010 | VOXEL_LAVA_BACKEND_PORT | βœ“ Unique | No | - -### PORT CONFLICTS FOUND - -1. **Port 3003 - DOUBLE ASSIGNED** - - Maerchenzauber Backend: `MAERCHENZAUBER_BACKEND_PORT=3003` - - Picture Backend: `PICTURE_BACKEND_PORT=3003` - -2. **Port 3002 - DOUBLE ASSIGNED** - - Chat Backend: `CHAT_BACKEND_PORT=3002` - - Nutriphi Backend: `NUTRIPHI_BACKEND_PORT=3002` - -### RECOMMENDATION - -Reassign conflicting ports: - -- Maerchenzauber: Keep 3003, reassign Picture to **3005** or **3006** -- OR reassign Maerchenzauber to **3005** and keep Picture at 3003 -- Nutriphi: Reassign to **3006** or another available port -- Mana Games: Currently 3011 -- Voxel Lava: Currently 3010 - ---- - -## 2. AUTH ENVIRONMENT VARIABLES AUDIT - -### Central Configuration (.env.development) - -**PRESENT & CONFIGURED:** - -- βœ“ `MANA_CORE_AUTH_URL=http://localhost:3001` (Line 16) -- βœ“ `DEV_BYPASS_AUTH=true` (Line 59 - Chat only) -- βœ“ JWT_PRIVATE_KEY & JWT_PUBLIC_KEY (Lines 19-20) -- βœ“ CORS_ORIGINS=... (Line 41) - -**MISSING CENTRALIZED:** - -- βœ— `DEV_USER_ID` - NOT in .env.development - - Used hardcoded in Chat: `17cb0be7-058a-4964-9e18-1fe7055fd014` - - Should be centralized in .env.development - -- βœ— `MANA_CORE_SERVICE_KEY` - NOT found in generate-env.mjs mapping - - Defined for Manadeck in .env.example - - Not passed to backends via generator - -### Backend-Specific Auth Configuration - -| Backend | Auth URL Var | Dev Bypass | Dev User ID | Status | -| ------------ | ------------------ | ------------------- | ------------- | --------------- | -| **Chat** | MANA_CORE_AUTH_URL | βœ“ Configured | βœ— Hardcoded | ⚠ Partially | -| **Picture** | MANA_CORE_AUTH_URL | βœ— Missing | βœ— Not checked | βœ— Incomplete | -| **Zitare** | MANA_CORE_AUTH_URL | βœ— Missing | βœ— Not checked | βœ— Incomplete | -| **Presi** | MANA_CORE_AUTH_URL | βœ— Missing | βœ— Not checked | βœ— Incomplete | -| **Manadeck** | MANA_SERVICE_URL | βœ— Not in generation | βœ— Not mapped | βœ— Not generated | - -### ISSUE: Naming Convention Inconsistency - -Different backends use DIFFERENT variable names for the same thing: - -``` -INCONSISTENT: -- Chat uses: MANA_CORE_AUTH_URL (from generate-env.mjs line 95) -- Picture uses: MANA_CORE_AUTH_URL (from generate-env.mjs line 230) -- Zitare uses: MANA_CORE_AUTH_URL (from generate-env.mjs line 300) -- Presi uses: MANA_CORE_AUTH_URL (from generate-env.mjs line 330) - -- Manadeck uses: MANA_SERVICE_URL (from generate-env.mjs line 205) -- Manadeck uses: APP_ID (from generate-env.mjs line 206) - -- Nutriphi uses: MANACORE_AUTH_URL (from generate-env.mjs line 272) -``` - -**STANDARDIZATION NEEDED:** -All backends should use consistent naming: - -- Recommend: `MANA_CORE_AUTH_URL` (most common) - ---- - -## 3. ENVIRONMENT VARIABLE MAPPING AUDIT - -### Generate-env.mjs Coverage Analysis - -| Backend | .env.example | generate-env.mjs | .env Generated | Coverage | -| -------------- | ------------ | ---------------- | --------------- | ------------------ | -| Chat | βœ“ Exists | βœ“ Lines 85-98 | βœ“ Will generate | βœ“ Complete | -| Picture | βœ“ Exists | βœ“ Lines 223-243 | βœ“ Will generate | βœ“ Complete | -| Manadeck | βœ“ Exists | βœ“ Lines 199-209 | βœ“ Will generate | βœ“ Complete | -| **Zitare** | βœ— Missing | βœ“ Lines 294-303 | βœ“ Will generate | ⚠ Missing example | -| **Presi** | βœ— Missing | βœ“ Lines 323-334 | βœ“ Will generate | ⚠ Missing example | -| Mana-Core-Auth | βœ“ Exists | βœ“ Lines 57-82 | βœ“ Will generate | βœ“ Complete | - -**Missing .env.example files:** - -- `/apps/zitare/apps/backend/.env.example` - Should document PORT, DATABASE_URL, MANA_CORE_AUTH_URL, CORS_ORIGINS -- `/apps/presi/apps/backend/.env.example` - Should document PORT, DATABASE_URL, MANA_CORE_AUTH_URL, JWT_PUBLIC_KEY, CORS_ORIGINS - ---- - -## 4. HARDCODED VALUES & SECURITY CONCERNS - -### Hardcoded in Source Code - -**Chat Backend** (`apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts`): - -```typescript -const DEV_USER_ID = '17cb0be7-058a-4964-9e18-1fe7055fd014'; // Line 1 -``` - -- Should be: `configService.get('DEV_USER_ID')` -- Should be in .env.development: `DEV_USER_ID=17cb0be7-058a-4964-9e18-1fe7055fd014` - -### Hardcoded CORS Origins in main.ts - -**Chat** (`src/main.ts` lines 10-18): - -```typescript -origin: [ - 'http://localhost:3000', - 'http://localhost:5173', - 'http://localhost:5174', - 'http://localhost:5178', - 'http://localhost:8081', - 'exp://localhost:8081', - 'http://localhost:3001', // Mana Core Auth -]; -``` - -**Picture** (`src/main.ts` lines 11-19): - -```typescript -const allowedOrigins = [ - 'http://localhost:3000', - 'http://localhost:5173', - 'http://localhost:5174', - 'http://localhost:5175', - 'http://localhost:8081', - 'exp://localhost:8081', - 'http://localhost:3001', -]; -``` - -**Presi** (`src/main.ts` lines 10-17): - -```typescript -origin: [ - 'http://localhost:3000', - 'http://localhost:5173', - 'http://localhost:5177', - 'http://localhost:5178', - 'http://localhost:8081', - 'exp://localhost:8081', - 'http://localhost:3001', -]; -``` - -**Zitare** (`src/main.ts` lines 10-16): - -```typescript -origin: [ - 'http://localhost:3000', - 'http://localhost:5173', - 'http://localhost:5177', - 'http://localhost:8081', - 'exp://localhost:8081', - 'http://localhost:3001', -]; -``` - -**RECOMMENDATION:** Move CORS_ORIGINS to .env.development (already exists as CORS_ORIGINS global variable, but not used by all backends) - ---- - -## 5. CONFIGURATION BEST PRACTICES COMPLIANCE - -### Configuration Module Setup - -| Backend | ConfigModule | Validation | Env File Path | Status | -| -------------- | ------------------------ | ---------------------- | ------------- | ---------- | -| Chat | βœ“ ConfigModule.forRoot() | βœ— No validation schema | `.env` | ⚠ Minimal | -| Picture | βœ“ ConfigModule.forRoot() | βœ— No validation schema | `.env` | ⚠ Minimal | -| Zitare | βœ“ ConfigModule.forRoot() | βœ— No validation schema | `.env` | ⚠ Minimal | -| Presi | βœ“ ConfigModule.forRoot() | βœ— No validation schema | `.env` | ⚠ Minimal | -| Manadeck | βœ“ ConfigModule.forRoot() | βœ“ Joi schema | `.env` | βœ“ Complete | -| Mana-Core-Auth | βœ“ ConfigModule.forRoot() | βœ“ Config service | `.env` | βœ“ Complete | - -**ISSUE:** Chat, Picture, Zitare, Presi lack validation schemas. - -**EXAMPLE (Manadeck validation.schema.ts):** - -```typescript -export const validationSchema = Joi.object({ - NODE_ENV: Joi.string().valid('development', 'production'), - PORT: Joi.number().required(), - DATABASE_URL: Joi.string().required(), - MANA_CORE_AUTH_URL: Joi.string().required(), - // ... etc -}); -``` - ---- - -## 6. CRITICAL ISSUES SUMMARY - -### BLOCKING ISSUES (Fix Immediately) - -1. **Port Conflict - 3002** - - Chat and Nutriphi both assigned to port 3002 - - Cannot run simultaneously - - **Fix:** Reassign Nutriphi to port 3006 - -2. **Port Conflict - 3003** - - Picture and Maerchenzauber both assigned to port 3003 - - Cannot run simultaneously - - **Fix:** Reassign Picture to port 3005 or Maerchenzauber to 3006 - -3. **Hardcoded Dev User ID in Chat Backend** - - `DEV_USER_ID = '17cb0be7-058a-4964-9e18-1fe7055fd014'` hardcoded in source - - Not configurable via environment - - **Fix:** Move to .env.development and load via ConfigService - -### MAJOR ISSUES (Fix Soon) - -4. **Inconsistent Auth Variable Names** - - Manadeck uses `MANA_SERVICE_URL` instead of `MANA_CORE_AUTH_URL` - - Nutriphi uses `MANACORE_AUTH_URL` (no underscore) - - **Fix:** Standardize all to `MANA_CORE_AUTH_URL` - -5. **Hardcoded CORS Origins** - - 4 backends hardcode CORS lists in main.ts - - Should use environment variables - - **Fix:** Use CORS_ORIGINS from .env.development - -6. **Missing Configuration Examples** - - Zitare and Presi lack .env.example files - - **Fix:** Create comprehensive .env.example files - -### MEDIUM ISSUES (Improve Quality) - -7. **Missing Validation Schemas** - - 4 backends lack Joi validation schemas - - No type safety for environment variables - - **Fix:** Add validation schemas to Chat, Picture, Zitare, Presi - -8. **Dev Bypass Auth Not Consistent** - - Only Chat backend has DEV_BYPASS_AUTH implemented - - Other backends may lack development bypass mechanism - - **Fix:** Add consistent development auth bypass pattern - ---- - -## 7. RECOMMENDED ACTIONS - -### Phase 1: Critical Fixes (Do First) - -```bash -# 1. Fix port conflicts in .env.development -# Change line 122: PICTURE_BACKEND_PORT=3003 β†’ PICTURE_BACKEND_PORT=3005 -# Change line 146: NUTRIPHI_BACKEND_PORT=3002 β†’ NUTRIPHI_BACKEND_PORT=3006 - -# 2. Add DEV_USER_ID to .env.development -# Add after line 59: DEV_USER_ID=17cb0be7-058a-4964-9e18-1fe7055fd014 - -# 3. Standardize auth URL naming -# Update generate-env.mjs line 272 (Nutriphi): -# MANACORE_AUTH_URL: β†’ MANA_CORE_AUTH_URL: -# Update generate-env.mjs line 205 (Manadeck): -# MANA_SERVICE_URL: β†’ MANA_CORE_AUTH_URL: -``` - -### Phase 2: Configuration Examples - -```bash -# Create missing .env.example files: -# - apps/zitare/apps/backend/.env.example -# - apps/presi/apps/backend/.env.example - -# Based on .env.development variables and backend requirements -``` - -### Phase 3: Code Quality - -```bash -# Add validation schemas to: -# - apps/chat/apps/backend/src/config/validation.schema.ts -# - apps/picture/apps/backend/src/config/validation.schema.ts -# - apps/zitare/apps/backend/src/config/validation.schema.ts -# - apps/presi/apps/backend/src/config/validation.schema.ts - -# Move CORS origins to environment: -# Update main.ts in Chat, Picture, Zitare, Presi to: -# app.enableCors({ -# origin: (configService.get('CORS_ORIGINS') || '').split(','), -# }) -``` - ---- - -## 8. UPDATED PORT ASSIGNMENTS (RECOMMENDED) - -| Backend | Recommended Port | Current | Status | -| -------------- | ---------------- | ------- | ---------- | -| Mana Core Auth | 3001 | 3001 | βœ“ Keep | -| Chat | 3002 | 3002 | βœ“ Keep | -| Maerchenzauber | 3003 | 3003 | βœ“ Keep | -| Manadeck | 3004 | 3004 | βœ“ Keep | -| Picture | **3005** | 3003 | **CHANGE** | -| Nutriphi | **3006** | 3002 | **CHANGE** | -| Zitare | 3007 | 3007 | βœ“ Keep | -| Presi | 3008 | 3008 | βœ“ Keep | -| Voxel Lava | 3010 | 3010 | βœ“ Keep | -| Mana Games | 3011 | 3011 | βœ“ Keep | - ---- - -## 9. ENVIRONMENT VARIABLE SUMMARY TABLE - -### Required for All Backends - -| Variable | Purpose | Centralized | Backend Usage | -| ------------------ | --------------------- | ------------------ | -------------------------------------- | -| NODE_ENV | Environment type | βœ“ .env.development | All | -| PORT | Server port | βœ“ Individual vars | All | -| DATABASE_URL | PostgreSQL connection | βœ“ Individual vars | Chat, Manadeck, Picture, Zitare, Presi | -| MANA_CORE_AUTH_URL | Auth service URL | βœ“ .env.development | Chat, Picture, Zitare, Presi, Manadeck | -| CORS_ORIGINS | Allowed origins | βœ“ .env.development | All (hardcoded, should use env) | - -### Optional but Recommended - -| Variable | Purpose | Centralized | Backend Usage | -| --------------- | ---------------- | ------------------ | ------------- | -| DEV_BYPASS_AUTH | Skip auth in dev | ⚠ Partial | Chat only | -| DEV_USER_ID | Dev test user | βœ— Hardcoded | Chat | -| JWT_PUBLIC_KEY | Token validation | βœ“ .env.development | Presi | - -### Backend-Specific - -| Backend | Key Variables | Centralized | -| -------------- | ------------------------------------- | ------------------ | -| Chat | GOOGLE*GENAI_API_KEY, AZURE_OPENAI*\* | βœ“ .env.development | -| Picture | REPLICATE*API_TOKEN, S3*\* vars | βœ“ .env.development | -| Zitare | (None beyond base) | βœ“ .env.development | -| Presi | (None beyond base) | βœ“ .env.development | -| Manadeck | GOOGLE_GENAI_API_KEY | βœ“ .env.development | -| Mana-Core-Auth | JWT*\*, STRIPE*_, CREDITS\__ | βœ“ .env.development | - ---- - -## 10. IMPLEMENTATION CHECKLIST - -- [ ] Fix port conflict: Picture 3003 β†’ 3005 -- [ ] Fix port conflict: Nutriphi 3002 β†’ 3006 -- [ ] Add DEV_USER_ID to .env.development -- [ ] Update Chat backend to use DEV_USER_ID from ConfigService -- [ ] Standardize MANA_SERVICE_URL to MANA_CORE_AUTH_URL in Manadeck generate-env.mjs -- [ ] Standardize MANACORE_AUTH_URL to MANA_CORE_AUTH_URL in Nutriphi generate-env.mjs -- [ ] Create .env.example for Zitare backend -- [ ] Create .env.example for Presi backend -- [ ] Add validation schemas to Chat backend config -- [ ] Add validation schemas to Picture backend config -- [ ] Add validation schemas to Zitare backend config -- [ ] Add validation schemas to Presi backend config -- [ ] Move CORS origins from hardcoded arrays to environment variables (all backends) -- [ ] Document port assignments in CLAUDE.md -- [ ] Test all backends can run simultaneously with correct ports -- [ ] Verify auth endpoint connectivity from each backend to mana-core-auth - ---- - -## AUDIT DETAILS - -**Files Reviewed:** - -- .env.development (202 lines) -- scripts/generate-env.mjs (433 lines) -- 6 backends app.module.ts files -- 5 backends main.ts files -- 3 .env.example files (Chat, Picture, Manadeck) -- 1 mana-core-auth main.ts -- Various configuration schemas and guards - -**Total Files Analyzed:** 25+ -**Lines of Code Reviewed:** 2,000+ -**Issues Identified:** 8 critical/major issues -**Port Conflicts Found:** 2 (affecting 3 backends) diff --git a/docs/MAC_MINI_DEPLOYMENT.md b/docs/MAC_MINI_DEPLOYMENT.md deleted file mode 100644 index b95ceb298..000000000 --- a/docs/MAC_MINI_DEPLOYMENT.md +++ /dev/null @@ -1,234 +0,0 @@ -# Mac Mini Deployment Guide - -Production deployment auf Mac Mini M2 via Cloudflare Tunnel. - -**Domain:** mana.how -**Tunnel ID:** bb0ea86d-8253-4a54-838b-107bb7945be9 - ---- - -## Architektur - -``` -Internet β†’ Cloudflare Tunnel β†’ Mac Mini (Docker) β†’ Apps - ↓ - mana.how β†’ localhost:5173 (Dashboard) - auth.mana.how β†’ localhost:3001 (Auth API) - chat.mana.how β†’ localhost:3000 (Chat Web) - chat-api.mana.how β†’ localhost:3002 (Chat API) - todo.mana.how β†’ localhost:5188 (Todo Web) - todo-api.mana.how β†’ localhost:3018 (Todo API) - calendar.mana.how β†’ localhost:5186 (Calendar Web) - calendar-api.mana.how β†’ localhost:3016 (Calendar API) - clock.mana.how β†’ localhost:5187 (Clock Web) - clock-api.mana.how β†’ localhost:3017 (Clock API) -``` - ---- - -## Voraussetzungen - -- Mac Mini mit Apple Silicon (ARM64) -- Docker Desktop for Mac -- Homebrew -- Cloudflared - ---- - -## Erstmaliges Setup - -### 1. Repository klonen - -```bash -mkdir -p ~/projects -cd ~/projects -git clone https://github.com/Memo-2023/manacore-monorepo.git -cd manacore-monorepo -``` - -### 2. Cloudflared installieren & konfigurieren - -```bash -brew install cloudflared - -# Bereits erledigt: Tunnel ist erstellt und konfiguriert -# Die Config liegt in: cloudflared-config.yml -``` - -### 3. Cloudflared als Service einrichten - -```bash -chmod +x scripts/mac-mini/setup-cloudflared-service.sh -./scripts/mac-mini/setup-cloudflared-service.sh -``` - -Das Script erstellt einen launchd-Service, der: -- Automatisch beim Login startet -- Bei AbstΓΌrzen neu startet -- Logs nach `/tmp/cloudflared.log` schreibt - -### 4. Environment konfigurieren - -```bash -# Template kopieren -cp .env.macmini.example .env.macmini - -# Werte eintragen -nano .env.macmini -``` - -**Wichtige Werte:** -- `POSTGRES_PASSWORD` - Sicheres Passwort fΓΌr PostgreSQL -- `REDIS_PASSWORD` - Sicheres Passwort fΓΌr Redis -- `JWT_SECRET` - FΓΌr JWT-Token Generierung -- `AZURE_OPENAI_*` - FΓΌr Chat AI Features (optional) - -### 5. Container starten - -```bash -chmod +x scripts/mac-mini/deploy.sh -./scripts/mac-mini/deploy.sh -``` - ---- - -## TΓ€gliche Operationen - -### Container Status prΓΌfen - -```bash -docker compose -f docker-compose.macmini.yml ps -``` - -### Logs anschauen - -```bash -# Alle Services -docker compose -f docker-compose.macmini.yml logs -f - -# Einzelner Service -docker compose -f docker-compose.macmini.yml logs -f mana-core-auth -``` - -### Neustart aller Services - -```bash -docker compose -f docker-compose.macmini.yml restart -``` - -### Update auf neue Images - -```bash -# Neuste Images pullen -docker compose -f docker-compose.macmini.yml pull - -# Container mit neuen Images starten -docker compose -f docker-compose.macmini.yml up -d - -# Alte Images aufrΓ€umen -docker image prune -f -``` - ---- - -## Cloudflared Service verwalten - -```bash -# Status prΓΌfen -launchctl list | grep cloudflared - -# Logs anschauen -tail -f /tmp/cloudflared.log - -# Service stoppen -launchctl unload ~/Library/LaunchAgents/com.cloudflare.cloudflared.plist - -# Service starten -launchctl load ~/Library/LaunchAgents/com.cloudflare.cloudflared.plist -``` - ---- - -## Troubleshooting - -### Container startet nicht - -```bash -# Logs des Services anschauen -docker compose -f docker-compose.macmini.yml logs - -# Beispiel -docker compose -f docker-compose.macmini.yml logs mana-core-auth -``` - -### Datenbank-Probleme - -```bash -# In PostgreSQL einloggen -docker compose -f docker-compose.macmini.yml exec postgres psql -U postgres - -# Datenbanken auflisten -\l - -# Zu Datenbank wechseln -\c manacore_auth -``` - -### Cloudflare Tunnel nicht erreichbar - -1. PrΓΌfen ob der Service lΓ€uft: - ```bash - launchctl list | grep cloudflared - ``` - -2. Logs prΓΌfen: - ```bash - cat /tmp/cloudflared.error.log - ``` - -3. Manuell testen: - ```bash - cloudflared tunnel --config cloudflared-config.yml run - ``` - -### Health Checks - -```bash -curl http://localhost:3001/api/v1/health # Auth -curl http://localhost:5173/health # Dashboard -curl http://localhost:3000/health # Chat Web -curl http://localhost:3002/api/v1/health # Chat API -curl http://localhost:5188/health # Todo Web -curl http://localhost:3018/api/health # Todo API -curl http://localhost:5186/health # Calendar Web -curl http://localhost:3016/api/v1/health # Calendar API -curl http://localhost:5187/health # Clock Web -curl http://localhost:3017/api/v1/health # Clock API -``` - ---- - -## CI/CD - -Docker Images werden automatisch bei Push zu `main` gebaut: -- Multi-Arch: `linux/amd64` (Hetzner) + `linux/arm64` (Mac Mini) -- Registry: `ghcr.io/memo-2023/:latest` - -Nach einem neuen Build: -```bash -cd ~/projects/manacore-monorepo -git pull -./scripts/mac-mini/deploy.sh -``` - ---- - -## Wichtige Dateien - -| Datei | Beschreibung | -|-------|--------------| -| `docker-compose.macmini.yml` | Docker Compose fΓΌr Mac Mini | -| `cloudflared-config.yml` | Cloudflare Tunnel Routing | -| `.env.macmini` | Environment Variables | -| `scripts/mac-mini/deploy.sh` | Deployment Script | -| `scripts/mac-mini/setup-cloudflared-service.sh` | Cloudflared Service Setup | diff --git a/docs/MAC_MINI_RUNNER_SETUP.md b/docs/MAC_MINI_RUNNER_SETUP.md deleted file mode 100644 index d75fceb60..000000000 --- a/docs/MAC_MINI_RUNNER_SETUP.md +++ /dev/null @@ -1,165 +0,0 @@ -# Mac Mini Setup: GitHub Actions Runner & SSH-Zugang - -## Aktueller Status - -| Komponente | Status | Details | -|-----------|--------|---------| -| SSH-Zugang | Aktiv | User `mana`, lokale IP `192.168.178.131` | -| GitHub Actions Runner | Aktiv | Name: `mac-mini`, Labels: `self-hosted, macOS, ARM64` | -| CD-Pipeline | Aktiv | `.github/workflows/cd-macmini.yml` | -| LaunchAgent | Installiert | `actions.runner.Memo-2023-manacore-monorepo.mac-mini` | - -**Runner-Verzeichnis:** `/Users/mana/actions-runner/` -**Projekt-Verzeichnis:** `/Users/mana/projects/manacore-monorepo/` -**Runner-Logs:** `/Users/mana/Library/Logs/actions.runner.Memo-2023-manacore-monorepo.mac-mini/` - ---- - -## Teil A: SSH-Zugang - -SSH ist eingerichtet. Verbindung vom Entwicklungsrechner: - -### A1. SSH-Dienst aktivieren (falls noch nicht aktiv) - -```bash -# PrΓΌfen ob SSH aktiv ist -sudo systemsetup -getremotelogin - -# Falls "Off": aktivieren -sudo systemsetup -setremotelogin on -``` - -### A2. SSH-Key hinterlegen - -Folgenden Public Key in `~/.ssh/authorized_keys` auf dem Mac Mini einfΓΌgen: - -```bash -mkdir -p ~/.ssh && chmod 700 ~/.ssh - -# Claude Code SSH-Key hinzufΓΌgen -echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAmtp92RmE6lPhHRg24VSYIvq9ne4+qe61SiR4c+lPWu claude-code@manacore" >> ~/.ssh/authorized_keys - -chmod 600 ~/.ssh/authorized_keys -``` - -### A3. Verbindung testen (vom Entwicklungsrechner) - -```bash -ssh mana@192.168.178.131 "echo 'SSH works!'" -``` - -### A4. SSH-Config auf dem Entwicklungsrechner - -Falls noch nicht vorhanden, `~/.ssh/config` erstellen/ergΓ€nzen: - -``` -# Lokales Netzwerk (direkt) -Host mana-server - HostName 192.168.178.131 - User mana - -# Über Cloudflare Tunnel (von extern) -Host mana-server-remote - HostName mac-mini.mana.how - User mana - ProxyCommand /opt/homebrew/bin/cloudflared access ssh --hostname %h -``` - -### A5. NΓΌtzliche SSH-Befehle - -```bash -# Verbinden -ssh mana-server - -# Direkt einen Befehl ausfΓΌhren -ssh mana-server "cd ~/projects/manacore-monorepo && ./scripts/mac-mini/status.sh" - -# Manuelles Deployment -ssh mana-server "cd ~/projects/manacore-monorepo && git pull && docker compose -f docker-compose.macmini.yml --env-file .env.macmini up -d --build matrix-web" - -# Logs eines Containers ansehen -ssh mana-server "docker logs -f mana-matrix-web --tail 50" -``` - ---- - -## Teil B: GitHub Actions Self-Hosted Runner - -Der Runner ist installiert und lΓ€uft als LaunchAgent. Er startet automatisch bei Systemstart. - -### Manuelles Deployment auslΓΆsen - -- **Automatisch:** Push auf `main` β†’ erkennt geΓ€nderte Services β†’ baut & startet nur diese -- **Manuell:** https://github.com/Memo-2023/manacore-monorepo/actions/workflows/cd-macmini.yml β†’ "Run workflow" β†’ Service wΓ€hlen - -### Runner-Status prΓΌfen - -```bash -# Auf dem Mac Mini -cd ~/actions-runner && ./svc.sh status - -# Oder via GitHub API -gh api repos/Memo-2023/manacore-monorepo/actions/runners --jq '.runners[] | "\(.name): \(.status)"' - -# Oder im Browser -# https://github.com/Memo-2023/manacore-monorepo/settings/actions/runners -``` - -### Neuinstallation (falls nΓΆtig) - -```bash -# 1. Token holen -# https://github.com/Memo-2023/manacore-monorepo/settings/actions/runners/new -# Oder: gh api -X POST repos/Memo-2023/manacore-monorepo/actions/runners/registration-token --jq '.token' - -# 2. Runner installieren -mkdir -p ~/actions-runner && cd ~/actions-runner -curl -o actions-runner.tar.gz -L https://github.com/actions/runner/releases/latest/download/actions-runner-osx-arm64-2.322.0.tar.gz -tar xzf actions-runner.tar.gz -./config.sh --url https://github.com/Memo-2023/manacore-monorepo --token DEIN_TOKEN --name mac-mini --unattended --replace - -# 3. Als Service starten -./svc.sh install && ./svc.sh start -``` - -## Fehlerbehebung - -### Runner ist offline - -```bash -cd ~/actions-runner -./svc.sh status -./svc.sh stop -./svc.sh start -``` - -### Runner-Token abgelaufen - -```bash -cd ~/actions-runner -./svc.sh stop -./config.sh remove --token ALTES_TOKEN -# Neuen Token holen (siehe Schritt 1) -./config.sh --url https://github.com/Memo-2023/manacore-monorepo --token NEUES_TOKEN -./svc.sh start -``` - -### Logs ansehen - -```bash -# Runner-Logs -tail -f ~/actions-runner/_diag/Runner_*.log - -# Workflow-Logs: im GitHub UI unter Actions-Tab -``` - -## Was passiert nach dem Setup? - -Bei jedem Push auf `main`: -1. Der Runner erkennt welche Services sich geΓ€ndert haben -2. Pullt den neuesten Code (`git pull`) -3. Baut nur die geΓ€nderten Docker-Container neu (`docker compose up -d --build `) -4. FΓΌhrt Health Checks durch -5. Ergebnis ist im GitHub Actions-Tab sichtbar - -Manuelle Deploys sind jederzeit mΓΆglich ΓΌber den "Run workflow" Button im Actions-Tab. diff --git a/docs/MAC_MINI_SETUP_CHECKLIST.md b/docs/MAC_MINI_SETUP_CHECKLIST.md deleted file mode 100644 index 7fb0ed483..000000000 --- a/docs/MAC_MINI_SETUP_CHECKLIST.md +++ /dev/null @@ -1,180 +0,0 @@ -# Mac Mini Setup Checklist - -**Server:** mana-server (ssh.mana.how) -**Domain:** mana.how -**Stand:** 22.01.2026 - ---- - -## 1. SSH verbinden - -```bash -ssh mana-server -``` - ---- - -## 2. Repo aktualisieren - -```bash -cd ~/projects/manacore-monorepo -git pull -``` - ---- - -## 3. Environment-Datei erstellen - -```bash -cp .env.macmini.example .env.macmini -nano .env.macmini -``` - -**Diese Werte eintragen:** - -```env -# Datenbank (selbst ausdenken, sicher!) -POSTGRES_PASSWORD=MeinSicheresPasswort123! - -# Redis (selbst ausdenken) -REDIS_PASSWORD=RedisPasswort456! - -# JWT Secret (mind. 32 Zeichen) -JWT_SECRET=MeinSuperGeheimerJWTSecretKey2026! - -# Optional: Azure OpenAI fΓΌr Chat -AZURE_OPENAI_ENDPOINT=https://xxx.openai.azure.com/ -AZURE_OPENAI_API_KEY=xxx -``` - -Speichern: `Ctrl+O`, `Enter`, `Ctrl+X` - ---- - -## 4. Cloudflared Service einrichten (einmalig) - -```bash -chmod +x scripts/mac-mini/setup-cloudflared-service.sh -./scripts/mac-mini/setup-cloudflared-service.sh -``` - -**PrΓΌfen ob es lΓ€uft:** -```bash -launchctl list | grep cloudflared -tail -f /tmp/cloudflared.log -``` - ---- - -## 5. Docker Images pullen & Container starten - -```bash -# Bei GitHub einloggen (PAT mit read:packages Berechtigung) -echo "DEIN_GITHUB_TOKEN" | docker login ghcr.io -u memo-2023 --password-stdin - -# Images pullen -docker compose -f docker-compose.macmini.yml --env-file .env.macmini pull - -# Container starten -docker compose -f docker-compose.macmini.yml --env-file .env.macmini up -d -``` - ---- - -## 6. Datenbanken erstellen - -```bash -docker compose -f docker-compose.macmini.yml exec -T postgres psql -U postgres -c "CREATE DATABASE manacore_auth;" -docker compose -f docker-compose.macmini.yml exec -T postgres psql -U postgres -c "CREATE DATABASE chat;" -docker compose -f docker-compose.macmini.yml exec -T postgres psql -U postgres -c "CREATE DATABASE todo;" -docker compose -f docker-compose.macmini.yml exec -T postgres psql -U postgres -c "CREATE DATABASE calendar;" -docker compose -f docker-compose.macmini.yml exec -T postgres psql -U postgres -c "CREATE DATABASE clock;" -``` - ---- - -## 7. Status prΓΌfen - -```bash -# Container Status -docker compose -f docker-compose.macmini.yml ps - -# Logs anschauen (falls Probleme) -docker compose -f docker-compose.macmini.yml logs -f -``` - ---- - -## 8. Health Checks - -```bash -curl -s http://localhost:3001/api/v1/health && echo " βœ“ Auth" -curl -s http://localhost:5173/health && echo " βœ“ Dashboard" -curl -s http://localhost:3002/api/v1/health && echo " βœ“ Chat API" -curl -s http://localhost:3000/health && echo " βœ“ Chat Web" -curl -s http://localhost:3018/api/health && echo " βœ“ Todo API" -curl -s http://localhost:5188/health && echo " βœ“ Todo Web" -curl -s http://localhost:3016/api/v1/health && echo " βœ“ Calendar API" -curl -s http://localhost:5186/health && echo " βœ“ Calendar Web" -curl -s http://localhost:3017/api/v1/health && echo " βœ“ Clock API" -curl -s http://localhost:5187/health && echo " βœ“ Clock Web" -``` - ---- - -## 9. Im Browser testen - -| App | URL | -|-----|-----| -| Dashboard | https://mana.how | -| Auth API | https://auth.mana.how/api/v1/health | -| Chat | https://chat.mana.how | -| Todo | https://todo.mana.how | -| Calendar | https://calendar.mana.how | -| Clock | https://clock.mana.how | - ---- - -## NΓΌtzliche Befehle - -```bash -# Alle Container stoppen -docker compose -f docker-compose.macmini.yml down - -# Alle Container neustarten -docker compose -f docker-compose.macmini.yml restart - -# Logs eines Services -docker compose -f docker-compose.macmini.yml logs -f mana-core-auth - -# Update auf neue Images -docker compose -f docker-compose.macmini.yml pull -docker compose -f docker-compose.macmini.yml up -d - -# Alte Images aufrΓ€umen -docker image prune -f - -# Cloudflared Logs -tail -f /tmp/cloudflared.log -``` - ---- - -## Troubleshooting - -**Container startet nicht:** -```bash -docker compose -f docker-compose.macmini.yml logs -``` - -**Datenbank-Fehler:** -```bash -docker compose -f docker-compose.macmini.yml exec postgres psql -U postgres -c "\l" -``` - -**Cloudflared Probleme:** -```bash -launchctl unload ~/Library/LaunchAgents/com.cloudflare.cloudflared.plist -launchctl load ~/Library/LaunchAgents/com.cloudflare.cloudflared.plist -tail -f /tmp/cloudflared.error.log -``` diff --git a/docs/SELF-HOSTING-GUIDE.md b/docs/SELF-HOSTING-GUIDE.md deleted file mode 100644 index ba5918b0b..000000000 --- a/docs/SELF-HOSTING-GUIDE.md +++ /dev/null @@ -1,709 +0,0 @@ -# Self-Hosting Guide - Manacore Monorepo - -Komplette Anleitung zum Hosten aller Projekte auf eigener Infrastruktur (VPS). - -## ProjektΓΌbersicht - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ MANACORE MONOREPO β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ MAERCHENZAUBERβ”‚ β”‚ MANACORE β”‚ β”‚ MANADECK β”‚ β”‚ MEMORO β”‚ β”‚ -β”‚ β”‚ (Storyteller)β”‚ β”‚ (Auth Hub) β”‚ β”‚ (Deck App) β”‚ β”‚ (Voice App) β”‚ β”‚ -β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ -β”‚ β”‚ β€’ Web β”‚ β”‚ β€’ Web β”‚ β”‚ β€’ Web β”‚ β”‚ β€’ Web β”‚ β”‚ -β”‚ β”‚ β€’ Mobile β”‚ β”‚ β€’ Mobile β”‚ β”‚ β€’ Mobile β”‚ β”‚ β€’ Mobile β”‚ β”‚ -β”‚ β”‚ β€’ Landing β”‚ β”‚ β€’ Landing β”‚ β”‚ β€’ Landing β”‚ β”‚ β€’ Landing β”‚ β”‚ -β”‚ β”‚ β€’ Backend β”‚ β”‚ β”‚ β”‚ β€’ Backend β”‚ β”‚ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ PICTURE β”‚ β”‚ ULOAD β”‚ β”‚ -β”‚ β”‚ (Canvas App) β”‚ β”‚(URL Shortener)β”‚ β”‚ -β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ -β”‚ β”‚ β€’ Web β”‚ β”‚ β€’ Web β”‚ β”‚ -β”‚ β”‚ β€’ Mobile β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β€’ Landing β”‚ β”‚ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - ---- - -## Technologie-Stack pro Projekt - -| Projekt | Web App | Landing | Backend | Mobile | Datenbank | -| ------------------ | --------- | ------- | ------- | ------ | ------------------ | -| **Maerchenzauber** | SvelteKit | Astro | NestJS | Expo | Supabase | -| **Manacore** | SvelteKit | Astro | - | Expo | Supabase | -| **Manadeck** | SvelteKit | Astro | NestJS | Expo | PostgreSQL | -| **Memoro** | SvelteKit | Astro | - | Expo | Supabase | -| **Picture** | SvelteKit | Astro | - | Expo | Supabase | -| **uLoad** | SvelteKit | - | - | - | PostgreSQL + Redis | - ---- - -## Deployment-Optionen im Überblick - -### Option A: Single VPS mit Coolify (Empfohlen fΓΌr Start) - -- **Kosten:** ~€15-30/Monat -- **KomplexitΓ€t:** Niedrig -- **Skalierung:** Begrenzt - -### Option B: Multi-VPS mit Coolify - -- **Kosten:** ~€50-100/Monat -- **KomplexitΓ€t:** Mittel -- **Skalierung:** Gut - -### Option C: Kubernetes (K3s) - -- **Kosten:** ~€30-80/Monat -- **KomplexitΓ€t:** Hoch -- **Skalierung:** Sehr gut - -### Option D: Hybrid (Self-Hosted + Managed) - -- **Kosten:** ~€20-50/Monat + Supabase -- **KomplexitΓ€t:** Niedrig-Mittel -- **Skalierung:** Flexibel - ---- - -# Option A: Single VPS mit Coolify - -Die einfachste LΓΆsung fΓΌr den Start. Alle Services auf einem Server. - -## Architektur - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Hetzner VPS (CX31+) β”‚ -β”‚ 4 vCPU, 8GB RAM, 80GB β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ COOLIFY β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ TRAEFIK β”‚ β”‚ -β”‚ β”‚ (Reverse Proxy + SSL) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Web Apps β”‚ β”‚ Backends β”‚ β”‚ Databases β”‚ β”‚ Landing β”‚ β”‚ -β”‚ β”‚ (Node.js) β”‚ β”‚ (NestJS) β”‚ β”‚ (PG+Redis)β”‚ β”‚ (Astro) β”‚ β”‚ -β”‚ β”‚ :3000-3005 β”‚ β”‚ :4000-4001β”‚ β”‚ :5432,6379β”‚ β”‚ :8080+ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -## Ressourcen-Anforderungen - -| Komponente | RAM | CPU | Disk | -| ----------------- | -------- | ------ | --------- | -| PostgreSQL | 1GB | 0.5 | 10GB | -| Redis | 256MB | 0.2 | 1GB | -| Coolify | 512MB | 0.3 | 5GB | -| Traefik | 128MB | 0.1 | - | -| Pro Web App | 256MB | 0.3 | - | -| Pro Backend | 512MB | 0.5 | - | -| Pro Landing | 64MB | 0.1 | - | -| **Gesamt (alle)** | **~6GB** | **~4** | **~30GB** | - -**Empfohlener Server:** Hetzner CX31 (4 vCPU, 8GB RAM, 80GB) - €8.98/Monat - -## Schritt-fΓΌr-Schritt Setup - -### 1. VPS bestellen und Coolify installieren - -```bash -# SSH zum Server -ssh root@YOUR-IP - -# System updaten -apt update && apt upgrade -y - -# Coolify installieren -curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash -``` - -### 2. Datenbank-Services erstellen - -**PostgreSQL:** - -``` -Name: shared-postgres -Version: 16-alpine -Databases: manacore, manadeck, uload -``` - -**Redis:** - -``` -Name: shared-redis -Version: 7-alpine -``` - -### 3. Projekte deployen - -#### Deployment-Reihenfolge (wichtig!) - -1. **Datenbanken** (PostgreSQL, Redis) -2. **Backends** (Maerchenzauber, Manadeck) -3. **Web Apps** (alle) -4. **Landing Pages** (alle) - -#### Konfiguration pro Projekt - -**Alle SvelteKit Web Apps:** - -``` -Base Directory: / -Dockerfile: {projekt}/apps/web/Dockerfile # Falls vorhanden -oder -Build Pack: Nixpacks -Build Command: cd {projekt}/apps/web && pnpm build -Start Command: cd {projekt}/apps/web && node build -Port: 3000 -``` - -**Alle Astro Landing Pages:** - -``` -Build Pack: Static -Base Directory: {projekt}/apps/landing -Build Command: pnpm build -Publish Directory: dist -``` - -**NestJS Backends:** - -``` -Base Directory: / -Dockerfile: {projekt}/apps/backend/Dockerfile -oder -Dockerfile: {projekt}/backend/Dockerfile -Port: 4000 -``` - -### 4. Domain-Mapping - -| Service | Domain | Port | -| ---------------------- | --------------------- | ---- | -| uload-web | ulo.ad | 3000 | -| maerchenzauber-web | app.maerchenzauber.de | 3001 | -| maerchenzauber-landing | maerchenzauber.de | 8080 | -| maerchenzauber-backend | api.maerchenzauber.de | 4000 | -| manacore-web | app.manacore.io | 3002 | -| manacore-landing | manacore.io | 8081 | -| manadeck-web | app.manadeck.de | 3003 | -| manadeck-landing | manadeck.de | 8082 | -| manadeck-backend | api.manadeck.de | 4001 | -| memoro-web | app.memoro.ai | 3004 | -| memoro-landing | memoro.ai | 8083 | -| picture-web | app.picture.io | 3005 | -| picture-landing | picture.io | 8084 | - ---- - -# Option B: Multi-VPS mit Coolify - -Bessere Isolation und Skalierung durch mehrere Server. - -## Architektur - -``` - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ DNS / CDN β”‚ - β”‚ (Cloudflare) β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ β”‚ β”‚ - β–Ό β–Ό β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ VPS 1 β”‚ β”‚ VPS 2 β”‚ β”‚ VPS 3 β”‚ -β”‚ (Apps) β”‚ β”‚ (Backends) β”‚ β”‚ (Databases) β”‚ -β”‚ CX21 β”‚ β”‚ CX21 β”‚ β”‚ CX31 β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ β€’ Web Apps β”‚ ◄─────► β”‚ β€’ NestJS APIs β”‚ ◄─────► β”‚ β€’ PostgreSQL β”‚ -β”‚ β€’ Landing β”‚ β”‚ β€’ Workers β”‚ β”‚ β€’ Redis β”‚ -β”‚ Pages β”‚ β”‚ β”‚ β”‚ β€’ Backups β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -## Server-Aufteilung - -### VPS 1: Frontend (CX21 - €4.49/Monat) - -- Alle SvelteKit Web Apps -- Alle Astro Landing Pages -- Traefik Reverse Proxy - -### VPS 2: Backends (CX21 - €4.49/Monat) - -- Maerchenzauber NestJS Backend -- Manadeck NestJS Backend -- Background Workers - -### VPS 3: Datenbanken (CX31 - €8.98/Monat) - -- PostgreSQL (shared) -- Redis (shared) -- Automated Backups - -**Gesamtkosten:** ~€18/Monat - -## Einrichtung - -### VPS 3 (Datenbanken) zuerst - -```bash -# Coolify installieren -curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash - -# PostgreSQL mit externem Zugriff -# In Coolify: Network β†’ Enable External Access -``` - -### VPS 2 (Backends) - -```bash -# Coolify installieren -# Backends deployen mit DATABASE_URL zu VPS 3 -``` - -### VPS 1 (Frontends) - -```bash -# Coolify installieren -# Web Apps deployen mit API_URL zu VPS 2 -``` - -## Netzwerk-Sicherheit - -```bash -# Auf VPS 3 (Datenbanken): Nur VPS 1+2 erlauben -ufw allow from VPS1-IP to any port 5432 -ufw allow from VPS2-IP to any port 5432 -ufw allow from VPS1-IP to any port 6379 -ufw allow from VPS2-IP to any port 6379 -ufw deny 5432 -ufw deny 6379 -``` - ---- - -# Option C: Kubernetes mit K3s - -FΓΌr maximale Skalierung und Automatisierung. - -## Architektur - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ K3s Cluster β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ INGRESS (Traefik) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ -β”‚ β”‚ β”‚ Namespace β”‚ β”‚ Namespace β”‚ β”‚ Namespace β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ uload β”‚ β”‚ maerchen- β”‚ β”‚ manadeck β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ zauber β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ web:3 β”‚ β”‚ β”‚ β”‚ web:2 β”‚ β”‚ β”‚ β”‚ web:2 β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ replicasβ”‚ β”‚ β”‚ β”‚ backend β”‚ β”‚ β”‚ β”‚ backend β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ landing β”‚ β”‚ β”‚ β”‚ landing β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ -β”‚ β”‚ β”‚ Shared Services β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ PostgreSQL (StatefulSet) β”‚ Redis (StatefulSet) β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ -β”‚ Node 1 (CX21) Node 2 (CX21) Node 3 (CX21) β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -## K3s Setup - -### Master Node installieren - -```bash -# Auf Node 1 -curl -sfL https://get.k3s.io | sh - - -# Token fΓΌr Worker holen -cat /var/lib/rancher/k3s/server/node-token -``` - -### Worker Nodes hinzufΓΌgen - -```bash -# Auf Node 2 und 3 -curl -sfL https://get.k3s.io | K3S_URL=https://NODE1-IP:6443 K3S_TOKEN=TOKEN sh - -``` - -### Helm Charts deployen - -```yaml -# values-uload.yaml -replicaCount: 2 -image: - repository: ghcr.io/your-org/uload-web - tag: latest -service: - port: 3000 -ingress: - enabled: true - hosts: - - host: ulo.ad - paths: - - path: / -env: - - name: DATABASE_URL - valueFrom: - secretKeyRef: - name: db-credentials - key: url -``` - -```bash -helm install uload ./charts/sveltekit -f values-uload.yaml -``` - -## Vorteile K8s - -- Auto-Scaling bei Last -- Rolling Updates ohne Downtime -- Self-Healing bei AusfΓ€llen -- Resource Limits pro App - -## Nachteile K8s - -- HΓΆhere KomplexitΓ€t -- Mehr Overhead (RAM fΓΌr K8s selbst) -- Lernkurve - ---- - -# Option D: Hybrid (Self-Hosted + Managed) - -Kombination aus Self-Hosting und Managed Services fΓΌr beste Balance. - -## Architektur - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ MANAGED SERVICES β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ SUPABASE β”‚ β”‚ CLOUDFLARE β”‚ β”‚ VERCEL/ β”‚ β”‚ -β”‚ β”‚ (Database) β”‚ β”‚ (CDN) β”‚ β”‚ NETLIFY β”‚ β”‚ -β”‚ β”‚ PostgreSQL β”‚ β”‚ DNS, Cache β”‚ β”‚ (Landing) β”‚ β”‚ -β”‚ β”‚ Auth, Store β”‚ β”‚ DDoS Prot. β”‚ β”‚ Static β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β”‚ β”‚ - β–Ό β–Ό β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ SELF-HOSTED (VPS) β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Hetzner CX21 β”‚ β”‚ -β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ -β”‚ β”‚ β”‚ Web Apps β”‚ β”‚ Backends β”‚ β”‚ uLoad β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ (SvelteKit)β”‚ β”‚ (NestJS) β”‚ β”‚ + DB β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -## Was wo hosten? - -### Managed Services (empfohlen) - -| Service | Anbieter | Kosten | Grund | -| ------------- | -------------- | ---------- | ------------------------- | -| Datenbank | Supabase | Free-$25/M | Auth + Realtime inklusive | -| Landing Pages | Vercel/Netlify | Free | CDN + Edge | -| CDN | Cloudflare | Free | DDoS + Caching | -| Email | Resend | Free-$20/M | Deliverability | -| Payments | Stripe | % per Tx | Compliance | - -### Self-Hosted (VPS) - -| Service | Grund | -| -------- | -------------------------------------- | -| Web Apps | Volle Kontrolle, gΓΌnstiger bei Traffic | -| Backends | Custom Code, API Keys | -| uLoad | Komplett eigene Infra gewΓΌnscht | -| Redis | Falls benΓΆtigt | - -## Setup - -### 1. Supabase Projekt erstellen - -FΓΌr: Maerchenzauber, Manacore, Memoro, Picture - -```bash -# Supabase CLI -supabase init -supabase db push -``` - -### 2. Landing Pages auf Vercel - -```bash -# In jedem Landing-Projekt -cd maerchenzauber/apps/landing -vercel deploy --prod -``` - -### 3. VPS fΓΌr Web Apps + Backends - -```bash -# Coolify auf Hetzner CX21 -curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash - -# Apps deployen mit Supabase URLs -``` - -## Kosten-Vergleich - -| Komponente | Full Self-Hosted | Hybrid | -| ---------- | ---------------- | ------------------ | -| VPS | €9-18/Monat | €4.50/Monat | -| Supabase | - | Free-€25/Monat | -| Vercel | - | Free | -| Cloudflare | - | Free | -| **Gesamt** | **€9-18/Monat** | **€4.50-30/Monat** | - ---- - -# Dockerfiles fΓΌr alle Projekte - -## SvelteKit Web Apps (Template) - -Erstelle fΓΌr jedes Projekt ohne Dockerfile: - -```dockerfile -# {projekt}/apps/web/Dockerfile - -FROM node:20-alpine AS builder -RUN corepack enable && corepack prepare pnpm@9.15.0 --activate -WORKDIR /app - -# Monorepo files -COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ -COPY {projekt}/apps/web/ ./{projekt}/apps/web/ -COPY packages/ ./packages/ - -# Install and build -RUN pnpm install --filter @{projekt}/web... --shamefully-hoist -WORKDIR /app/{projekt}/apps/web -RUN pnpm build - -# Runner -FROM node:20-alpine -RUN adduser -D sveltekit -WORKDIR /app -COPY --from=builder /app/{projekt}/apps/web/build ./build -COPY --from=builder /app/{projekt}/apps/web/package.json ./ -COPY --from=builder /app/node_modules ./node_modules - -USER sveltekit -ENV NODE_ENV=production PORT=3000 -EXPOSE 3000 -CMD ["node", "build"] -``` - -## Astro Landing Pages - -```dockerfile -# {projekt}/apps/landing/Dockerfile - -FROM node:20-alpine AS builder -RUN corepack enable && corepack prepare pnpm@9.15.0 --activate -WORKDIR /app - -COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ -COPY {projekt}/apps/landing/ ./{projekt}/apps/landing/ -COPY packages/ ./packages/ - -RUN pnpm install --filter @{projekt}/landing... --shamefully-hoist -WORKDIR /app/{projekt}/apps/landing -RUN pnpm build - -# Nginx for static files -FROM nginx:alpine -COPY --from=builder /app/{projekt}/apps/landing/dist /usr/share/nginx/html -EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] -``` - -## NestJS Backends - -Bereits vorhanden in: - -- `maerchenzauber/apps/backend/Dockerfile` -- `manadeck/backend/Dockerfile` - ---- - -# Environment Variables - -## Gemeinsame Variablen (alle Projekte) - -```env -NODE_ENV=production -``` - -## Supabase-basierte Projekte - -```env -# Maerchenzauber, Manacore, Memoro, Picture -PUBLIC_SUPABASE_URL=https://xxx.supabase.co -PUBLIC_SUPABASE_ANON_KEY=eyJxx... -SUPABASE_SERVICE_ROLE_KEY=eyJxx... # Nur Backend -``` - -## PostgreSQL-basierte Projekte - -```env -# Manadeck, uLoad -DATABASE_URL=postgresql://user:pass@host:5432/db -``` - -## Projekt-spezifische Variablen - -### Maerchenzauber Backend - -```env -AZURE_OPENAI_ENDPOINT=https://xxx.openai.azure.com -AZURE_OPENAI_API_KEY=xxx -GOOGLE_GEMINI_API_KEY=xxx -REPLICATE_API_TOKEN=xxx -GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json -``` - -### Manadeck Backend - -```env -GOOGLE_GEMINI_API_KEY=xxx -``` - -### uLoad - -```env -REDIS_URL=redis://localhost:6379 -STRIPE_SECRET_KEY=sk_live_xxx -STRIPE_WEBHOOK_SECRET=whsec_xxx -RESEND_API_KEY=re_xxx -R2_ACCESS_KEY_ID=xxx -R2_SECRET_ACCESS_KEY=xxx -R2_BUCKET_NAME=xxx -R2_ENDPOINT=https://xxx.r2.cloudflarestorage.com -AUTH_SECRET=xxx -``` - ---- - -# Checkliste: Komplettes Self-Hosting - -## Infrastruktur - -- [ ] VPS bestellt (Hetzner CX21/CX31) -- [ ] SSH-Zugang eingerichtet -- [ ] Coolify installiert -- [ ] Firewall konfiguriert - -## Datenbanken - -- [ ] PostgreSQL lΓ€uft -- [ ] Redis lΓ€uft (falls benΓΆtigt) -- [ ] Backups eingerichtet -- [ ] Connection Strings notiert - -## Projekte (fΓΌr jedes) - -- [ ] Dockerfile erstellt/geprΓΌft -- [ ] Environment Variables gesetzt -- [ ] Domain konfiguriert -- [ ] SSL-Zertifikat aktiv -- [ ] Health-Check funktioniert - -## DNS (fΓΌr jede Domain) - -- [ ] A-Record auf Server-IP -- [ ] www CNAME (optional) -- [ ] Propagation geprΓΌft - -## Monitoring - -- [ ] Logs erreichbar -- [ ] Alerting eingerichtet (optional) -- [ ] Uptime-Monitoring (optional) - -## Backups - -- [ ] Datenbank-Backup automatisiert -- [ ] Backup-Test durchgefΓΌhrt -- [ ] Offsite-Backup (optional) - ---- - -# Empfehlung - -## FΓΌr den Start: Option D (Hybrid) - -1. **Supabase** fΓΌr Datenbank + Auth (Free Tier) -2. **Vercel/Netlify** fΓΌr Landing Pages (Free) -3. **Hetzner CX21** fΓΌr Web Apps + Backends (€4.50/Monat) -4. **Cloudflare** fΓΌr DNS + CDN (Free) - -**Vorteile:** - -- Schneller Start -- Geringe Kosten -- Managed Auth & Realtime -- Einfache Skalierung spΓ€ter - -## FΓΌr Wachstum: Option B (Multi-VPS) - -Wenn Traffic steigt: - -1. Datenbanken auf eigenen VPS migrieren -2. Frontend/Backend trennen -3. Load Balancing hinzufΓΌgen - -## FΓΌr Enterprise: Option C (Kubernetes) - -Wenn benΓΆtigt: - -- Auto-Scaling -- Zero-Downtime Deployments -- Multi-Region - ---- - -# Support & Links - -- **Coolify Docs:** https://coolify.io/docs -- **Hetzner:** https://www.hetzner.com/cloud -- **Supabase:** https://supabase.com/docs -- **K3s:** https://k3s.io -- **Traefik:** https://doc.traefik.io/traefik/ diff --git a/docs/TESTING.md b/docs/TESTING.md deleted file mode 100644 index cb3646d31..000000000 --- a/docs/TESTING.md +++ /dev/null @@ -1,1644 +0,0 @@ -# Testing Strategy for Manacore Monorepo - -## Table of Contents - -- [Overview](#overview) -- [Current State Analysis](#current-state-analysis) -- [Testing Infrastructure by App Type](#testing-infrastructure-by-app-type) -- [Test Organization](#test-organization) -- [Coverage Strategy](#coverage-strategy) -- [Testing Scenarios](#testing-scenarios) -- [CI/CD Integration](#cicd-integration) -- [Implementation Roadmap](#implementation-roadmap) -- [Best Practices](#best-practices) - -## Overview - -This document outlines the comprehensive automated testing strategy for the Manacore monorepo. The goal is to achieve 80% test coverage for new code while maintaining quality and development velocity. - -### Goals - -- **80% coverage minimum** for new code -- **100% coverage** for critical paths (auth, payments, data integrity) -- **Fast feedback loops** (<5 minutes for unit tests) -- **Consistent patterns** across all projects -- **Automated testing** in CI/CD pipeline -- **Developer-friendly** test writing experience - -## Current State Analysis - -### Existing Test Files (25 total) - -#### By Project - -**Maerchenzauber (13 files, ~4,182 total lines)**: -- Mobile: 5 comprehensive auth flow tests (excellent pattern) -- Backend: 8 NestJS service/controller tests - -**Memoro (3 files)**: -- Mobile: Video edge cases, UploadModal integration, media utils - -**Uload (9 files)**: -- Web: Vitest unit tests + Playwright E2E (good foundation) - -### Testing Infrastructure Currently in Use - -| App Type | Framework | Config | Coverage Tool | -|----------|-----------|--------|---------------| -| NestJS Backend | Jest | Inline in package.json | Jest coverage | -| React Native Mobile | Jest + jest-expo | Inline in package.json | Not configured | -| SvelteKit Web | Vitest + Playwright | Separate configs | vitest coverage-v8 | -| Astro Landing | None | - | - | - -### Key Findings - -**Strengths**: -- Maerchenzauber mobile auth tests show excellent patterns (comprehensive, well-organized) -- 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 (only 2 backend deployment workflows) -- Sparse coverage in most projects -- No E2E testing for mobile apps -- No shared package tests -- No integration tests with real Supabase - -## Testing Infrastructure by App Type - -### 1. NestJS Backends - -**Framework**: Jest (built-in with NestJS) - -**Key Features**: -- Controller unit tests with mocked services -- Service tests with dependency injection -- Integration tests with TestingModule -- E2E tests with supertest -- Supabase client mocking - -**Configuration**: `jest.config.js` - -```javascript -module.exports = { - moduleFileExtensions: ['js', 'json', 'ts'], - rootDir: 'src', - testRegex: '.*\\.spec\\.ts$', - transform: { - '^.+\\.(t|j)s$': 'ts-jest', - }, - collectCoverageFrom: [ - '**/*.(t|j)s', - '!**/*.module.ts', - '!**/*.interface.ts', - '!**/main.ts', - '!**/*.dto.ts', - ], - coverageDirectory: '../coverage', - testEnvironment: 'node', - coverageThresholds: { - global: { - branches: 80, - functions: 80, - lines: 80, - statements: 80, - }, - }, -}; -``` - -**Test Structure**: -``` -src/ -β”œβ”€β”€ module-name/ -β”‚ β”œβ”€β”€ module-name.controller.ts -β”‚ β”œβ”€β”€ module-name.service.ts -β”‚ β”œβ”€β”€ __tests__/ # Preferred location -β”‚ β”‚ β”œβ”€β”€ module-name.controller.spec.ts -β”‚ β”‚ β”œβ”€β”€ module-name.service.spec.ts -β”‚ β”‚ └── module-name.integration.spec.ts -β”‚ └── dto/ -test/ # E2E tests only -└── e2e/ - └── module-name.e2e-spec.ts -``` - -### 2. React Native Mobile (Expo) - -**Framework**: Jest + React Native Testing Library - -**Key Features**: -- Component rendering tests -- Navigation flow tests -- Zustand store tests -- API integration mocks (MSW) -- Platform-specific tests -- expo-secure-store mocking - -**Configuration**: `jest.config.js` - -```javascript -module.exports = { - preset: 'jest-expo', - setupFilesAfterEnv: ['/jest.setup.js'], - testMatch: [ - '**/__tests__/**/*.test.[jt]s?(x)', - '**/?(*.)+(spec|test).[jt]s?(x)', - ], - testPathIgnorePatterns: [ - '/node_modules/', - '/__tests__/utils/', - '/__tests__/fixtures/', - ], - transformIgnorePatterns: [ - 'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@unimodules/.*|unimodules|native-base|react-native-svg)', - ], - collectCoverageFrom: [ - 'src/**/*.{ts,tsx}', - 'app/**/*.{ts,tsx}', - '!**/*.d.ts', - '!**/node_modules/**', - '!**/__tests__/**', - ], - coverageDirectory: 'coverage', - coverageThresholds: { - global: { - branches: 80, - functions: 80, - lines: 80, - statements: 80, - }, - }, -}; -``` - -**Test Structure**: -``` -src/ -β”œβ”€β”€ components/ -β”‚ β”œβ”€β”€ Button/ -β”‚ β”‚ β”œβ”€β”€ Button.tsx -β”‚ β”‚ └── __tests__/ -β”‚ β”‚ β”œβ”€β”€ Button.test.tsx -β”‚ β”‚ └── Button.integration.test.tsx -β”‚ └── __tests__/ # Shared component tests -β”œβ”€β”€ services/ -β”‚ β”œβ”€β”€ authService.ts -β”‚ └── __tests__/ -β”‚ └── authService.test.ts -β”œβ”€β”€ hooks/ -β”‚ β”œβ”€β”€ useAuth.ts -β”‚ └── __tests__/ -β”‚ └── useAuth.test.ts -└── utils/ - └── __tests__/ - └── api.test.ts -app/ -└── (tabs)/ - └── __tests__/ - └── navigation.test.tsx -``` - -### 3. SvelteKit Web Apps - -**Framework**: Vitest (unit) + Playwright (E2E) - -**Key Features**: -- Component unit tests (Svelte 5 runes) -- Page/route tests -- SSR behavior tests -- Form validation tests -- Store tests -- Accessibility tests - -**Configuration**: `vitest.config.ts` - -```typescript -import { defineConfig } from 'vitest/config'; -import { sveltekit } from '@sveltejs/kit/vite'; - -export default defineConfig({ - plugins: [sveltekit()], - test: { - include: ['src/**/*.{test,spec}.{js,ts}'], - exclude: ['e2e/**', 'node_modules/**'], - environment: 'jsdom', - globals: true, - setupFiles: ['./vitest.setup.ts'], - coverage: { - provider: 'v8', - reporter: ['text', 'json', 'html', 'lcov'], - include: ['src/**/*.{js,ts,svelte}'], - exclude: [ - '**/*.d.ts', - '**/*.config.*', - '**/mockData/**', - '**/__tests__/**', - ], - thresholds: { - lines: 80, - functions: 80, - branches: 80, - statements: 80, - }, - }, - }, -}); -``` - -**Playwright Config**: `playwright.config.ts` - -```typescript -import { defineConfig, devices } from '@playwright/test'; - -export default defineConfig({ - testDir: './e2e', - fullyParallel: true, - forbidOnly: !!process.env.CI, - retries: process.env.CI ? 2 : 0, - workers: process.env.CI ? 1 : undefined, - reporter: process.env.CI ? 'github' : 'html', - use: { - baseURL: 'http://localhost:5173', - trace: 'on-first-retry', - }, - projects: [ - { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, - { name: 'firefox', use: { ...devices['Desktop Firefox'] } }, - { name: 'webkit', use: { ...devices['Desktop Safari'] } }, - ], - webServer: { - command: 'pnpm run build && pnpm run preview', - port: 5173, - reuseExistingServer: !process.env.CI, - }, -}); -``` - -**Test Structure**: -``` -src/ -β”œβ”€β”€ lib/ -β”‚ β”œβ”€β”€ components/ -β”‚ β”‚ └── Button/ -β”‚ β”‚ β”œβ”€β”€ Button.svelte -β”‚ β”‚ └── Button.test.ts -β”‚ β”œβ”€β”€ stores/ -β”‚ β”‚ β”œβ”€β”€ auth.svelte.ts -β”‚ β”‚ └── auth.test.ts -β”‚ └── utils/ -β”‚ β”œβ”€β”€ cache.ts -β”‚ └── cache.test.ts -β”œβ”€β”€ routes/ -β”‚ β”œβ”€β”€ (app)/ -β”‚ β”‚ β”œβ”€β”€ dashboard/ -β”‚ β”‚ β”‚ β”œβ”€β”€ +page.svelte -β”‚ β”‚ β”‚ β”œβ”€β”€ +page.server.ts -β”‚ β”‚ β”‚ └── +page.server.test.ts -e2e/ -β”œβ”€β”€ auth.spec.ts -β”œβ”€β”€ dashboard.spec.ts -└── helpers/ - └── test-utils.ts -``` - -### 4. Astro Landing Pages - -**Framework**: Vitest - -**Key Features**: -- Component tests -- Static content validation -- Link checking -- Build output validation - -**Configuration**: `vitest.config.ts` - -```typescript -import { defineConfig } from 'vitest/config'; -import { getViteConfig } from 'astro/config'; - -export default defineConfig( - getViteConfig({ - test: { - include: ['src/**/*.{test,spec}.{js,ts}'], - environment: 'jsdom', - globals: true, - }, - }) -); -``` - -### 5. Shared Packages - -**Framework**: Vitest (lightweight, fast) - -**Configuration**: Create `packages/vitest.config.base.ts` - -```typescript -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - include: ['src/**/*.{test,spec}.{js,ts}'], - environment: 'node', - globals: true, - coverage: { - provider: 'v8', - reporter: ['text', 'json', 'lcov'], - include: ['src/**/*.{js,ts}'], - exclude: ['**/*.d.ts', '**/__tests__/**'], - thresholds: { - lines: 80, - functions: 80, - branches: 80, - statements: 80, - }, - }, - }, -}); -``` - -## Test Organization - -### Directory Structure Convention - -**Preferred Pattern**: `__tests__/` directories co-located with source code - -``` -src/ -β”œβ”€β”€ feature/ -β”‚ β”œβ”€β”€ feature.ts -β”‚ └── __tests__/ -β”‚ β”œβ”€β”€ feature.test.ts -β”‚ β”œβ”€β”€ feature.integration.test.ts -β”‚ └── fixtures/ -β”‚ └── mockData.ts -``` - -**Alternative**: Side-by-side (for simple files) - -``` -src/ -β”œβ”€β”€ utils/ -β”‚ β”œβ”€β”€ format.ts -β”‚ └── format.test.ts -``` - -### File Naming Conventions - -- **Unit tests**: `*.test.ts` or `*.spec.ts` -- **Integration tests**: `*.integration.test.ts` -- **E2E tests**: `*.e2e.spec.ts` or `*.spec.ts` (in e2e/ directory) -- **Test utilities**: `test-utils.ts`, `*TestUtils.ts` -- **Fixtures**: `fixtures/` directory or `mockData.ts` - -### Test Utilities - -Create shared test utilities in `__tests__/utils/`: - -```typescript -// Mobile: src/__tests__/utils/authTestUtils.ts -export const mockAuthService = { - signIn: jest.fn(), - signOut: jest.fn(), - refreshToken: jest.fn(), -}; - -export const createMockUser = (overrides = {}) => ({ - id: 'test-user-id', - email: 'test@example.com', - ...overrides, -}); - -// Backend: src/__tests__/utils/testHelpers.ts -export const createTestingModule = async (providers = []) => { - return Test.createTestingModule({ - providers: [ - ...providers, - { provide: ConfigService, useValue: mockConfigService }, - ], - }).compile(); -}; - -// Web: src/lib/__tests__/utils/svelte-test-utils.ts -export const renderComponent = (Component, props = {}) => { - const { container } = render(Component, { props }); - return { container, ...screen }; -}; -``` - -## Coverage Strategy - -### Coverage Thresholds by Component Type - -| Component Type | Threshold | Justification | -|----------------|-----------|---------------| -| **Critical Paths** | 100% | Auth, payments, data integrity | -| **Services/API Clients** | 90% | Core business logic | -| **Controllers/Routes** | 85% | Request handling | -| **Components** | 80% | UI layer | -| **Utilities** | 90% | Reusable functions | -| **Types/Interfaces** | Excluded | No runtime logic | - -### Critical Paths Requiring 100% Coverage - -1. **Authentication**: - - `@manacore/shared-auth` package - - `authService.ts` in all apps - - `tokenManager.ts` - - JWT verification logic - -2. **Payment/Credit System**: - - Credit consumption logic - - Stripe integration - - Credit balance checks - - Transaction recording - -3. **Data Integrity**: - - Database migrations - - RLS policy validation (via integration tests) - - User data validation - - File upload validation - -### Coverage Reporting - -**Local Development**: -```bash -# Generate coverage report -pnpm run test:cov - -# View HTML report -open coverage/index.html -``` - -**CI/CD**: Coverage reports uploaded to Codecov or similar service - -**Coverage Gates**: -- Pull requests must maintain or increase coverage -- New files must meet 80% threshold -- Critical paths must maintain 100% - -## Testing Scenarios - -### 1. NestJS Backend Tests - -#### Controller Tests - -```typescript -// src/story/__tests__/story.controller.spec.ts -import { Test, TestingModule } from '@nestjs/testing'; -import { StoryController } from '../story.controller'; -import { StoryService } from '../story.service'; -import { CreateStoryDto } from '../dto/create-story.dto'; - -describe('StoryController', () => { - let controller: StoryController; - let service: StoryService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [StoryController], - providers: [ - { - provide: StoryService, - useValue: { - create: jest.fn(), - findAll: jest.fn(), - findOne: jest.fn(), - update: jest.fn(), - remove: jest.fn(), - }, - }, - ], - }).compile(); - - controller = module.get(StoryController); - service = module.get(StoryService); - }); - - describe('create', () => { - it('should create a story', async () => { - const dto: CreateStoryDto = { - description: 'A magical adventure', - characterId: 'char-123', - }; - const expectedResult = { id: 'story-123', ...dto }; - - jest.spyOn(service, 'create').mockResolvedValue(expectedResult); - - const result = await controller.create(dto, { user: { sub: 'user-123' } }); - - expect(result).toEqual(expectedResult); - expect(service.create).toHaveBeenCalledWith(dto, 'user-123'); - }); - - it('should handle validation errors', async () => { - const dto: CreateStoryDto = { - description: '', // Invalid - characterId: 'char-123', - }; - - await expect(controller.create(dto, { user: { sub: 'user-123' } })) - .rejects - .toThrow(); - }); - }); - - describe('findAll', () => { - it('should return user stories', async () => { - const stories = [{ id: 'story-1' }, { id: 'story-2' }]; - jest.spyOn(service, 'findAll').mockResolvedValue(stories); - - const result = await controller.findAll({ user: { sub: 'user-123' } }); - - expect(result).toEqual(stories); - expect(service.findAll).toHaveBeenCalledWith('user-123'); - }); - }); -}); -``` - -#### Service Tests with Mocked Dependencies - -```typescript -// src/story/__tests__/story.service.spec.ts -import { Test, TestingModule } from '@nestjs/testing'; -import { StoryService } from '../story.service'; -import { SupabaseDataService } from '../../core/services/supabase-data.service'; -import { PromptingService } from '../../core/services/prompting.service'; -import { IllustrationService } from '../illustration.service'; - -describe('StoryService', () => { - let service: StoryService; - let supabaseService: jest.Mocked; - let promptingService: jest.Mocked; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ - StoryService, - { - provide: SupabaseDataService, - useValue: { - insertStory: jest.fn(), - getStory: jest.fn(), - updateStory: jest.fn(), - }, - }, - { - provide: PromptingService, - useValue: { - generateStoryText: jest.fn(), - generateIllustrationPrompt: jest.fn(), - }, - }, - { - provide: IllustrationService, - useValue: { - generateImage: jest.fn(), - }, - }, - ], - }).compile(); - - service = module.get(StoryService); - supabaseService = module.get(SupabaseDataService); - promptingService = module.get(PromptingService); - }); - - describe('create', () => { - it('should generate and save a story', async () => { - const dto = { - description: 'A magical forest adventure', - characterId: 'char-123', - }; - const userId = 'user-123'; - - promptingService.generateStoryText.mockResolvedValue({ - pages: [{ text: 'Once upon a time...', pageNumber: 1 }], - }); - - supabaseService.insertStory.mockResolvedValue({ - data: { id: 'story-123', ...dto }, - error: null, - }); - - const result = await service.create(dto, userId); - - expect(result.data).toBeDefined(); - expect(result.data.id).toBe('story-123'); - expect(promptingService.generateStoryText).toHaveBeenCalled(); - expect(supabaseService.insertStory).toHaveBeenCalled(); - }); - - it('should handle generation errors', async () => { - promptingService.generateStoryText.mockRejectedValue( - new Error('API error') - ); - - const result = await service.create( - { description: 'Test', characterId: 'char-123' }, - 'user-123' - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeNull(); - }); - }); -}); -``` - -#### Integration Tests with Supabase - -```typescript -// src/story/__tests__/story.integration.spec.ts -import { Test, TestingModule } from '@nestjs/testing'; -import { ConfigModule } from '@nestjs/config'; -import { StoryModule } from '../story.module'; -import { SupabaseProvider } from '../../supabase/supabase.provider'; - -describe('StoryService Integration', () => { - let module: TestingModule; - - beforeAll(async () => { - module = await Test.createTestingModule({ - imports: [ - ConfigModule.forRoot({ - envFilePath: '.env.test', // Use test environment - }), - StoryModule, - ], - }).compile(); - }); - - afterAll(async () => { - await module.close(); - }); - - it('should create story in test database', async () => { - // Integration test with real Supabase test project - // Uses seeded test data - }); -}); -``` - -#### E2E Tests with Supertest - -```typescript -// test/e2e/story.e2e-spec.ts -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { AppModule } from '../../src/app.module'; - -describe('Story API (e2e)', () => { - let app: INestApplication; - let authToken: string; - - beforeAll(async () => { - const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); - - app = moduleFixture.createNestApplication(); - await app.init(); - - // Get auth token for tests - const authResponse = await request(app.getHttpServer()) - .post('/auth/signin') - .send({ email: 'test@example.com', password: 'test123' }); - - authToken = authResponse.body.appToken; - }); - - afterAll(async () => { - await app.close(); - }); - - describe('/story (POST)', () => { - it('should create a story', () => { - return request(app.getHttpServer()) - .post('/story') - .set('Authorization', `Bearer ${authToken}`) - .send({ - description: 'A magical adventure', - characterId: 'char-123', - }) - .expect(201) - .expect((res) => { - expect(res.body.id).toBeDefined(); - expect(res.body.description).toBe('A magical adventure'); - }); - }); - - it('should require authentication', () => { - return request(app.getHttpServer()) - .post('/story') - .send({ description: 'Test' }) - .expect(401); - }); - }); - - describe('/story (GET)', () => { - it('should return user stories', () => { - return request(app.getHttpServer()) - .get('/story') - .set('Authorization', `Bearer ${authToken}`) - .expect(200) - .expect((res) => { - expect(Array.isArray(res.body)).toBe(true); - }); - }); - }); -}); -``` - -### 2. React Native Mobile Tests - -#### Component Tests - -```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 with text', () => { - const { getByText } = render(); - expect(getByText('Click Me')).toBeTruthy(); - }); - - it('should call onPress when pressed', () => { - const onPress = jest.fn(); - const { getByText } = render( - - ); - - fireEvent.press(getByText('Click Me')); - expect(onPress).toHaveBeenCalledTimes(1); - }); - - it('should be disabled when loading', () => { - const onPress = jest.fn(); - const { getByText } = render( - - ); - - fireEvent.press(getByText('Click Me')); - expect(onPress).not.toHaveBeenCalled(); - }); - - it('should show loading indicator', () => { - const { getByTestId } = render( - - ); - - expect(getByTestId('button-loading')).toBeTruthy(); - }); -}); -``` - -#### Navigation Tests - -```typescript -// app/(tabs)/__tests__/navigation.test.tsx -import { render, waitFor } from '@testing-library/react-native'; -import { NavigationContainer } from '@react-navigation/native'; -import { TabNavigator } from '../_layout'; - -describe('Tab Navigation', () => { - it('should render all tabs', () => { - const { getByText } = render( - - - - ); - - expect(getByText('Stories')).toBeTruthy(); - expect(getByText('Characters')).toBeTruthy(); - expect(getByText('Settings')).toBeTruthy(); - }); - - it('should navigate between tabs', async () => { - const { getByText } = render( - - - - ); - - fireEvent.press(getByText('Characters')); - - await waitFor(() => { - expect(getByTestId('characters-screen')).toBeTruthy(); - }); - }); -}); -``` - -#### Zustand Store Tests - -```typescript -// src/stores/__tests__/authStore.test.ts -import { renderHook, act } from '@testing-library/react-hooks'; -import { useAuthStore } from '../authStore'; - -describe('useAuthStore', () => { - beforeEach(() => { - const { result } = renderHook(() => useAuthStore()); - act(() => { - result.current.reset(); - }); - }); - - it('should initialize with null user', () => { - const { result } = renderHook(() => useAuthStore()); - expect(result.current.user).toBeNull(); - }); - - it('should set user on sign in', () => { - const { result } = renderHook(() => useAuthStore()); - const user = { id: 'user-123', email: 'test@example.com' }; - - act(() => { - result.current.setUser(user); - }); - - expect(result.current.user).toEqual(user); - expect(result.current.isAuthenticated).toBe(true); - }); - - it('should clear user on sign out', () => { - const { result } = renderHook(() => useAuthStore()); - - act(() => { - result.current.setUser({ id: 'user-123', email: 'test@example.com' }); - result.current.signOut(); - }); - - expect(result.current.user).toBeNull(); - expect(result.current.isAuthenticated).toBe(false); - }); -}); -``` - -#### API Integration Tests with MSW - -```typescript -// src/utils/__tests__/api.test.ts -import { setupServer } from 'msw/node'; -import { rest } from 'msw'; -import { fetchWithAuth } from '../api'; - -const server = setupServer( - rest.get('http://localhost:3000/api/stories', (req, res, ctx) => { - return res(ctx.json({ stories: [] })); - }) -); - -beforeAll(() => server.listen()); -afterEach(() => server.resetHandlers()); -afterAll(() => server.close()); - -describe('fetchWithAuth', () => { - it('should fetch with auth token', async () => { - const response = await fetchWithAuth('/api/stories'); - const data = await response.json(); - - expect(data).toEqual({ stories: [] }); - }); - - it('should refresh token on 401', async () => { - server.use( - rest.get('http://localhost:3000/api/stories', (req, res, ctx) => { - return res.once(ctx.status(401)); - }), - rest.post('http://localhost:3000/auth/refresh', (req, res, ctx) => { - return res(ctx.json({ token: 'new-token' })); - }) - ); - - const response = await fetchWithAuth('/api/stories'); - expect(response.ok).toBe(true); - }); -}); -``` - -### 3. SvelteKit Web Tests - -#### Component Tests (Svelte 5 Runes) - -```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'; -import userEvent from '@testing-library/user-event'; - -describe('Button', () => { - it('should render with text', () => { - render(Button, { props: { children: 'Click Me' } }); - expect(screen.getByText('Click Me')).toBeTruthy(); - }); - - it('should call onclick when clicked', async () => { - const user = userEvent.setup(); - const onclick = vi.fn(); - - render(Button, { props: { onclick, children: 'Click Me' } }); - - await user.click(screen.getByText('Click Me')); - expect(onclick).toHaveBeenCalledOnce(); - }); - - it('should be disabled when loading', () => { - render(Button, { props: { loading: true, children: 'Click Me' } }); - const button = screen.getByRole('button'); - expect(button).toHaveProperty('disabled', true); - }); -}); -``` - -#### Store Tests (Svelte 5) - -```typescript -// src/lib/stores/__tests__/auth.test.ts -import { describe, it, expect, beforeEach } from 'vitest'; -import { authStore } from '../auth.svelte'; - -describe('authStore', () => { - beforeEach(() => { - authStore.reset(); - }); - - it('should initialize with null user', () => { - expect(authStore.user).toBeNull(); - }); - - it('should set user', () => { - const user = { id: '123', email: 'test@example.com' }; - authStore.setUser(user); - - expect(authStore.user).toEqual(user); - expect(authStore.isAuthenticated).toBe(true); - }); - - it('should clear user', () => { - authStore.setUser({ id: '123', email: 'test@example.com' }); - authStore.clear(); - - expect(authStore.user).toBeNull(); - expect(authStore.isAuthenticated).toBe(false); - }); -}); -``` - -#### Server Load Function Tests - -```typescript -// src/routes/(app)/dashboard/__tests__/+page.server.test.ts -import { describe, it, expect, vi } from 'vitest'; -import { load } from '../+page.server'; - -describe('Dashboard Load Function', () => { - it('should load user data', async () => { - const locals = { - pb: { - collection: vi.fn(() => ({ - getList: vi.fn().mockResolvedValue({ - items: [{ id: '1', title: 'Test' }], - }), - })), - }, - }; - - const result = await load({ locals }); - - expect(result.items).toHaveLength(1); - expect(result.items[0].title).toBe('Test'); - }); - - it('should handle errors', async () => { - const locals = { - pb: { - collection: vi.fn(() => ({ - getList: vi.fn().mockRejectedValue(new Error('DB error')), - })), - }, - }; - - await expect(load({ locals })).rejects.toThrow('DB error'); - }); -}); -``` - -#### E2E Tests with Playwright - -```typescript -// e2e/auth.spec.ts -import { test, expect } from '@playwright/test'; - -test.describe('Authentication', () => { - test('should sign in successfully', async ({ page }) => { - await page.goto('/signin'); - - await page.fill('input[name="email"]', 'test@example.com'); - await page.fill('input[name="password"]', 'password123'); - await page.click('button[type="submit"]'); - - await expect(page).toHaveURL('/dashboard'); - await expect(page.locator('text=Welcome')).toBeVisible(); - }); - - test('should show error for invalid credentials', async ({ page }) => { - await page.goto('/signin'); - - await page.fill('input[name="email"]', 'test@example.com'); - await page.fill('input[name="password"]', 'wrongpassword'); - await page.click('button[type="submit"]'); - - await expect(page.locator('text=Invalid credentials')).toBeVisible(); - }); - - test('should redirect to signin when not authenticated', async ({ page }) => { - await page.goto('/dashboard'); - await expect(page).toHaveURL(/.*signin/); - }); -}); -``` - -### 4. Shared Package Tests - -#### Utility Function Tests - -```typescript -// packages/shared-utils/src/__tests__/format.test.ts -import { describe, it, expect } from 'vitest'; -import { formatDate, truncate, slugify } 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'); - }); - - it('should handle invalid dates', () => { - expect(() => formatDate(null, 'yyyy-MM-dd')).toThrow(); - }); -}); - -describe('truncate', () => { - it('should truncate long strings', () => { - const text = 'This is a very long string that should be truncated'; - expect(truncate(text, 20)).toBe('This is a very long...'); - }); - - it('should not truncate short strings', () => { - const text = 'Short'; - expect(truncate(text, 20)).toBe('Short'); - }); - - it('should handle custom ellipsis', () => { - const text = 'This is a very long string'; - expect(truncate(text, 10, '...')).toBe('This is...'); - }); -}); - -describe('slugify', () => { - it('should convert to slug', () => { - expect(slugify('Hello World')).toBe('hello-world'); - expect(slugify('React & TypeScript')).toBe('react-typescript'); - }); -}); -``` - -#### Auth Service Tests - -```typescript -// packages/shared-auth/src/__tests__/authService.test.ts -import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { createAuthService } from '../authService'; -import { TokenManager } from '../tokenManager'; - -describe('createAuthService', () => { - let authService; - let mockTokenManager; - - beforeEach(() => { - mockTokenManager = { - getValidToken: vi.fn(), - setTokens: vi.fn(), - clearTokens: vi.fn(), - }; - - authService = createAuthService({ - apiUrl: 'http://localhost:3000', - tokenManager: mockTokenManager, - }); - }); - - describe('signIn', () => { - it('should sign in and store tokens', async () => { - global.fetch = vi.fn().mockResolvedValue({ - ok: true, - json: async () => ({ - appToken: 'token-123', - refreshToken: 'refresh-123', - }), - }); - - const result = await authService.signIn('test@example.com', 'password'); - - expect(result.success).toBe(true); - expect(mockTokenManager.setTokens).toHaveBeenCalledWith({ - appToken: 'token-123', - refreshToken: 'refresh-123', - }); - }); - - it('should handle sign in errors', async () => { - global.fetch = vi.fn().mockResolvedValue({ - ok: false, - status: 401, - }); - - const result = await authService.signIn('test@example.com', 'wrong'); - - expect(result.success).toBe(false); - expect(result.error).toBeDefined(); - }); - }); -}); -``` - -## CI/CD Integration - -### GitHub Actions Workflow - -Create `.github/workflows/test.yml`: - -```yaml -name: Test Suite - -on: - pull_request: - branches: [main, develop] - push: - branches: [main, develop] - -jobs: - test-backends: - name: Test NestJS Backends - runs-on: ubuntu-latest - - strategy: - matrix: - project: [maerchenzauber, manadeck, chat, nutriphi] - - steps: - - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 9.15.0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run tests - run: pnpm --filter @${{ matrix.project }}/backend test:cov - - - name: Upload coverage - uses: codecov/codecov-action@v4 - with: - files: ./apps/${{ matrix.project }}/apps/backend/coverage/lcov.info - flags: backend-${{ matrix.project }} - name: backend-${{ matrix.project }} - - test-mobile: - name: Test React Native Mobile Apps - runs-on: ubuntu-latest - - strategy: - matrix: - project: [maerchenzauber, memoro, picture, chat] - - steps: - - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 9.15.0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run tests - run: pnpm --filter @${{ matrix.project }}/mobile test -- --coverage --watchAll=false - - - name: Upload coverage - uses: codecov/codecov-action@v4 - with: - files: ./apps/${{ matrix.project }}/apps/mobile/coverage/lcov.info - flags: mobile-${{ matrix.project }} - name: mobile-${{ matrix.project }} - - test-web: - name: Test SvelteKit Web Apps - runs-on: ubuntu-latest - - strategy: - matrix: - project: [maerchenzauber, manacore, memoro, picture, uload, chat] - - steps: - - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 9.15.0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run unit tests - run: pnpm --filter @${{ matrix.project }}/web test:unit -- --coverage - - - name: Install Playwright browsers - run: pnpm --filter @${{ matrix.project }}/web exec playwright install --with-deps - - - name: Run E2E tests - run: pnpm --filter @${{ matrix.project }}/web test:e2e - - - name: Upload coverage - uses: codecov/codecov-action@v4 - with: - files: ./apps/${{ matrix.project }}/apps/web/coverage/lcov.info - flags: web-${{ matrix.project }} - name: web-${{ matrix.project }} - - test-shared-packages: - name: Test Shared Packages - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 9.15.0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run tests - run: pnpm --filter '@manacore/*' test -- --coverage - - - name: Upload coverage - uses: codecov/codecov-action@v4 - with: - files: ./packages/*/coverage/lcov.info - flags: shared-packages - name: shared-packages - - coverage-report: - name: Aggregate Coverage Report - needs: [test-backends, test-mobile, test-web, test-shared-packages] - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Download all coverage reports - uses: actions/download-artifact@v4 - - - name: Generate combined coverage report - run: | - echo "## Test Coverage Summary" >> $GITHUB_STEP_SUMMARY - echo "All tests passed with coverage thresholds met" >> $GITHUB_STEP_SUMMARY -``` - -### Test Performance Optimization - -**Parallel Execution**: -```json -{ - "scripts": { - "test": "jest --maxWorkers=50%", - "test:ci": "jest --maxWorkers=2 --ci" - } -} -``` - -**Test Sharding** (for large test suites): -```yaml -strategy: - matrix: - shard: [1, 2, 3, 4] -steps: - - run: pnpm test -- --shard=${{ matrix.shard }}/4 -``` - -**Caching**: -```yaml -- name: Cache test results - uses: actions/cache@v4 - with: - path: | - **/node_modules - **/.next/cache - **/coverage - key: test-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }} -``` - -## Implementation Roadmap - -### Phase 1: Foundation (Week 1-2) - -**Goals**: Set up infrastructure and create shared utilities - -- [ ] Create shared test configurations - - [ ] `packages/test-config/jest.config.base.js` - - [ ] `packages/test-config/vitest.config.base.ts` - - [ ] `packages/test-config/playwright.config.base.ts` -- [ ] Install testing dependencies across all projects -- [ ] Create shared test utilities package - - [ ] `packages/shared-test-utils/` - - [ ] Mock factories - - [ ] Test helpers - - [ ] Supabase mocks -- [ ] Set up coverage reporting - - [ ] Codecov integration - - [ ] Coverage badges in README -- [ ] Document testing patterns in this file - -### Phase 2: Critical Path Coverage (Week 3-4) - -**Goals**: Achieve 100% coverage for critical paths - -- [ ] **Authentication** (Priority 1) - - [ ] `@manacore/shared-auth` package (100% coverage) - - [ ] Token manager tests - - [ ] JWT validation tests - - [ ] Auth service tests per app -- [ ] **Payment/Credit System** (Priority 2) - - [ ] Credit consumption logic - - [ ] Stripe integration mocks - - [ ] Credit balance validation -- [ ] **Data Integrity** (Priority 3) - - [ ] RLS policy integration tests - - [ ] Database migration tests - - [ ] Data validation tests - -### Phase 3: Backend Coverage (Week 5-6) - -**Goals**: 80% coverage for all NestJS backends - -- [ ] **Maerchenzauber Backend** - - [ ] Story service tests (expand existing) - - [ ] Character service tests (expand existing) - - [ ] AI integration mocks - - [ ] E2E API tests -- [ ] **Chat Backend** - - [ ] Chat service tests - - [ ] WebSocket tests - - [ ] Message persistence tests -- [ ] **Manadeck Backend** - - [ ] Deck service tests - - [ ] Card service tests -- [ ] **Nutriphi Backend** - - [ ] Recipe service tests - - [ ] Nutrition calculation tests - -### Phase 4: Mobile Coverage (Week 7-8) - -**Goals**: 80% coverage for all mobile apps - -- [ ] **Maerchenzauber Mobile** (expand from 5 tests) - - [ ] Component tests - - [ ] Navigation tests - - [ ] Store tests - - [ ] API integration tests -- [ ] **Memoro Mobile** (expand from 3 tests) - - [ ] Audio recording tests - - [ ] Upload flow tests - - [ ] Playback tests -- [ ] **Picture Mobile** - - [ ] Image generation flow - - [ ] Gallery tests - - [ ] Share functionality -- [ ] **Chat Mobile** - - [ ] Message list tests - - [ ] Chat input tests - - [ ] Real-time updates - -### Phase 5: Web Coverage (Week 9-10) - -**Goals**: 80% coverage for all web apps - -- [ ] **Uload Web** (expand from 9 tests) - - [ ] Link management tests - - [ ] QR code tests - - [ ] Analytics tests -- [ ] **Manacore Web** - - [ ] Dashboard tests - - [ ] App switcher tests - - [ ] Profile tests -- [ ] **SvelteKit Apps** - - [ ] Component library tests - - [ ] Form validation tests - - [ ] SSR behavior tests - -### Phase 6: Shared Packages (Week 11) - -**Goals**: 90% coverage for all shared packages - -- [ ] `@manacore/shared-auth` (100%) -- [ ] `@manacore/shared-utils` (90%) -- [ ] `@manacore/shared-types` (validation tests) -- [ ] `@manacore/shared-ui` (component tests) -- [ ] `@manacore/shared-supabase` (90%) - -### Phase 7: CI/CD Integration (Week 12) - -**Goals**: Automated testing pipeline - -- [ ] Create GitHub Actions workflows - - [ ] PR checks - - [ ] Branch protection rules - - [ ] Coverage gates -- [ ] Set up Codecov - - [ ] Coverage badges - - [ ] PR comments - - [ ] Coverage diff reports -- [ ] Performance optimization - - [ ] Test caching - - [ ] Parallel execution - - [ ] Selective test running - -### Phase 8: E2E Testing (Week 13-14) - -**Goals**: Critical user flows covered - -- [ ] Playwright setup for all web apps -- [ ] Detox or Maestro for mobile apps -- [ ] Critical flows: - - [ ] Authentication flow - - [ ] Content creation flow - - [ ] Payment flow - - [ ] Share flow - -## Best Practices - -### General Testing Principles - -1. **AAA Pattern**: Arrange, Act, Assert -2. **Single Responsibility**: One test, one assertion (ideally) -3. **Isolation**: Tests should not depend on each other -4. **Descriptive Names**: Test names explain what and why -5. **Fast Tests**: Unit tests < 100ms, integration tests < 1s -6. **Deterministic**: Same input = same output - -### Test Naming Convention - -```typescript -describe('ServiceName', () => { - describe('methodName', () => { - it('should do something when condition', () => { - // Test implementation - }); - - it('should handle error when invalid input', () => { - // Error handling test - }); - }); -}); -``` - -### Mock Best Practices - -**DO**: -- Mock external dependencies (APIs, databases) -- Mock time-dependent functions (`Date.now()`) -- Use factories for test data -- Reset mocks between tests - -**DON'T**: -- Mock internal implementation details -- Over-mock (keep some real implementations) -- Forget to restore mocks after tests - -### Coverage Best Practices - -**What to Cover**: -- Business logic -- Error handling paths -- Edge cases -- Boundary conditions - -**What NOT to Cover**: -- Type definitions -- Simple getters/setters -- Framework boilerplate -- Third-party libraries - -### Supabase Testing Strategy - -**Unit Tests**: Mock Supabase client -```typescript -const mockSupabase = { - from: jest.fn(() => ({ - select: jest.fn().mockResolvedValue({ data: [], error: null }), - insert: jest.fn().mockResolvedValue({ data: {}, error: null }), - })), -}; -``` - -**Integration Tests**: Use Supabase local development -```bash -# Start local Supabase -npx supabase start - -# Run migrations -npx supabase db reset - -# Run integration tests -pnpm test:integration -``` - -**E2E Tests**: Use dedicated test project in Supabase with seeded data - -### Continuous Improvement - -- Review coverage reports weekly -- Add tests when bugs are found -- Refactor tests alongside code -- Share testing patterns across teams -- Update this document as patterns evolve - -## Resources - -- [Jest Documentation](https://jestjs.io/) -- [Vitest Documentation](https://vitest.dev/) -- [Playwright Documentation](https://playwright.dev/) -- [React Native Testing Library](https://callstack.github.io/react-native-testing-library/) -- [Testing Library](https://testing-library.com/) -- [NestJS Testing](https://docs.nestjs.com/fundamentals/testing) -- [Svelte Testing](https://svelte.dev/docs/testing) - -## FAQ - -**Q: Should I write tests before or after code?** -A: Ideally TDD (test-first), but pragmatically write tests as you develop features. - -**Q: How do I test Supabase RLS policies?** -A: Use integration tests with different user contexts, or use Supabase's policy testing features. - -**Q: What's the minimum coverage for a PR to be merged?** -A: 80% coverage for new code, no decrease in overall coverage. - -**Q: Should I test private methods?** -A: No, test public API. Private methods are tested indirectly. - -**Q: How do I mock Expo modules?** -A: Use `jest.mock()` or create manual mocks in `__mocks__/` directory. - -**Q: What about snapshot tests?** -A: Use sparingly for UI components, not for data structures. - ---- - -**Last Updated**: 2025-11-27 -**Version**: 1.0.0 -**Maintainer**: Hive Mind - Tester Agent diff --git a/docs/TESTING_GUIDE.md b/docs/TESTING_GUIDE.md deleted file mode 100644 index 5b7f07ece..000000000 --- a/docs/TESTING_GUIDE.md +++ /dev/null @@ -1,641 +0,0 @@ -# Testing Guide - -Comprehensive guide for testing in the ManaCore monorepo, including local testing, CI/CD integration, and best practices. - -## Table of Contents - -- [Overview](#overview) -- [Test Types](#test-types) -- [Running Tests Locally](#running-tests-locally) -- [Automated Daily Tests](#automated-daily-tests) -- [Writing Tests](#writing-tests) -- [Test Data Management](#test-data-management) -- [Coverage Requirements](#coverage-requirements) -- [Troubleshooting](#troubleshooting) -- [CI/CD Integration](#cicd-integration) - -## Overview - -The ManaCore monorepo uses a comprehensive testing strategy: - -- **Unit Tests**: Test individual functions and components -- **Integration Tests**: Test interactions between services -- **E2E Tests**: Test complete user flows (planned) -- **Coverage Tracking**: Monitor test coverage over time -- **Automated Daily Runs**: Ensure continuous quality - -### Testing Stack - -| Platform | Framework | Runner | Coverage | -|----------|-----------|--------|----------| -| Backend (NestJS) | Jest | Jest | Istanbul | -| Web (SvelteKit) | Vitest | Vitest | V8 | -| Mobile (React Native) | Jest | Jest | Istanbul | -| Shared Packages | Jest/Vitest | Depends | Istanbul/V8 | - -## Test Types - -### Unit Tests - -Test individual functions, services, and components in isolation. - -**Location**: `src/**/*.spec.ts` (backend), `src/**/*.test.ts` (web/mobile) - -**Example (Backend)**: -```typescript -// src/auth/auth.service.spec.ts -import { Test } from '@nestjs/testing'; -import { AuthService } from './auth.service'; - -describe('AuthService', () => { - let service: AuthService; - - beforeEach(async () => { - const module = await Test.createTestingModule({ - providers: [AuthService], - }).compile(); - - service = module.get(AuthService); - }); - - it('should hash passwords correctly', async () => { - const password = 'TestPassword123!'; - const hashed = await service.hashPassword(password); - - expect(hashed).not.toBe(password); - expect(hashed.length).toBeGreaterThan(30); - }); -}); -``` - -### Integration Tests - -Test interactions between multiple services or components. - -**Location**: `test/integration/*.spec.ts` - -**Example**: -```typescript -// test/integration/auth-flow.integration.spec.ts -describe('Authentication Flow', () => { - it('should complete registration -> login -> token validation', async () => { - // Register - const registerResult = await authService.register({ - email: 'test@example.com', - password: 'Password123!', - name: 'Test User', - }); - - expect(registerResult.id).toBeDefined(); - - // Login - const loginResult = await authService.login({ - email: 'test@example.com', - password: 'Password123!', - }); - - expect(loginResult.accessToken).toBeDefined(); - - // Validate token - const validation = await authService.validateToken(loginResult.accessToken); - expect(validation.valid).toBe(true); - }); -}); -``` - -### E2E Tests (Planned) - -End-to-end tests using Playwright to test complete user flows across frontend and backend. - -## Running Tests Locally - -### Prerequisites - -1. **Docker**: Required for database tests - ```bash - pnpm docker:up - ``` - -2. **Dependencies**: Install all packages - ```bash - pnpm install - ``` - -### Run All Tests - -```bash -# Run all tests in monorepo -pnpm test - -# Run tests with coverage -./scripts/run-tests-with-coverage.sh -``` - -### Run Specific Tests - -```bash -# Test specific service -./scripts/run-tests-with-coverage.sh mana-core-auth - -# Test specific backend -./scripts/run-tests-with-coverage.sh chat-backend - -# Test within a package -cd services/mana-core-auth -pnpm test - -# Watch mode (auto-rerun on changes) -pnpm test:watch - -# Coverage report -pnpm test:cov -``` - -### Run Integration Tests - -```bash -# Auth integration tests -cd services/mana-core-auth -pnpm test:e2e - -# Or run specific integration test file -pnpm test test/integration/auth-flow.integration.spec.ts -``` - -## Automated Daily Tests - -The daily test workflow runs automatically every day at 2 AM UTC and can be triggered manually. - -### Workflow Features - -- **Parallel Execution**: Tests run in parallel across multiple test suites -- **Database Setup**: Automatic PostgreSQL/Redis setup for each test suite -- **Coverage Enforcement**: Fails if coverage drops below 80% -- **Flaky Test Detection**: Identifies tests that fail intermittently -- **Performance Tracking**: Monitors test execution time trends -- **Failure Notifications**: Creates GitHub issues and sends Slack notifications - -### Manual Trigger - -1. Go to GitHub Actions -2. Select "Daily Tests" workflow -3. Click "Run workflow" -4. (Optional) Adjust coverage threshold -5. Click "Run workflow" button - -### Viewing Results - -Daily test results are available in: - -- **GitHub Actions**: View workflow runs and logs -- **Artifacts**: Download coverage reports, metrics, and flaky test reports -- **GitHub Issues**: Automatically created for failures and flaky tests -- **Slack**: Notifications sent on failure (if configured) - -## Writing Tests - -### Best Practices - -1. **Descriptive Names**: Use clear, descriptive test names - ```typescript - // βœ… Good - it('should hash passwords using bcrypt with cost factor 10', () => {}); - - // ❌ Bad - it('should work', () => {}); - ``` - -2. **Arrange-Act-Assert**: Structure tests clearly - ```typescript - it('should validate JWT tokens correctly', async () => { - // Arrange - const token = await generateToken({ userId: '123' }); - - // Act - const result = await validateToken(token); - - // Assert - expect(result.valid).toBe(true); - expect(result.payload.userId).toBe('123'); - }); - ``` - -3. **Isolation**: Tests should not depend on each other - ```typescript - // βœ… Good - Each test is independent - beforeEach(async () => { - await cleanupDatabase(); - await seedTestData(); - }); - - // ❌ Bad - Tests depend on execution order - let userId; - it('should create user', () => { - userId = createUser(); // Other tests depend on this - }); - ``` - -4. **Mock External Services**: Don't make real API calls - ```typescript - // βœ… Good - jest.mock('openai', () => ({ - OpenAI: jest.fn().mockImplementation(() => ({ - chat: { - completions: { - create: jest.fn().mockResolvedValue({ choices: [...] }), - }, - }, - })), - })); - - // ❌ Bad - Real API call - const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); - ``` - -5. **Use Test Factories**: Create test data consistently - ```typescript - // Create a test factory - function createTestUser(overrides = {}) { - return { - id: uuid(), - email: `test-${Date.now()}@example.com`, - name: 'Test User', - role: 'user', - ...overrides, - }; - } - - // Use in tests - it('should create user', () => { - const user = createTestUser({ email: 'specific@example.com' }); - }); - ``` - -### Testing Backend Services - -```typescript -// services/mana-core-auth/src/credits/credits.service.spec.ts -import { Test } from '@nestjs/testing'; -import { CreditsService } from './credits.service'; - -describe('CreditsService', () => { - let service: CreditsService; - - beforeEach(async () => { - const module = await Test.createTestingModule({ - providers: [ - CreditsService, - // Mock dependencies - { - provide: 'DATABASE', - useValue: mockDatabase, - }, - ], - }).compile(); - - service = module.get(CreditsService); - }); - - describe('deductCredits', () => { - it('should deduct from balance if sufficient', async () => { - const result = await service.deductCredits('user-id', 10); - - expect(result.isOk()).toBe(true); - expect(result.value.balance).toBe(90); // Started with 100 - }); - - it('should return error if insufficient balance', async () => { - const result = await service.deductCredits('user-id', 200); - - expect(result.isErr()).toBe(true); - expect(result.error.code).toBe('INSUFFICIENT_CREDITS'); - }); - }); -}); -``` - -### Testing Web Components (Svelte) - -```typescript -// apps/chat/apps/web/src/lib/components/Button.test.ts -import { render, screen, fireEvent } from '@testing-library/svelte'; -import Button from './Button.svelte'; - -describe('Button', () => { - it('should render with text', () => { - render(Button, { props: { text: 'Click me' } }); - - expect(screen.getByText('Click me')).toBeInTheDocument(); - }); - - it('should call onClick when clicked', async () => { - const onClick = vi.fn(); - render(Button, { props: { text: 'Click', onClick } }); - - await fireEvent.click(screen.getByText('Click')); - - expect(onClick).toHaveBeenCalledTimes(1); - }); -}); -``` - -### Testing Mobile Components (React Native) - -```typescript -// apps/chat/apps/mobile/src/components/MessageBubble.test.tsx -import { render, screen } from '@testing-library/react-native'; -import MessageBubble from './MessageBubble'; - -describe('MessageBubble', () => { - it('should render user message', () => { - render( - - ); - - expect(screen.getByText('Hello!')).toBeTruthy(); - }); - - it('should render assistant message', () => { - render( - - ); - - expect(screen.getByText('Hi there!')).toBeTruthy(); - }); -}); -``` - -## Test Data Management - -### Seeding Test Data - -Use deterministic test data for reproducible tests. - -```bash -# Seed all services -./scripts/test-data/seed-test-data.sh - -# Seed specific service -./scripts/test-data/seed-test-data.sh auth -./scripts/test-data/seed-test-data.sh chat -``` - -### Test User Accounts - -Pre-seeded test users (password: `TestPassword123!`): - -| Email | ID | Role | -|-------|-----|------| -| `test-user-1@example.com` | `00000000-0000-0000-0000-000000000001` | user | -| `test-user-2@example.com` | `00000000-0000-0000-0000-000000000002` | user | -| `admin@example.com` | `00000000-0000-0000-0000-000000000003` | admin | - -### Cleanup After Tests - -```bash -# Clean all databases -./scripts/test-data/cleanup-test-data.sh - -# Clean specific database -./scripts/test-data/cleanup-test-data.sh auth -``` - -### Isolation Strategy - -Each test suite should: - -1. **Setup**: Create necessary test data -2. **Execute**: Run tests -3. **Teardown**: Clean up test data - -```typescript -describe('User Management', () => { - let testUserId: string; - - beforeEach(async () => { - // Setup: Create test user - const user = await createTestUser(); - testUserId = user.id; - }); - - afterEach(async () => { - // Teardown: Remove test user - await deleteUser(testUserId); - }); - - it('should update user profile', async () => { - // Test uses testUserId - }); -}); -``` - -## Coverage Requirements - -### Global Thresholds - -All packages must maintain minimum coverage: - -| Metric | Threshold | -|--------|-----------| -| Lines | 80% | -| Statements | 80% | -| Functions | 80% | -| Branches | 80% | - -### Critical Path Requirements - -Critical services require 100% coverage: - -- **Auth Service**: `services/mana-core-auth/src/auth/auth.service.ts` -- **Credits Service**: `services/mana-core-auth/src/credits/credits.service.ts` -- **JWT Guards**: `services/mana-core-auth/src/common/guards/jwt-auth.guard.ts` - -### Viewing Coverage Reports - -```bash -# Generate coverage report -cd services/mana-core-auth -pnpm test:cov - -# Open HTML report -open coverage/lcov-report/index.html -``` - -### Coverage Configuration - -Coverage is configured in `jest.config.js` or `vitest.config.ts`: - -```javascript -// jest.config.js -module.exports = { - coverageThreshold: { - global: { - branches: 80, - functions: 80, - lines: 80, - statements: 80, - }, - // Specific file requirements - './src/auth/auth.service.ts': { - branches: 100, - functions: 100, - lines: 100, - statements: 100, - }, - }, - collectCoverageFrom: [ - 'src/**/*.ts', - '!src/**/*.dto.ts', - '!src/**/*.module.ts', - '!src/main.ts', - ], -}; -``` - -## Troubleshooting - -### Common Issues - -#### Tests Fail with Database Connection Error - -**Problem**: `Error: connect ECONNREFUSED 127.0.0.1:5432` - -**Solution**: -```bash -# Start Docker services -pnpm docker:up - -# Verify PostgreSQL is running -docker ps | grep postgres - -# Test connection -psql -U manacore -h localhost -p 5432 -d manacore -``` - -#### Tests Pass Locally but Fail in CI - -**Problem**: Tests work locally but fail in GitHub Actions - -**Solution**: -1. Check environment variables in workflow -2. Ensure database setup steps run before tests -3. Verify Docker services are healthy -4. Check for hardcoded local paths - -#### Coverage Drops Below Threshold - -**Problem**: `Coverage 75% is below threshold 80%` - -**Solution**: -1. Identify uncovered code: `open coverage/lcov-report/index.html` -2. Write tests for uncovered functions -3. Remove dead code that can't be tested -4. Adjust threshold if justified (requires team approval) - -#### Flaky Tests - -**Problem**: Test fails intermittently - -**Solution**: -1. Check for timing issues (use `await` properly) -2. Ensure proper test isolation (no shared state) -3. Mock time-dependent functions -4. Add explicit waits for async operations - -```typescript -// ❌ Bad - Race condition -it('should process async operation', () => { - startAsyncOperation(); - expect(result).toBeDefined(); // Might not be ready -}); - -// βœ… Good - Properly awaited -it('should process async operation', async () => { - await startAsyncOperation(); - expect(result).toBeDefined(); // Guaranteed ready -}); -``` - -#### Mock Not Working - -**Problem**: Mock doesn't override actual implementation - -**Solution**: -```typescript -// βœ… Correct - Mock before import -jest.mock('./service'); -import { MyService } from './service'; - -// ❌ Wrong - Import before mock -import { MyService } from './service'; -jest.mock('./service'); // Too late! -``` - -### Getting Help - -1. **Check existing tests**: Look at similar test files for patterns -2. **Read test documentation**: `docs/test-examples/` -3. **Ask in Slack**: `#testing` channel -4. **GitHub Issues**: Label with `testing` for visibility - -## CI/CD Integration - -### Workflow Triggers - -| Event | Workflow | When | -|-------|----------|------| -| PR to main/dev | `ci.yml` | Validation only (type-check, lint) | -| Push to main/dev | `ci.yml` | Build Docker images | -| Daily at 2 AM UTC | `daily-tests.yml` | Full test suite + coverage | -| Manual trigger | `daily-tests.yml` | On-demand testing | - -### Test Artifacts - -Artifacts are stored for 30-90 days: - -- **Coverage Reports**: `coverage-{service-name}` (30 days) -- **Aggregated Coverage**: `aggregated-coverage-report` (90 days) -- **Test Metrics**: `test-metrics` (365 days) -- **Flaky Test Reports**: `flaky-test-report` (90 days) - -### Monitoring Dashboard - -Track test trends over time: - -1. **Coverage Trend**: View in aggregated coverage reports -2. **Flaky Tests**: Check `flaky-test-report` artifact -3. **Performance Metrics**: Review `test-metrics` artifact -4. **GitHub Issues**: Automatically created for failures - -## Best Practices Summary - -βœ… **DO**: -- Write tests for all new features -- Use descriptive test names -- Keep tests isolated and independent -- Mock external dependencies -- Use test factories for data creation -- Run tests locally before pushing -- Aim for high coverage (80%+) -- Use `beforeEach`/`afterEach` for setup/teardown - -❌ **DON'T**: -- Skip tests for "simple" code -- Use vague test names like "should work" -- Create tests that depend on execution order -- Make real API calls in tests -- Hardcode IDs or timestamps -- Commit failing tests -- Ignore coverage drops -- Share state between tests - ---- - -For more examples, see: -- [Backend Test Examples](test-examples/backend/) -- [Web Test Examples](test-examples/web/) -- [Mobile Test Examples](test-examples/mobile/) diff --git a/docs/TESTING_IMPLEMENTATION_GUIDE.md b/docs/TESTING_IMPLEMENTATION_GUIDE.md deleted file mode 100644 index f04aefe5f..000000000 --- a/docs/TESTING_IMPLEMENTATION_GUIDE.md +++ /dev/null @@ -1,646 +0,0 @@ -# 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); - }); - - 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(); - expect(getByText('Click Me')).toBeTruthy(); - }); - - it('should call onPress', () => { - const onPress = jest.fn(); - const { getByText } = render(); - - 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 -``` diff --git a/docs/TESTING_QUICK_REFERENCE.md b/docs/TESTING_QUICK_REFERENCE.md deleted file mode 100644 index a95d41760..000000000 --- a/docs/TESTING_QUICK_REFERENCE.md +++ /dev/null @@ -1,245 +0,0 @@ -# Testing Quick Reference - -Fast reference guide for common testing tasks in the ManaCore monorepo. - -## Quick Commands - -### Run Tests - -```bash -# All tests -pnpm test - -# Specific service -cd services/mana-core-auth && pnpm test - -# With coverage -pnpm test:cov - -# Watch mode -pnpm test:watch - -# Specific file -pnpm test src/auth/auth.service.spec.ts -``` - -### Run Tests with Script - -```bash -# All packages -./scripts/run-tests-with-coverage.sh - -# Specific package -./scripts/run-tests-with-coverage.sh mana-core-auth -./scripts/run-tests-with-coverage.sh chat-backend -``` - -### Setup/Cleanup - -```bash -# Start Docker services -pnpm docker:up - -# Seed test data -./scripts/test-data/seed-test-data.sh - -# Clean test data -./scripts/test-data/cleanup-test-data.sh - -# Stop Docker -pnpm docker:down -``` - -## Test Patterns - -### Unit Test Template (Backend) - -```typescript -import { Test } from '@nestjs/testing'; -import { MyService } from './my.service'; - -describe('MyService', () => { - let service: MyService; - - beforeEach(async () => { - const module = await Test.createTestingModule({ - providers: [MyService], - }).compile(); - - service = module.get(MyService); - }); - - it('should do something', () => { - const result = service.doSomething(); - expect(result).toBe(expected); - }); -}); -``` - -### Integration Test Template - -```typescript -describe('Integration Test', () => { - let app: INestApplication; - - beforeAll(async () => { - const module = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); - - app = module.createNestApplication(); - await app.init(); - }); - - afterAll(async () => { - await app.close(); - }); - - it('should complete flow', async () => { - // Test full flow - }); -}); -``` - -### Mock Template - -```typescript -// Mock entire module -jest.mock('./external-service', () => ({ - ExternalService: jest.fn().mockImplementation(() => ({ - method: jest.fn().mockResolvedValue(mockData), - })), -})); - -// Mock specific function -jest.spyOn(service, 'method').mockResolvedValue(mockData); -``` - -## Coverage - -### View Coverage - -```bash -# Generate report -pnpm test:cov - -# Open HTML report (macOS) -open coverage/lcov-report/index.html - -# Open HTML report (Linux) -xdg-open coverage/lcov-report/index.html -``` - -### Coverage Thresholds - -- **Global**: 80% minimum -- **Critical paths**: 100% required -- **Check in CI**: Automated daily tests - -## Test Data - -### Pre-seeded Users - -| Email | Password | Role | -|-------|----------|------| -| `test-user-1@example.com` | `TestPassword123!` | user | -| `test-user-2@example.com` | `TestPassword123!` | user | -| `admin@example.com` | `AdminPassword123!` | admin | - -### Create Test User - -```typescript -const testUser = { - id: uuid(), - email: `test-${Date.now()}@example.com`, - name: 'Test User', - role: 'user', -}; -``` - -## Troubleshooting - -### Database Connection Failed - -```bash -# 1. Start Docker -pnpm docker:up - -# 2. Verify running -docker ps | grep postgres - -# 3. Test connection -psql -U manacore -h localhost -p 5432 -d manacore -``` - -### Tests Fail in CI but Pass Locally - -1. Check environment variables -2. Verify database setup in workflow -3. Check for hardcoded paths -4. Review Docker service health checks - -### Flaky Tests - -1. Ensure proper `await` usage -2. Check test isolation -3. Mock time-dependent functions -4. Add explicit waits - -```typescript -// ❌ Flaky -it('should complete', () => { - asyncOperation(); - expect(result).toBeDefined(); -}); - -// βœ… Stable -it('should complete', async () => { - await asyncOperation(); - expect(result).toBeDefined(); -}); -``` - -## CI/CD - -### Trigger Daily Tests Manually - -1. Go to GitHub Actions -2. Select "Daily Tests" workflow -3. Click "Run workflow" -4. Set optional parameters -5. Run - -### View Test Results - -- **Workflow Runs**: GitHub Actions tab -- **Coverage**: Download artifacts from workflow -- **Metrics**: Check test-metrics artifact -- **Flaky Tests**: Check flaky-test-report artifact - -## Best Practices - -### DO βœ… - -- Write tests for new features -- Use descriptive names -- Keep tests isolated -- Mock external services -- Run locally before push -- Maintain 80%+ coverage - -### DON'T ❌ - -- Skip tests -- Use vague names -- Depend on test order -- Make real API calls -- Hardcode values -- Commit failing tests - -## Getting Help - -- **Docs**: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/docs/TESTING_GUIDE.md` -- **Examples**: `/Users/wuesteon/dev/mana_universe/manacore-monorepo/docs/test-examples/` -- **Issues**: Label with `testing` on GitHub -- **Team**: Ask in #testing Slack channel diff --git a/docs/TESTING_SUMMARY.md b/docs/TESTING_SUMMARY.md deleted file mode 100644 index 20949cd0c..000000000 --- a/docs/TESTING_SUMMARY.md +++ /dev/null @@ -1,477 +0,0 @@ -# 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) diff --git a/docs/daily-reports/2025-12-10.md b/docs/daily-reports/2025-12-10.md deleted file mode 100644 index d1eaa78bb..000000000 --- a/docs/daily-reports/2025-12-10.md +++ /dev/null @@ -1,347 +0,0 @@ -# Tagesbericht 10. Dezember 2025 - -**Autor:** Till JS - -Übersicht aller Γ„nderungen der letzten 20 Stunden, nach PrioritΓ€t sortiert. - ---- - -## PrioritΓ€t 1: Neue Features - -### Network Graph Visualisierung (Contacts, Calendar, Todo) - -Interaktive Netzwerk-Graphen zur Visualisierung von Verbindungen zwischen Elementen basierend auf gemeinsamen Tags. - -**Commits:** - -- `feat(contacts): add interactive network graph visualization` -- `feat(calendar,todo): add network graph visualization for tags` -- `feat(ui): centralize network graph components in shared-ui` -- `feat(network): add quick wins - keyboard shortcuts, strength filter, better tooltips` -- `feat(contacts): improve network graph UX with zoom-independent labels and larger nodes` -- `fix(network): initialize D3 simulation on page load` - -**Features:** - -- D3.js Force-Simulation fΓΌr physikbasiertes Layout -- Zoom & Pan mit Maus/Touchpad -- Keyboard Shortcuts: `+/-` Zoom, `0` Reset, `Esc` Deselect, `/` Suche, `F` Fokus -- Filterung nach Tags, Firma/Ort/Projekt, VerbindungsstΓ€rke -- Hover-Tooltips mit Verbindungsdetails -- Klick auf Node ΓΆffnet Detail-Sidebar (Contacts) oder Info-Panel (Calendar/Todo) -- Doppelklick navigiert zur Detail-Seite -- Shared Components in `@manacore/shared-ui` - ---- - -### Zentrales Tags API (mana-core-auth) - -Neues zentrales Tag-Management ΓΌber den Auth-Service fΓΌr app-ΓΌbergreifende Tags. - -**Commits:** - -- `feat(auth): add central Tags API in mana-core-auth` -- `feat(ui,contacts,todo): centralize tag components and add label management` - -**Features:** - -- CRUD-Endpoints fΓΌr Tags in mana-core-auth -- Schema: `tags` Tabelle mit userId, name, color, app -- Shared Tag-Komponenten in `@manacore/shared-ui` -- Label-Management in Todo App - ---- - -### Todo App - Umfangreiche Erweiterungen - -Massive Erweiterung der Todo App mit vielen neuen Features. - -**Commits:** - -- `feat(todo): redesign task input and items with glass-pill style` -- `feat(todo): add comprehensive settings page with 20+ preferences` -- `feat(todo): add task edit modal and fix task loading` -- `feat(todo): add task metadata fields and mana page` -- `feat(todo): add statistics page with visualizations` -- `feat(todo): add PWA support with offline capabilities` -- `feat(todo): add multiple kanban boards with task editing features` - -**Features:** - -- **Glass-Pill Design**: Neues modernes UI fΓΌr Task-Input und Items -- **Settings Page**: 20+ Einstellungen fΓΌr Personalisierung -- **Task Edit Modal**: Inline-Bearbeitung von Tasks -- **Metadata Fields**: Erweiterte Task-Eigenschaften -- **Mana Page**: Neue Seite fΓΌr Gamification/Belohnungen -- **Statistics Page**: Visualisierungen mit Charts -- **PWA Support**: Offline-FΓ€higkeit, Service Worker, Install-Prompt -- **Multiple Kanban Boards**: Mehrere Boards pro User - ---- - -### Contacts App - Erweiterte Funktionen - -**Commits:** - -- `feat(contacts): add duplicate detection, photo upload, and batch operations` -- `feat(contacts): add enhanced favorites page with multiple view modes` -- `feat(contacts): improve alphabet view UX and make it default` -- `feat(contacts): add SearchModal component and help content` -- `feat(contacts): add archive link to settings page` - -**Features:** - -- **Duplikat-Erkennung**: Automatische Erkennung Γ€hnlicher Kontakte -- **Foto-Upload**: Kontaktbilder hochladen -- **Batch-Operationen**: Mehrere Kontakte gleichzeitig bearbeiten -- **Favoriten-Seite**: Grid/List/Cards Ansichtsmodi -- **Alphabet-Ansicht**: Verbesserte UX, jetzt Standard -- **Search Modal**: Schnellsuche mit TastaturkΓΌrzel - ---- - -### Themes Page (Contacts, Todo, Calendar) - -Neue Themes-Seite fΓΌr Farbschema-Auswahl in allen Apps. - -**Commits:** - -- `feat(themes): add themes page to contacts, todo, and calendar apps` - -**Features:** - -- Auswahl aus vordefinierten Farbthemen -- Live-Preview -- Persistierung der Auswahl - ---- - -### Referral System Frontend - -Integration des Empfehlungssystems in die Web-Apps. - -**Commits:** - -- `feat(referral): integrate referral system frontend` - -**Features:** - -- Referral-Code Anzeige -- Einladungs-Links -- Belohnungs-Tracking - ---- - -### Help System - -Zentralisiertes Hilfesystem mit Shared Packages. - -**Commits:** - -- `feat(help): add centralized help system with shared packages` - -**Features:** - -- `@manacore/shared-help-content`: Hilfetexte -- `@manacore/shared-help-ui`: UI-Komponenten -- `@manacore/shared-help-types`: TypeScript-Typen - ---- - -### CommandBar (Global Search) - -Globale Suche ΓΌber alle Apps hinweg. - -**Commits:** - -- `feat(shared-ui): add global CommandBar component with search across apps` - -**Features:** - -- `Cmd+K` / `Ctrl+K` ΓΆffnet CommandBar -- Suche ΓΌber alle Inhalte -- Tastaturnavigation - ---- - -## PrioritΓ€t 2: UI/UX Verbesserungen - -### Skeleton Loaders - -Ladezustands-Anzeigen fΓΌr bessere UX. - -**Commits:** - -- `feat(ui): add comprehensive skeleton loaders for contacts and todo apps` -- `feat(ui): add skeleton loaders for calendar and clock apps` - -**Features:** - -- SkeletonAvatar, SkeletonCard, SkeletonGrid, SkeletonList, SkeletonRow -- Konsistente Lade-Animation -- App-spezifische Skeleton-Komponenten - ---- - -### Settings Page Verbesserungen - -**Commits:** - -- `feat(ui): add table of contents and sticky pill headers to settings page` -- `fix(settings): unify global settings across all web apps` -- `fix(settings): complete global settings unification for remaining apps` - -**Features:** - -- Inhaltsverzeichnis mit Sprungmarken -- Sticky Section Headers -- Einheitliche Settings-Struktur ΓΌber alle Apps - ---- - -### PillNavigation Icons - -**Commits:** - -- `feat(ui): add Phosphor Icons to PillNavigation` - -**Features:** - -- Phosphor Icons statt Text-Labels -- Bessere visuelle Unterscheidung - ---- - -### Settings Components Refactoring - -**Commits:** - -- `refactor(shared-ui): convert SettingsSelect from CSS to Tailwind classes` -- `refactor(shared-ui): convert settings components from scoped CSS to Tailwind` - -**Features:** - -- Migration von Scoped CSS zu Tailwind -- Bessere Konsistenz und Wartbarkeit - ---- - -## PrioritΓ€t 3: Refactoring & Code Quality - -### Groups β†’ Tags Konsolidierung - -**Commits:** - -- `refactor(contacts): consolidate groups into tags feature` -- `fix(contacts): remove groups store dependency from data page` - -**Γ„nderungen:** - -- Groups-Feature entfernt -- FunktionalitΓ€t in Tags integriert -- Weniger Code-Duplikation - ---- - -### Calendar Tags Integration - -**Commits:** - -- `feat(calendar): add full tags integration with colors` - -**Features:** - -- Farbige Tags fΓΌr Events -- Filterung nach Tags - ---- - -## PrioritΓ€t 4: Bugfixes - -### Database Schema Fix - -**Commits:** - -- `fix(todo): use TEXT for user_id columns (Better Auth compatibility)` -- `fix(db): use TEXT for user_id columns across entire codebase` - -**Problem:** Better Auth generiert User-IDs, die nicht UUID-kompatibel sind. -**LΓΆsung:** Alle `user_id` Spalten von UUID auf TEXT umgestellt. - ---- - -### Contacts Settings Page - -**Commits:** - -- `fix(contacts): fix settings page styling and add Tailwind source directives` - -**Problem:** Styling-Probleme auf der Settings-Seite. -**LΓΆsung:** Tailwind source directives hinzugefΓΌgt. - ---- - -### Network Graph Simulation - -**Commits:** - -- `fix(network): initialize D3 simulation on page load` - -**Problem:** Network-Graph zeigte keine Nodes an. -**LΓΆsung:** D3 Simulation wird jetzt korrekt beim Laden initialisiert. - ---- - -## PrioritΓ€t 5: DevOps & CI/CD - -### Deployment Guide - -**Commits:** - -- `docs(cicd): add comprehensive deployment guide with CI/CD architecture` - -**Dokumentation:** - -- CI/CD Pipeline Architektur -- Deployment-Prozesse -- Staging vs. Production - ---- - -### CI/CD Verbesserungen - -**Commits:** - -- `fix(ci): prevent container name conflict in staging deployment` -- `feat(ci): add database migrations step to tagged staging deployments` - -**Γ„nderungen:** - -- Container-Namenskonflikte behoben -- Automatische DB-Migrationen bei Tagged Deployments - ---- - -## Statistik - -| Kategorie | Anzahl | -| ---------------------- | ------ | -| Neue Features | 15 | -| UI/UX Verbesserungen | 8 | -| Refactoring | 5 | -| Bugfixes | 5 | -| DevOps/CI | 3 | -| Dokumentation | 3 | - -**Betroffene Apps:** - -- Todo (7 große Features) -- Contacts (6 große Features) -- Calendar (2 Features) -- Clock (1 Feature) -- Shared UI (8 Komponenten) -- mana-core-auth (1 API) - ---- - -_Autor: Till JS | Generiert am 10.12.2025_ diff --git a/docs/pr-reviews/PR-014-major-update.md b/docs/pr-reviews/PR-014-major-update.md deleted file mode 100644 index 6bb024b2d..000000000 --- a/docs/pr-reviews/PR-014-major-update.md +++ /dev/null @@ -1,272 +0,0 @@ -# Code Review: PR #14 - -**Title:** feat: major update with network graphs, themes, todo extensions, and more -**Author:** Till-JS -**Date:** 2025-12-10 -**Status:** OPEN -**URL:** https://github.com/Memo-2023/manacore-monorepo/pull/14 - ---- - -## Summary - -| Metric | Value | -|--------|-------| -| Files Changed | 382 | -| Additions | +39,514 | -| Deletions | -6,251 | - ---- - -## Overview - -This is a **major feature release** introducing: - -1. **Network Graph Visualization** - D3.js force-directed graphs for Contacts, Calendar, and Todo apps -2. **Central Tags API** - Unified tagging system in mana-core-auth -3. **Custom Themes System** - Theme editor, community gallery, and sharing -4. **Todo App Extensions** - Kanban boards, statistics, settings page, PWA support -5. **Contacts App Features** - Duplicate detection, photo upload, batch operations, favorites views -6. **Help System** - Shared packages for content, UI, and types (`shared-help-content`, `shared-help-ui`, `shared-help-types`, `shared-help-mobile`) -7. **Skeleton Loaders** - Better loading states across apps -8. **CommandBar** - Global search (Cmd+K) -9. **Bug Fixes** - Network graph simulation fixes, database schema TEXT for user_id - ---- - -## Code Quality Analysis - -### Strengths - -#### 1. Excellent Architecture -- Clean separation of concerns with shared packages (`shared-ui`, `shared-theme`, `shared-tags`, `shared-help-*`) -- Proper Svelte 5 runes usage (`$state`, `$derived`, `$effect`) -- Good TypeScript typing throughout - -#### 2. NetworkGraph Component (`packages/shared-ui/src/organisms/network/`) -- Well-structured D3.js integration with `d3-zoom` and `d3-selection` -- Proper zoom/pan handling -- Keyboard shortcuts implemented: - - `+`/`-` for zoom in/out - - `0` to reset zoom - - `Esc` to deselect - - `F` to focus on selected node - - `/` to focus search -- Accessible with `role="button"`, `aria-label`, `tabindex` -- Efficient re-rendering with proper state management - -#### 3. Tags Service (`services/mana-core-auth/src/tags/`) -- Proper validation (duplicate name check before create/update) -- Good use of Drizzle's `returning()` for immediate results -- User-scoped queries with proper authorization (`userId` checks) -- Default tags created for new users - -#### 4. Custom Themes Store (`packages/shared-theme/src/custom-themes-store.svelte.ts`) -- Clean API design with factory function pattern -- Proper state management with Svelte 5 runes -- Good separation of public/authenticated API calls -- CSS variable application for runtime theming - ---- - -### Suggestions for Improvement - -#### 1. Hardcoded German Strings - -**Location:** `packages/shared-ui/src/organisms/network/NetworkGraph.svelte:440-442` - -```svelte -

Keine Verbindungen gefunden

-

Elemente werden verbunden, wenn sie gemeinsame Tags haben.

-``` - -**Recommendation:** Use i18n for user-facing strings to maintain consistency across the monorepo. - ---- - -#### 2. Default Tags in German Only - -**Location:** `services/mana-core-auth/src/tags/tags.service.ts:10-15` - -```typescript -const DEFAULT_TAGS = [ - { name: 'Arbeit', color: '#3B82F6', icon: 'Briefcase' }, - { name: 'PersΓΆnlich', color: '#10B981', icon: 'User' }, - { name: 'Familie', color: '#EC4899', icon: 'Heart' }, - { name: 'Wichtig', color: '#EF4444', icon: 'Star' }, -]; -``` - -**Recommendation:** Consider locale-aware default tags or use English defaults that users can customize. - ---- - -#### 3. Database Connection Pattern - -**Location:** `services/mana-core-auth/src/tags/tags.service.ts:21-24` - -```typescript -private getDb() { - const databaseUrl = this.configService.get('database.url'); - return getDb(databaseUrl!); -} -``` - -**Issue:** Using `!` assertion is less safe. - -**Recommendation:** Inject the database connection via NestJS dependency injection instead of calling `getDb()` on every method call. - ---- - -#### 4. Missing Error Boundary Handling - -The NetworkGraph component handles empty states but doesn't have explicit error handling for malformed node/link data. - -**Recommendation:** Add defensive checks for invalid data structures. - ---- - -### Potential Issues - -#### 1. PR Size - -- 382 files is extremely large for a single PR -- Makes code review difficult and increases risk -- Consider splitting into feature branches for easier review and rollback - -#### 2. Database Schema Consistency - -**Location:** `services/mana-core-auth/src/db/schema/tags.schema.ts:11` - -```typescript -userId: text('user_id').notNull(), -``` - -This uses `TEXT` type for user_id. Verify this aligns with how user IDs are stored in other tables (some use `UUID`). - -#### 3. Missing Test Coverage - -This major PR adds significant functionality without visible test changes. Consider adding: -- Unit tests for `TagsService` -- Component tests for `NetworkGraph` -- Integration tests for the themes API - ---- - -### Security Considerations - -#### Authorization Checks βœ… - -- Tag operations properly scope by `userId` -- Custom themes store requires authentication for write operations -- Community theme browsing allows public access (appropriate) - -#### Input Validation - -- DTOs should be reviewed for proper validation (max lengths, format checks) -- Tag color field accepts any 7-char string - consider validating hex format (`/^#[0-9A-Fa-f]{6}$/`) - -#### Environment Files βœ… - -- `.env.development` only removes 6 lines, no secrets added -- No credentials exposed in the diff - ---- - -## New Shared Packages - -| Package | Purpose | -|---------|---------| -| `@manacore/shared-tags` | Client for central tags API | -| `@manacore/shared-help-content` | Markdown content loader and search | -| `@manacore/shared-help-ui` | Svelte help page components | -| `@manacore/shared-help-types` | TypeScript types for help system | -| `@manacore/shared-help-mobile` | React Native help components | -| `@manacore/shared-theme-ui` | Theme editor and community gallery | - ---- - -## Files Changed by Category - -| Category | Count | Notable Changes | -|----------|-------|-----------------| -| Contacts App | ~40 | Duplicates, batch ops, network, favorites | -| Todo App | ~30 | Kanban, statistics, settings, PWA | -| Calendar App | ~25 | Event tags, network graph | -| Shared UI | ~30 | NetworkGraph, skeleton loaders, tags | -| Shared Theme | ~15 | Custom themes store, editor | -| Shared Help | ~35 | Content, UI, types, mobile | -| mana-core-auth | ~15 | Tags API, themes API | -| Archived Apps | ~100 | Documentation cleanup | - ---- - -## Recommendations - -### 1. Split Future PRs - -Consider creating separate PRs for major features: -- Network Graph feature -- Central Tags API -- Custom Themes System -- Help System packages - -### 2. Add i18n - -Replace hardcoded German strings in shared components. - -### 3. Add Tests - -At minimum, add unit tests for: -- `TagsService` (create, update, delete, defaults) -- `ThemesService` (publish, download, rate) -- `NetworkGraph` (props, events, accessibility) - -### 4. Database Migration Plan - -Ensure `tags` and `themes` table migrations are coordinated across environments. - -### 5. Documentation Updates - -The CLAUDE.md files are helpful. Ensure README updates for new packages. - ---- - -## Rating Summary - -| Aspect | Rating | Notes | -|--------|--------|-------| -| Code Quality | ⭐⭐⭐⭐ | Clean, well-structured code | -| Architecture | ⭐⭐⭐⭐⭐ | Excellent use of shared packages | -| Test Coverage | ⭐⭐ | Missing tests for new features | -| PR Size | ⭐⭐ | Too large for single review | -| Security | ⭐⭐⭐⭐ | Good authorization patterns | -| i18n | ⭐⭐⭐ | Some hardcoded German strings | - ---- - -## Conclusion - -This is solid, well-architected code with good separation of concerns. The main concerns are: - -1. **PR size** - Makes review difficult -2. **Missing tests** - New features lack test coverage -3. **Hardcoded strings** - Some German text in shared components - -Consider splitting future releases of this scale into smaller, focused PRs. - ---- - -## Test Plan Checklist - -From the PR description: - -- [ ] Verify network graph loads correctly in Contacts, Calendar, Todo -- [ ] Test theme editor and community themes page -- [ ] Check Todo app new features (kanban, statistics, settings) -- [ ] Verify contacts duplicate detection and batch operations -- [ ] Test skeleton loaders appear during loading states - ---- - -*Review by Claude Code - 2025-12-10*