mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:21:10 +02:00
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) <noreply@anthropic.com>
This commit is contained in:
parent
7c1e2aca49
commit
67a181bb04
50 changed files with 0 additions and 25923 deletions
|
|
@ -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 <pr-number> # 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*
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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*
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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**
|
|
||||||
|
|
@ -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="<tunnel-id-hier>"
|
|
||||||
|
|
||||||
# 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: <TUNNEL_ID>
|
|
||||||
credentials-file: /Users/mana/.cloudflared/<TUNNEL_ID>.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.
|
|
||||||
|
|
@ -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\<user>\.cloudflared\<tunnel-id>.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\<user>\.cloudflared\config.yml`
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
tunnel: <TUNNEL_ID>
|
|
||||||
credentials-file: C:\Users\<user>\.cloudflared\<TUNNEL_ID>.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 <repo> 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 <windows-username>
|
|
||||||
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.
|
|
||||||
119
APP-IDEAS.md
119
APP-IDEAS.md
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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!
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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:** ___________________________
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load diff
492
COMMANDS.md
492
COMMANDS.md
|
|
@ -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)
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -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/`
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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)_
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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.*
|
|
||||||
491
RELEASE-PLAN.md
491
RELEASE-PLAN.md
|
|
@ -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.*
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -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 = `<script>
|
|
||||||
window.__PUBLIC_MANA_CORE_AUTH_URL__ = "${PUBLIC_MANA_CORE_AUTH_URL_CLIENT}";
|
|
||||||
</script>`;
|
|
||||||
return html.replace('<head>', `<head>${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<string[]>('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 <container-name> --tail=100
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Common fixes:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create missing database
|
|
||||||
docker compose exec -T postgres psql -U postgres -c "CREATE DATABASE <dbname>;"
|
|
||||||
|
|
||||||
# Restart a service
|
|
||||||
docker compose restart <service-name>
|
|
||||||
|
|
||||||
# Force recreate
|
|
||||||
docker compose up -d --force-recreate <service-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
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 <container> 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 <container> 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
|
## References
|
||||||
|
|
||||||
- [CLAUDE.md - Turborepo Configuration](./CLAUDE.md#turborepo-configuration)
|
- [CLAUDE.md - Turborepo Configuration](./CLAUDE.md#turborepo-configuration)
|
||||||
|
|
|
||||||
|
|
@ -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:
|
|
||||||
|
|
@ -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
|
|
||||||
<script>
|
|
||||||
import { Icon } from '@manacore/shared-icons';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Icon name="play" size={24} class="text-primary" />
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Icons**: 40+ häufig verwendete Icons (play, pause, settings, user, etc.)
|
|
||||||
|
|
||||||
### 5. `@manacore/shared-ui` (Erweitert)
|
|
||||||
**Pfad**: `packages/shared-ui/`
|
|
||||||
|
|
||||||
Atomic Design System für Svelte-Komponenten:
|
|
||||||
|
|
||||||
- **Atoms** (`src/atoms/`):
|
|
||||||
- `Text.svelte` - Typography mit Varianten
|
|
||||||
- `Button.svelte` - Primary, Secondary, Ghost, Danger
|
|
||||||
- `Badge.svelte` - Status-Badges
|
|
||||||
|
|
||||||
- **Molecules** (`src/molecules/`):
|
|
||||||
- `Toggle.svelte` - Toggle-Switch
|
|
||||||
- `Input.svelte` - Text-Input mit Label & Validation
|
|
||||||
|
|
||||||
- **Organisms** (`src/organisms/`):
|
|
||||||
- `Modal.svelte` - Overlay-Modal mit Slots
|
|
||||||
|
|
||||||
### 6. `@manacore/shared-types` (Erweitert)
|
|
||||||
**Pfad**: `packages/shared-types/`
|
|
||||||
|
|
||||||
Neue Type-Module hinzugefügt:
|
|
||||||
|
|
||||||
- `auth.ts` - Auth-bezogene Types (User, Session, Token)
|
|
||||||
- `theme.ts` - Theme-Konfiguration Types
|
|
||||||
- `ui.ts` - UI-Komponenten Types
|
|
||||||
- `common.ts` - Gemeinsame Utility Types
|
|
||||||
|
|
||||||
### 7. `@manacore/shared-utils` (Erweitert)
|
|
||||||
**Pfad**: `packages/shared-utils/`
|
|
||||||
|
|
||||||
Neue Utility-Module hinzugefügt:
|
|
||||||
|
|
||||||
- `format.ts` - formatDuration, formatFileSize, formatNumber, formatCurrency
|
|
||||||
- `validation.ts` - isValidEmail, isValidUrl, validatePassword
|
|
||||||
|
|
||||||
### 8. `@manacore/shared-i18n` (Neu)
|
|
||||||
**Pfad**: `packages/shared-i18n/`
|
|
||||||
|
|
||||||
Einheitliche Internationalisierung:
|
|
||||||
|
|
||||||
- Locale-Detection
|
|
||||||
- Common Translations (Buttons, Errors)
|
|
||||||
- svelte-i18n Integration
|
|
||||||
|
|
||||||
### 9. `@manacore/shared-config` (Neu)
|
|
||||||
**Pfad**: `packages/shared-config/`
|
|
||||||
|
|
||||||
Environment-Konfiguration:
|
|
||||||
|
|
||||||
- Zod-basierte Env-Validierung
|
|
||||||
- Typsichere Config-Objekte
|
|
||||||
|
|
||||||
### 10. `@manacore/shared-subscription-types` (Neu) / `@manacore/shared-subscription-ui` (Neu)
|
|
||||||
**Pfad**: `packages/shared-subscription-types/`, `packages/shared-subscription-ui/`
|
|
||||||
|
|
||||||
Subscription-bezogene Types und UI-Komponenten (Vorbereitung für zukünftige Integration).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## App-Spezifische Änderungen
|
|
||||||
|
|
||||||
### Memoro Web (`memoro/apps/web/`)
|
|
||||||
|
|
||||||
**Gelöschte Dateien** (Migration zu Shared Packages):
|
|
||||||
- `src/lib/components/AppleSignInButton.svelte` → `@manacore/shared-auth-ui`
|
|
||||||
- `src/lib/components/GoogleSignInButton.svelte` → `@manacore/shared-auth-ui`
|
|
||||||
- `src/lib/components/Modal.svelte` → `@manacore/shared-ui`
|
|
||||||
- `src/lib/components/Toggle.svelte` → `@manacore/shared-ui`
|
|
||||||
- `src/lib/components/BillingToggle.svelte` → Nicht mehr benötigt
|
|
||||||
- `src/lib/components/CostCard.svelte` → Refactored
|
|
||||||
- `src/lib/components/PackageCard.svelte` → Refactored
|
|
||||||
- `src/lib/components/SubscriptionCard.svelte` → Refactored
|
|
||||||
- `src/lib/components/SubscriptionButton.svelte` → Refactored
|
|
||||||
- `src/lib/components/UsageCard.svelte` → Refactored
|
|
||||||
- `src/lib/components/ManaIcon.svelte` → `@manacore/shared-icons`
|
|
||||||
- `src/lib/components/atoms/Text.svelte` → `@manacore/shared-ui`
|
|
||||||
- `src/lib/components/icons/` → `@manacore/shared-icons`
|
|
||||||
- `src/lib/utils/appleAuth.ts` → `@manacore/shared-auth-ui`
|
|
||||||
- `src/lib/utils/googleAuth.ts` → `@manacore/shared-auth-ui`
|
|
||||||
|
|
||||||
**Modifizierte Dateien**:
|
|
||||||
- `tailwind.config.js` - Reduziert von 165 auf 12 Zeilen (nutzt shared-tailwind preset)
|
|
||||||
- `src/app.css` - Drastisch reduziert (nutzt shared-tailwind CSS)
|
|
||||||
- `src/routes/(public)/login/+page.svelte` - Von 549 auf 46 Zeilen (nutzt LoginPage)
|
|
||||||
- `src/routes/(public)/register/+page.svelte` - Von 400+ auf 50 Zeilen (nutzt RegisterPage)
|
|
||||||
- 30+ Komponenten - Icon-Import auf `@manacore/shared-icons` umgestellt
|
|
||||||
|
|
||||||
### ManaCore Web (`manacore/apps/web/`)
|
|
||||||
|
|
||||||
**Gelöschte Dateien**:
|
|
||||||
- `src/routes/(auth)/login/+page.server.ts` → Client-side Auth
|
|
||||||
- `src/routes/(auth)/register/+page.server.ts` → Client-side Auth
|
|
||||||
|
|
||||||
**Neue Dateien**:
|
|
||||||
- `src/lib/stores/authStore.svelte.ts` - Auth-Store mit shared-auth
|
|
||||||
- `src/lib/components/Icon.svelte` - Icon-Wrapper
|
|
||||||
- `src/lib/components/ManaCoreLogo.svelte` - Logo-Komponente
|
|
||||||
- `src/lib/components/ThemeToggle.svelte` - Theme-Umschalter
|
|
||||||
- `src/lib/components/AppSlider.svelte` - App-Slider
|
|
||||||
|
|
||||||
**Modifizierte Dateien**:
|
|
||||||
- `tailwind.config.js` - Nutzt shared-tailwind preset
|
|
||||||
- `src/routes/(auth)/login/+page.svelte` - Nutzt LoginPage von shared-auth-ui
|
|
||||||
- `src/routes/(auth)/register/+page.svelte` - Nutzt RegisterPage von shared-auth-ui
|
|
||||||
|
|
||||||
### ManaDeck Web (`manadeck/apps/web/`)
|
|
||||||
|
|
||||||
**Gelöschte Dateien**:
|
|
||||||
- `src/lib/services/authService.ts` → `@manacore/shared-auth`
|
|
||||||
- `src/lib/services/tokenManager.ts` → `@manacore/shared-auth`
|
|
||||||
- `src/lib/services/deviceManager.ts` → `@manacore/shared-auth`
|
|
||||||
- `src/lib/utils/jwt.ts` → `@manacore/shared-auth`
|
|
||||||
|
|
||||||
**Neue Dateien**:
|
|
||||||
- `src/lib/auth.ts` - Auth-Initialisierung mit shared-auth
|
|
||||||
- `src/lib/components/Icon.svelte` - Icon-Wrapper
|
|
||||||
- `src/lib/components/ManaDeckLogo.svelte` - Logo-Komponente
|
|
||||||
|
|
||||||
**Modifizierte Dateien**:
|
|
||||||
- `tailwind.config.js` - Nutzt shared-tailwind
|
|
||||||
- `src/lib/stores/authStore.svelte.ts` - Nutzt shared-auth
|
|
||||||
- `src/routes/(auth)/login/+page.svelte` - Nutzt LoginPage
|
|
||||||
- `src/routes/(auth)/register/+page.svelte` - Nutzt RegisterPage
|
|
||||||
|
|
||||||
### Märchenzauber Web (`maerchenzauber/apps/web/`)
|
|
||||||
|
|
||||||
**Neue Dateien**:
|
|
||||||
- `src/lib/auth.ts` - Auth-Setup
|
|
||||||
- `src/lib/stores/` - Store-Implementierungen
|
|
||||||
- `src/lib/components/` - Komponenten
|
|
||||||
- `src/lib/utils/` - Utilities
|
|
||||||
- `src/lib/types/` - Type-Definitionen
|
|
||||||
- `src/routes/(auth)/` - Auth-Routen
|
|
||||||
- `src/app.css` - App-Styles
|
|
||||||
- `postcss.config.js` - PostCSS-Config
|
|
||||||
- `.env.example` - Environment-Template
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Quantitative Zusammenfassung
|
|
||||||
|
|
||||||
| Metrik | Vorher | Nachher | Einsparung |
|
|
||||||
|--------|--------|---------|------------|
|
|
||||||
| Dateien geändert | - | 102 | - |
|
|
||||||
| Zeilen hinzugefügt | - | ~1,400 | - |
|
|
||||||
| Zeilen gelöscht | - | ~4,300 | ~3,000 LOC |
|
|
||||||
| Login-Page LOC (Memoro) | 549 | 46 | 92% |
|
|
||||||
| Tailwind Config LOC (Memoro) | 165 | 12 | 93% |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Abhängigkeiten
|
|
||||||
|
|
||||||
Neue Dependencies in App `package.json`:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"dependencies": {
|
|
||||||
"@manacore/shared-auth": "workspace:*",
|
|
||||||
"@manacore/shared-auth-ui": "workspace:*",
|
|
||||||
"@manacore/shared-icons": "workspace:*",
|
|
||||||
"@manacore/shared-tailwind": "workspace:*",
|
|
||||||
"@manacore/shared-types": "workspace:*",
|
|
||||||
"@manacore/shared-ui": "workspace:*",
|
|
||||||
"@manacore/shared-utils": "workspace:*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Breaking Changes
|
|
||||||
|
|
||||||
1. **Icon-Import-Pfade** - Alle Icons müssen von `@manacore/shared-icons` importiert werden
|
|
||||||
2. **Modal-Import** - Modal kommt jetzt von `@manacore/shared-ui`
|
|
||||||
3. **Auth-Services** - Lokale authService/tokenManager durch shared-auth ersetzt
|
|
||||||
4. **OAuth-Buttons** - Konfiguration erfolgt über `setGoogleClientId()` / `setAppleConfig()`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Migration Guide
|
|
||||||
|
|
||||||
### Icon Migration
|
|
||||||
```svelte
|
|
||||||
<!-- Vorher -->
|
|
||||||
<script>
|
|
||||||
import Icon from '$lib/components/Icon.svelte';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Nachher -->
|
|
||||||
<script>
|
|
||||||
import { Icon } from '@manacore/shared-icons';
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Login Page Migration
|
|
||||||
```svelte
|
|
||||||
<!-- Vorher: 500+ Zeilen eigener Code -->
|
|
||||||
|
|
||||||
<!-- Nachher -->
|
|
||||||
<script>
|
|
||||||
import { LoginPage } from '@manacore/shared-auth-ui';
|
|
||||||
import MyLogo from '$lib/components/MyLogo.svelte';
|
|
||||||
import { authStore } from '$lib/stores/authStore';
|
|
||||||
|
|
||||||
async function handleSignIn(email, password) {
|
|
||||||
return authStore.signIn(email, password);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<LoginPage
|
|
||||||
onSignIn={handleSignIn}
|
|
||||||
onForgotPassword={handleForgotPassword}
|
|
||||||
registerUrl="/register"
|
|
||||||
>
|
|
||||||
{#snippet logo()}
|
|
||||||
<MyLogo />
|
|
||||||
{/snippet}
|
|
||||||
</LoginPage>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tailwind Config Migration
|
|
||||||
```javascript
|
|
||||||
// Vorher: 150+ Zeilen mit Theme-Definitionen
|
|
||||||
|
|
||||||
// Nachher
|
|
||||||
import preset from '@manacore/shared-tailwind/preset';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
presets: [preset],
|
|
||||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Nächste Schritte
|
|
||||||
|
|
||||||
1. **Testing** - Alle Apps auf Funktionalität prüfen
|
|
||||||
2. **Type-Checking** - `pnpm run type-check` in allen Apps ausführen
|
|
||||||
3. **Build-Verification** - Production Builds testen
|
|
||||||
4. **Dokumentation** - README-Dateien für neue Packages erstellen
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Referenzen
|
|
||||||
|
|
||||||
- `SHARED_PACKAGES_ROADMAP.md` - Vollständige Roadmap der Shared Packages
|
|
||||||
- `packages/shared-auth/src/index.ts` - Auth-API Dokumentation
|
|
||||||
- `packages/shared-tailwind/src/preset.js` - Theme-Konfiguration
|
|
||||||
|
|
@ -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<T>` 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
|
|
||||||
|
|
@ -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<any>,
|
|
||||||
options: BootstrapOptions = {}
|
|
||||||
): Promise<INestApplication> {
|
|
||||||
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<T>()` 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<TodoAppSettings>('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
|
|
||||||
<script lang="ts">
|
|
||||||
import { AppSlider } from '@manacore/shared-ui';
|
|
||||||
import { MANA_APPS, APP_STATUS_LABELS, APP_SLIDER_LABELS } from '@manacore/shared-branding';
|
|
||||||
|
|
||||||
const apps = MANA_APPS.map((app) => ({
|
|
||||||
name: app.name,
|
|
||||||
description: app.description.de, // German localization
|
|
||||||
longDescription: app.longDescription.de,
|
|
||||||
// ...
|
|
||||||
}));
|
|
||||||
|
|
||||||
const statusLabels = APP_STATUS_LABELS.de;
|
|
||||||
const labels = APP_SLIDER_LABELS.de;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<AppSlider {apps} title={labels.title} {statusLabels} ... />
|
|
||||||
```
|
|
||||||
|
|
||||||
**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
|
|
||||||
<script lang="ts">
|
|
||||||
import { PillDropdown } from '@manacore/shared-ui'; // Shared UI
|
|
||||||
import { getLanguageDropdownItems } from '@manacore/shared-i18n'; // Shared Helper
|
|
||||||
import { setLocale, supportedLocales } from '$lib/i18n'; // App-spezifisch
|
|
||||||
|
|
||||||
// ... connect the pieces
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<PillDropdown items={languageItems} label={currentLabel} />
|
|
||||||
```
|
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
@ -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*
|
|
||||||
|
|
@ -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*
|
|
||||||
|
|
@ -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*
|
|
||||||
|
|
@ -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<string> {
|
|
||||||
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<Buffer> {
|
|
||||||
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 <name>` | 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<T>` | Type-safe Session Data Wrapper |
|
|
||||||
| `UserListMapper<T>` | 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<UserSession | null>;
|
|
||||||
async getSession(matrixUserId: string): Promise<string | null>;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**TranscriptionService:**
|
|
||||||
```typescript
|
|
||||||
// Vorher: In 6 Bots dupliziert
|
|
||||||
// Nachher: Einmal in @manacore/bot-services
|
|
||||||
@Injectable()
|
|
||||||
export class TranscriptionService {
|
|
||||||
async transcribe(audioBuffer: Buffer): Promise<string>;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**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<Buffer> {
|
|
||||||
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*
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -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)
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
@ -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 <service-name>
|
|
||||||
|
|
||||||
# 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/<service>: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 |
|
|
||||||
|
|
@ -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 <service>`)
|
|
||||||
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.
|
|
||||||
|
|
@ -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 <service-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
**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
|
|
||||||
```
|
|
||||||
|
|
@ -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/
|
|
||||||
1644
docs/TESTING.md
1644
docs/TESTING.md
File diff suppressed because it is too large
Load diff
|
|
@ -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>(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>(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(
|
|
||||||
<MessageBubble
|
|
||||||
message={{ role: 'user', content: 'Hello!' }}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(screen.getByText('Hello!')).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render assistant message', () => {
|
|
||||||
render(
|
|
||||||
<MessageBubble
|
|
||||||
message={{ role: 'assistant', content: 'Hi there!' }}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
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/)
|
|
||||||
|
|
@ -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>(ExampleService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(service).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Run Tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm test
|
|
||||||
pnpm test:cov # With coverage
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adding Tests to React Native Mobile
|
|
||||||
|
|
||||||
### 1. Install Testing Dependencies
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd apps/YOUR_PROJECT/apps/mobile
|
|
||||||
|
|
||||||
pnpm add -D jest jest-expo @testing-library/react-native @testing-library/jest-native
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Create Jest Configuration
|
|
||||||
|
|
||||||
Create `jest.config.js`:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
module.exports = {
|
|
||||||
preset: '@manacore/test-config/jest-mobile',
|
|
||||||
// Project-specific overrides
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Create Setup File
|
|
||||||
|
|
||||||
Create `jest.setup.js`:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import '@testing-library/jest-native/extend-expect';
|
|
||||||
|
|
||||||
// Mock Expo modules
|
|
||||||
jest.mock('expo-secure-store', () => ({
|
|
||||||
getItemAsync: jest.fn(),
|
|
||||||
setItemAsync: jest.fn(),
|
|
||||||
deleteItemAsync: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('expo-font', () => ({
|
|
||||||
loadAsync: jest.fn(),
|
|
||||||
isLoaded: jest.fn(() => true),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Global test setup
|
|
||||||
global.fetch = jest.fn();
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Add Test Scripts to package.json
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"test": "jest --watchAll",
|
|
||||||
"test:ci": "jest --ci --coverage --watchAll=false",
|
|
||||||
"test:cov": "jest --coverage --watchAll=false"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Create Your First Component Test
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/components/Button/__tests__/Button.test.tsx
|
|
||||||
import React from 'react';
|
|
||||||
import { render, fireEvent } from '@testing-library/react-native';
|
|
||||||
import { Button } from '../Button';
|
|
||||||
|
|
||||||
describe('Button', () => {
|
|
||||||
it('should render', () => {
|
|
||||||
const { getByText } = render(<Button>Click Me</Button>);
|
|
||||||
expect(getByText('Click Me')).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call onPress', () => {
|
|
||||||
const onPress = jest.fn();
|
|
||||||
const { getByText } = render(<Button onPress={onPress}>Click</Button>);
|
|
||||||
|
|
||||||
fireEvent.press(getByText('Click'));
|
|
||||||
expect(onPress).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Run Tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm test
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adding Tests to SvelteKit Web
|
|
||||||
|
|
||||||
### 1. Install Testing Dependencies
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd apps/YOUR_PROJECT/apps/web
|
|
||||||
|
|
||||||
pnpm add -D vitest @vitest/coverage-v8 @testing-library/svelte jsdom
|
|
||||||
pnpm add -D @playwright/test # For E2E tests
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Create Vitest Configuration
|
|
||||||
|
|
||||||
Create `vitest.config.ts`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { defineConfig, mergeConfig } from 'vitest/config';
|
|
||||||
import svelteConfig from '@manacore/test-config/vitest-svelte';
|
|
||||||
import { sveltekit } from '@sveltejs/kit/vite';
|
|
||||||
|
|
||||||
export default mergeConfig(
|
|
||||||
svelteConfig,
|
|
||||||
defineConfig({
|
|
||||||
plugins: [sveltekit()],
|
|
||||||
test: {
|
|
||||||
// Project-specific overrides
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Create Vitest Setup File
|
|
||||||
|
|
||||||
Create `vitest.setup.ts`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { expect, afterEach } from 'vitest';
|
|
||||||
import { cleanup } from '@testing-library/svelte';
|
|
||||||
|
|
||||||
// Cleanup after each test
|
|
||||||
afterEach(() => {
|
|
||||||
cleanup();
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Create Playwright Configuration (E2E)
|
|
||||||
|
|
||||||
Create `playwright.config.ts`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { defineConfig } from '@playwright/test';
|
|
||||||
import baseConfig from '@manacore/test-config/playwright';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
...baseConfig,
|
|
||||||
use: {
|
|
||||||
...baseConfig.use,
|
|
||||||
baseURL: 'http://localhost:5173',
|
|
||||||
},
|
|
||||||
webServer: {
|
|
||||||
command: 'pnpm run build && pnpm run preview',
|
|
||||||
port: 5173,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Add Test Scripts to package.json
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"test": "pnpm run test:unit && pnpm run test:e2e",
|
|
||||||
"test:unit": "vitest run",
|
|
||||||
"test:unit:watch": "vitest",
|
|
||||||
"test:unit:cov": "vitest run --coverage",
|
|
||||||
"test:e2e": "playwright test",
|
|
||||||
"test:e2e:ui": "playwright test --ui"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Create Your First Component Test
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/lib/components/Button/__tests__/Button.test.ts
|
|
||||||
import { render, screen } from '@testing-library/svelte';
|
|
||||||
import { describe, it, expect, vi } from 'vitest';
|
|
||||||
import Button from '../Button.svelte';
|
|
||||||
|
|
||||||
describe('Button', () => {
|
|
||||||
it('should render', () => {
|
|
||||||
render(Button, { props: { children: 'Click Me' } });
|
|
||||||
expect(screen.getByText('Click Me')).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call onclick', async () => {
|
|
||||||
const onclick = vi.fn();
|
|
||||||
render(Button, { props: { onclick, children: 'Click' } });
|
|
||||||
|
|
||||||
await screen.getByText('Click').click();
|
|
||||||
expect(onclick).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7. Create Your First E2E Test
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// e2e/homepage.spec.ts
|
|
||||||
import { test, expect } from '@playwright/test';
|
|
||||||
|
|
||||||
test('homepage loads successfully', async ({ page }) => {
|
|
||||||
await page.goto('/');
|
|
||||||
await expect(page.locator('h1')).toBeVisible();
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8. Run Tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm test:unit # Unit tests
|
|
||||||
pnpm test:e2e # E2E tests
|
|
||||||
pnpm test:unit:cov # With coverage
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adding Tests to Shared Packages
|
|
||||||
|
|
||||||
### 1. Install Vitest
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd packages/YOUR_PACKAGE
|
|
||||||
|
|
||||||
pnpm add -D vitest @vitest/coverage-v8
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Create Vitest Configuration
|
|
||||||
|
|
||||||
Create `vitest.config.ts`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { defineConfig, mergeConfig } from 'vitest/config';
|
|
||||||
import baseConfig from '@manacore/test-config/vitest-base';
|
|
||||||
|
|
||||||
export default mergeConfig(
|
|
||||||
baseConfig,
|
|
||||||
defineConfig({
|
|
||||||
test: {
|
|
||||||
// Package-specific config
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Add Test Scripts to package.json
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"test": "vitest run",
|
|
||||||
"test:watch": "vitest",
|
|
||||||
"test:cov": "vitest run --coverage"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Create Your First Utility Test
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/__tests__/format.test.ts
|
|
||||||
import { describe, it, expect } from 'vitest';
|
|
||||||
import { formatDate, truncate } from '../format';
|
|
||||||
|
|
||||||
describe('formatDate', () => {
|
|
||||||
it('should format date correctly', () => {
|
|
||||||
const date = new Date('2024-01-15T12:00:00Z');
|
|
||||||
expect(formatDate(date, 'yyyy-MM-dd')).toBe('2024-01-15');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('truncate', () => {
|
|
||||||
it('should truncate long strings', () => {
|
|
||||||
expect(truncate('Very long text', 10)).toBe('Very long…');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Run Tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm test
|
|
||||||
pnpm test:cov
|
|
||||||
```
|
|
||||||
|
|
||||||
## Running Tests Locally
|
|
||||||
|
|
||||||
### Individual Project Tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Backend
|
|
||||||
pnpm --filter @maerchenzauber/backend test
|
|
||||||
|
|
||||||
# Mobile
|
|
||||||
pnpm --filter @memoro/mobile test
|
|
||||||
|
|
||||||
# Web (unit tests)
|
|
||||||
pnpm --filter @uload/web test:unit
|
|
||||||
|
|
||||||
# Web (E2E tests)
|
|
||||||
pnpm --filter @uload/web test:e2e
|
|
||||||
|
|
||||||
# Shared package
|
|
||||||
pnpm --filter @manacore/shared-utils test
|
|
||||||
```
|
|
||||||
|
|
||||||
### All Tests for a Project
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run all tests for maerchenzauber
|
|
||||||
pnpm --filter maerchenzauber... test
|
|
||||||
```
|
|
||||||
|
|
||||||
### Watch Mode
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Backend (Jest)
|
|
||||||
pnpm --filter @maerchenzauber/backend test:watch
|
|
||||||
|
|
||||||
# Mobile (Jest)
|
|
||||||
pnpm --filter @memoro/mobile test
|
|
||||||
|
|
||||||
# Web (Vitest)
|
|
||||||
pnpm --filter @uload/web test:unit:watch
|
|
||||||
```
|
|
||||||
|
|
||||||
### With Coverage
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Backend
|
|
||||||
pnpm --filter @maerchenzauber/backend test:cov
|
|
||||||
|
|
||||||
# Mobile
|
|
||||||
pnpm --filter @memoro/mobile test:cov
|
|
||||||
|
|
||||||
# Web
|
|
||||||
pnpm --filter @uload/web test:unit:cov
|
|
||||||
|
|
||||||
# View HTML report
|
|
||||||
open apps/YOUR_PROJECT/apps/backend/coverage/index.html
|
|
||||||
```
|
|
||||||
|
|
||||||
## Coverage Reports
|
|
||||||
|
|
||||||
### View Coverage Locally
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generate coverage
|
|
||||||
pnpm test:cov
|
|
||||||
|
|
||||||
# Open HTML report
|
|
||||||
open coverage/index.html
|
|
||||||
```
|
|
||||||
|
|
||||||
### Coverage Thresholds
|
|
||||||
|
|
||||||
All projects have these default thresholds:
|
|
||||||
|
|
||||||
- **Lines**: 80%
|
|
||||||
- **Functions**: 80%
|
|
||||||
- **Branches**: 80%
|
|
||||||
- **Statements**: 80%
|
|
||||||
|
|
||||||
To override for your project:
|
|
||||||
|
|
||||||
**Jest (Backend/Mobile)**:
|
|
||||||
```javascript
|
|
||||||
module.exports = {
|
|
||||||
preset: '@manacore/test-config/jest-backend',
|
|
||||||
coverageThresholds: {
|
|
||||||
global: {
|
|
||||||
lines: 90, // Higher threshold
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
**Vitest (Web/Shared)**:
|
|
||||||
```typescript
|
|
||||||
export default defineConfig({
|
|
||||||
test: {
|
|
||||||
coverage: {
|
|
||||||
thresholds: {
|
|
||||||
lines: 90,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### CI/CD Coverage
|
|
||||||
|
|
||||||
- Coverage reports are automatically uploaded to Codecov on PR/push to main
|
|
||||||
- Coverage badges available at `https://codecov.io/gh/YOUR_ORG/YOUR_REPO`
|
|
||||||
- PR comments show coverage diff
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Common Issues
|
|
||||||
|
|
||||||
#### "Cannot find module" errors
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clear caches
|
|
||||||
pnpm store prune
|
|
||||||
pnpm install --force
|
|
||||||
|
|
||||||
# Backend: Clear Jest cache
|
|
||||||
pnpm --filter @YOUR_PROJECT/backend test --clearCache
|
|
||||||
|
|
||||||
# Mobile: Clear Metro cache
|
|
||||||
cd apps/YOUR_PROJECT/apps/mobile
|
|
||||||
rm -rf node_modules/.cache
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Transform errors in React Native
|
|
||||||
|
|
||||||
Make sure `transformIgnorePatterns` in `jest.config.js` includes all necessary packages:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
transformIgnorePatterns: [
|
|
||||||
'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@manacore/.*)',
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Svelte component tests fail
|
|
||||||
|
|
||||||
Ensure you have the correct Vite plugin:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { sveltekit } from '@sveltejs/kit/vite';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [sveltekit()],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Playwright browser not installed
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm --filter @YOUR_PROJECT/web exec playwright install chromium
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Tests timeout
|
|
||||||
|
|
||||||
Increase timeout in config:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Vitest
|
|
||||||
export default defineConfig({
|
|
||||||
test: {
|
|
||||||
testTimeout: 30000, // 30 seconds
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Jest
|
|
||||||
module.exports = {
|
|
||||||
testTimeout: 30000,
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Coverage not generating
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Jest: Ensure collectCoverageFrom is set
|
|
||||||
collectCoverageFrom: [
|
|
||||||
'src/**/*.{ts,tsx}',
|
|
||||||
'!**/*.d.ts',
|
|
||||||
],
|
|
||||||
|
|
||||||
# Vitest: Ensure include is set
|
|
||||||
coverage: {
|
|
||||||
include: ['src/**/*.{js,ts,svelte}'],
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Getting Help
|
|
||||||
|
|
||||||
1. Check existing tests in the project for patterns
|
|
||||||
2. Review [docs/TESTING.md](./TESTING.md) for detailed strategies
|
|
||||||
3. Check example tests in [docs/test-examples/](./test-examples/)
|
|
||||||
4. Review CI logs for failure details
|
|
||||||
5. Ask in team chat for project-specific guidance
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
1. **Start with critical paths**: Auth, payments, data integrity
|
|
||||||
2. **Add tests incrementally**: Don't try to test everything at once
|
|
||||||
3. **Follow TDD when possible**: Write tests before code
|
|
||||||
4. **Review coverage**: Aim for 80% minimum, 100% for critical code
|
|
||||||
5. **Keep tests fast**: Unit tests < 100ms, integration < 1s
|
|
||||||
6. **Update this guide**: Add project-specific tips as you learn
|
|
||||||
|
|
||||||
## Resources
|
|
||||||
|
|
||||||
- [Full Testing Strategy](./TESTING.md)
|
|
||||||
- [Test Examples](./test-examples/)
|
|
||||||
- [Jest Documentation](https://jestjs.io/)
|
|
||||||
- [Vitest Documentation](https://vitest.dev/)
|
|
||||||
- [Playwright Documentation](https://playwright.dev/)
|
|
||||||
- [Testing Library](https://testing-library.com/)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Quick Reference Commands**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run all tests
|
|
||||||
pnpm test
|
|
||||||
|
|
||||||
# Run specific project tests
|
|
||||||
pnpm --filter @PROJECT/APP test
|
|
||||||
|
|
||||||
# Run with coverage
|
|
||||||
pnpm --filter @PROJECT/APP test:cov
|
|
||||||
|
|
||||||
# Run in watch mode
|
|
||||||
pnpm --filter @PROJECT/APP test:watch
|
|
||||||
|
|
||||||
# Run E2E tests
|
|
||||||
pnpm --filter @PROJECT/web test:e2e
|
|
||||||
|
|
||||||
# Type check
|
|
||||||
pnpm type-check
|
|
||||||
|
|
||||||
# Lint
|
|
||||||
pnpm lint
|
|
||||||
|
|
||||||
# Format
|
|
||||||
pnpm format
|
|
||||||
```
|
|
||||||
|
|
@ -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>(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
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
@ -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_
|
|
||||||
|
|
@ -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
|
|
||||||
<p class="empty-title">Keine Verbindungen gefunden</p>
|
|
||||||
<p class="empty-description">Elemente werden verbunden, wenn sie gemeinsame Tags haben.</p>
|
|
||||||
```
|
|
||||||
|
|
||||||
**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<string>('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*
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue