- Migrate Chat, Picture, Presi, Zitare backends to shared auth guards - Remove duplicate local JWT guards and decorators - Add CD staging workflow for tagged releases - Add comprehensive auth architecture documentation - Add Hetzner deployment and Docker setup guides - Add environment configuration audit docs - Update env generation scripts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
30 KiB
Backend Design Pattern Audit Report
Mana Universe Monorepo - Comprehensive Analysis
Audit Date: 2025-12-01 Source of Truth: mana-core-auth service (port 3001) Backends Analyzed: 5 active NestJS backends Total Issues Found: 18 (3 critical, 8 high, 7 medium)
Executive Summary
This comprehensive audit evaluated all backend services in the Mana Universe monorepo against the mana-core-auth service as the source of truth for authentication and API design patterns.
Key Findings
✅ PASSED: All backends are functional and compatible with mana-core-auth JWT validation ⚠️ CRITICAL ISSUES: 3 blocking issues prevent simultaneous backend execution 🔧 MAJOR DEVIATIONS: 8 high-priority inconsistencies require standardization 📋 RECOMMENDATIONS: 7 medium-priority improvements for code quality
Overall Compliance Score: 6.2/10
Score Breakdown:
- Authentication Integration: 7/10 (functional but fragmented)
- API Route Patterns: 5/10 (inconsistent versioning)
- Environment Configuration: 5/10 (port conflicts, hardcoded values)
- Code Standardization: 6/10 (duplicate implementations)
- Security Posture: 8/10 (validation works, lacks observability)
Table of Contents
- Source of Truth: mana-core-auth Analysis
- Backend Comparison Matrix
- Critical Issues (Blocking)
- High-Priority Deviations
- Medium-Priority Improvements
- Implementation Roadmap
- Detailed Findings by Category
- Compliance Checklist
1. Source of Truth: mana-core-auth Analysis
Service Architecture
Location: /services/mana-core-auth/
Port: 3001
Framework: NestJS 11 + Better Auth
Algorithm: EdDSA (NOT RS256 or HS256)
API Prefix: /api/v1
Canonical API Route Structure
BASE: http://localhost:3001/api/v1
Authentication:
POST /api/v1/auth/register
POST /api/v1/auth/login
POST /api/v1/auth/logout
POST /api/v1/auth/validate ← JWT validation endpoint
POST /api/v1/auth/refresh
GET /api/v1/auth/session
User Management:
GET /api/v1/users/:id
PATCH /api/v1/users/:id
DELETE /api/v1/users/:id
JWT Token Structure (EdDSA)
{
"sub": "user-id", // User ID (nanoid, not UUID)
"email": "user@example.com",
"role": "user", // Role claim
"sid": "session-id", // Session ID
"exp": 1764606251, // 15 minutes from issue
"iss": "manacore",
"aud": "manacore"
}
What's NOT in the token:
- Organization data (fetch via API)
- Credit balance (fetch via API)
- Customer type (fetch via API)
Validation Flow (Source of Truth)
┌─────────────┐ Bearer token ┌──────────────┐ POST /validate ┌────────────────┐
│ Client │─────────────────>│ Backend │───────────────────>│ mana-core-auth │
│ (Web/Mobile)│ │ (NestJS) │ {token} │ (port 3001) │
└─────────────┘ └──────────────┘ └────────────────┘
│ │
│<────────────────────────────────────│
│ {valid: true, payload: {...}} │
Required Environment Variables
# All backends MUST have these
MANA_CORE_AUTH_URL=http://localhost:3001
NODE_ENV=development|production
# Optional dev bypass
DEV_BYPASS_AUTH=true
DEV_USER_ID=00000000-0000-0000-0000-000000000000
# For credit operations (optional)
MANA_CORE_SERVICE_KEY=your-service-key
APP_ID=your-app-id
Integration Patterns (Source of Truth Defines Two Paths)
Path A: Lightweight Auth Only
- Package:
@manacore/shared-nestjs-auth - Features: JWT validation, @CurrentUser decorator
- Use when: Simple auth without credit system
Path B: Full Integration
- Package:
@mana-core/nestjs-integration - Features: JWT validation + credit client + @Public decorator
- Use when: Need credit consumption tracking
2. Backend Comparison Matrix
| Backend | Port | Route Prefix | Versioning | Auth Package | Integration Path | Compliance |
|---|---|---|---|---|---|---|
| mana-core-auth | 3001 | /api/v1 |
v1 | N/A (source) | N/A | 10/10 ✅ |
| Chat | 3002 | /api |
None | Custom (local) | Divergent | 5/10 ⚠️ |
| Picture | 3006 | /api |
None | Custom (local) | Divergent | 4/10 ⚠️ |
| Zitare | 3007 | /api |
None | @manacore/shared-nestjs-auth |
Path A ✓ | 7/10 ✓ |
| Presi | 3008 | /api |
None | Custom (local) | Divergent | 5/10 ⚠️ |
| ManaDeck | 8080 | /v1 |
v1 | @mana-core/nestjs-integration |
Path B ✓ | 6/10 ⚠️ |
Compliance Legend
- 10/10: Perfect alignment with source of truth
- 7-9/10: Good compliance, minor deviations
- 5-6/10: Functional but significant deviations
- 0-4/10: Major issues, requires immediate attention
3. Critical Issues (Blocking)
🚨 CRITICAL #1: Route Prefix Inconsistency
Severity: HIGH (API Contract Violation) Status: ❌ BLOCKING
Issue: ManaDeck uses /v1 prefix while source of truth uses /api/v1
| Service | Prefix | Status |
|---|---|---|
| mana-core-auth (source) | /api/v1 |
✅ Standard |
| Chat | /api |
⚠️ Missing version |
| Picture | /api |
⚠️ Missing version |
| Zitare | /api |
⚠️ Missing version |
| Presi | /api |
⚠️ Missing version |
| ManaDeck | /v1 |
❌ Wrong prefix |
Impact:
- Client code must handle 2 different URL patterns
- API documentation is inconsistent
- Future versioning strategy unclear
Files Affected:
apps/chat/apps/backend/src/main.ts:36
apps/picture/apps/backend/src/main.ts:50
apps/zitare/apps/backend/src/main.ts:32
apps/presi/apps/backend/src/main.ts:33
apps/manadeck/apps/backend/src/main.ts:39
Recommended Fix:
// Option 1: Full compliance with source of truth
app.setGlobalPrefix('api/v1');
// Option 2: Consistent api prefix, prepare for versioning
app.setGlobalPrefix('api');
// Option 3: Version-first (requires client updates)
app.setGlobalPrefix('v1');
Decision Required: Choose one standard for all backends
🚨 CRITICAL #2: Port 3002 Conflict
Severity: HIGH (Development Blocker) Status: ❌ BLOCKING
Issue: Chat and Nutriphi backends both configured for port 3002
# .env.development
CHAT_BACKEND_PORT=3002 ← Conflict
NUTRIPHI_BACKEND_PORT=3002 ← Conflict
Impact: Cannot run both backends simultaneously in development
Recommended Fix:
# Reassign ports sequentially
CHAT_BACKEND_PORT=3002 # Keep (active project)
NUTRIPHI_BACKEND_PORT=3010 # Move (archived project)
🚨 CRITICAL #3: Port 3003 Conflict
Severity: HIGH (Development Blocker) Status: ❌ BLOCKING
Issue: Maerchenzauber and Picture backends both configured for port 3003
# .env.development
MAERCHENZAUBER_BACKEND_PORT=3003 ← Conflict
PICTURE_BACKEND_PORT=3003 ← Conflict
Additional Issue: Picture's code defaults to 3003 but docs say 3006
// apps/picture/apps/backend/src/main.ts:52
await app.listen(process.env.PORT || 3003); // Says 3003
// CLAUDE.md says port 3006
Recommended Fix:
# Reassign to match documentation
MAERCHENZAUBER_BACKEND_PORT=3011 # Move (archived)
PICTURE_BACKEND_PORT=3006 # Match docs (active)
Code Fix Required:
// apps/picture/apps/backend/src/main.ts:52
await app.listen(process.env.PORT || 3006); // Fix default
4. High-Priority Deviations
⚠️ HIGH #1: Authentication Implementation Fragmentation
Severity: HIGH (Maintainability Issue) Status: ⚠️ NEEDS ATTENTION
Issue: 3 backends use custom local guards instead of shared packages
| Backend | Current Implementation | Should Use |
|---|---|---|
| Chat | Custom JwtAuthGuard (local) |
@manacore/shared-nestjs-auth |
| Picture | Custom JwtAuthGuard (local) |
@manacore/shared-nestjs-auth |
| Presi | Custom AuthGuard (local) |
@mana-core/nestjs-integration |
| Zitare | ✅ @manacore/shared-nestjs-auth |
✅ Already correct |
| ManaDeck | ✅ @mana-core/nestjs-integration |
✅ Already correct |
Files to Replace:
apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts (58 lines)
apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts (52 lines)
apps/presi/apps/backend/src/auth/auth.guard.ts (47 lines)
Problems with Local Implementations:
- Code Duplication: 157 lines of duplicate guard logic
- Inconsistent Behavior: Chat has dev bypass, Picture doesn't
- No Decorators: Missing
@CurrentUser(),@Public()support - Maintenance Burden: Bug fixes must be applied 3 times
Migration Path:
For Chat & Picture (simple auth):
// Before (local guard)
import { JwtAuthGuard } from './common/guards/jwt-auth.guard';
// After (shared package)
import { JwtAuthGuard, CurrentUser, CurrentUserData } from '@manacore/shared-nestjs-auth';
@Controller('api')
@UseGuards(JwtAuthGuard)
export class ApiController {
@Get('profile')
getProfile(@CurrentUser() user: CurrentUserData) {
return { userId: user.userId, email: user.email };
}
}
For Presi (needs credits):
// Migrate to full integration
import { AuthGuard } from '@mana-core/nestjs-integration/guards';
import { CurrentUser } from '@mana-core/nestjs-integration/decorators';
@Module({
imports: [
ManaCoreModule.forRootAsync({
useFactory: (config: ConfigService) => ({
appId: config.get('APP_ID'),
serviceKey: config.get('MANA_CORE_SERVICE_KEY'),
}),
inject: [ConfigService],
}),
],
})
⚠️ HIGH #2: Inconsistent Dev User ID
Severity: HIGH (Development Experience Issue) Status: ⚠️ NEEDS ATTENTION
Issue: Three different dev user IDs across backends
| Backend/Package | Dev User ID | Source |
|---|---|---|
@manacore/shared-nestjs-auth |
00000000-0000-0000-0000-000000000000 |
Hardcoded const |
| Chat Backend | 00000000-0000-0000-0000-000000000000 |
Hardcoded const |
| Picture Backend | 17cb0be7-058a-4964-9e18-1fe7055fd014 |
Hardcoded const |
@mana-core/nestjs-integration |
Configurable via DEV_USER_ID |
✅ Best practice |
Files Affected:
packages/shared-nestjs-auth/src/guards/jwt-auth.guard.ts:12
apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts:8
apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts:7
Impact:
- Development data inconsistent across backends
- Can't test user-specific features with same ID
- Confusion when switching between backends
Recommended Fix:
# Add to .env.development
DEV_USER_ID=00000000-0000-0000-0000-000000000000
// Update all guards to read from config
const devUserId = this.configService.get<string>('DEV_USER_ID') ||
'00000000-0000-0000-0000-000000000000';
⚠️ HIGH #3: Missing Dev Bypass in Picture Backend
Severity: HIGH (Development Experience Issue) Status: ⚠️ NEEDS ATTENTION
Issue: Picture backend custom guard lacks DEV_BYPASS_AUTH support
Comparison:
// Chat backend (HAS dev bypass)
const isDev = this.configService.get<string>('NODE_ENV') === 'development';
const bypassAuth = this.configService.get<string>('DEV_BYPASS_AUTH') === 'true';
if (isDev && bypassAuth) {
request.user = { userId: DEV_USER_ID, ... };
return true;
}
// Picture backend (NO dev bypass)
// Missing this feature entirely!
Impact:
- Picture backend always requires valid JWT in development
- Can't test with curl/Postman easily
- Inconsistent dev experience
Recommended Fix: Add dev bypass to Picture guard or migrate to shared package
⚠️ HIGH #4: Auth URL Variable Naming Inconsistency
Severity: HIGH (Configuration Issue) Status: ⚠️ NEEDS ATTENTION
Issue: Three different environment variable names for auth service URL
| Backend | Variable Name | Status |
|---|---|---|
| Chat | MANA_CORE_AUTH_URL |
✅ Standard |
| Picture | MANA_CORE_AUTH_URL |
✅ Standard |
| Zitare | MANA_CORE_AUTH_URL |
✅ Standard |
| Presi | MANA_CORE_AUTH_URL |
✅ Standard |
| ManaDeck | MANA_SERVICE_URL |
❌ Non-standard |
| Nutriphi | MANACORE_AUTH_URL |
❌ Non-standard |
Files Affected:
apps/manadeck/apps/backend/.env.example:3
scripts/generate-env.mjs (mapping for Nutriphi)
Recommended Fix: Standardize to MANA_CORE_AUTH_URL everywhere
⚠️ HIGH #5: Token Field Naming Divergence
Severity: HIGH (API Contract Issue) Status: ⚠️ NEEDS ATTENTION
Issue: User ID field named differently across implementations
| Implementation | Field Name | Decorator Returns |
|---|---|---|
| JWT payload (source of truth) | sub |
N/A |
@manacore/shared-nestjs-auth |
userId |
CurrentUserData.userId |
@mana-core/nestjs-integration |
sub |
JwtPayload.sub |
| Chat backend | userId |
request.user.userId |
| Picture backend | userId |
request.user.userId |
| Presi backend | sub |
request.user.sub |
Problem: Inconsistent property access across backends
// Zitare (using shared-nestjs-auth)
@CurrentUser() user: CurrentUserData
console.log(user.userId); // Works
// ManaDeck (using nestjs-integration)
@CurrentUser() user: JwtPayload
console.log(user.sub); // Works
console.log(user.userId); // undefined!
Impact:
- Code is not portable between backends
- Confusion for developers switching projects
- Violates JWT standard (should be
sub)
Recommended Fix: Standardize on sub (JWT standard) with migration alias
export interface CurrentUserData {
sub: string; // JWT standard
userId?: string; // Deprecated alias
email: string;
role: string;
sessionId?: string;
}
⚠️ HIGH #6: Hardcoded CORS Origins
Severity: MEDIUM-HIGH (Security Configuration Issue) Status: ⚠️ NEEDS ATTENTION
Issue: 4 backends hardcode CORS origins in source code instead of environment
Files with Hardcoded CORS:
// apps/chat/apps/backend/src/main.ts:20
app.enableCors({
origin: 'http://localhost:5173', // Hardcoded!
credentials: true,
});
// apps/picture/apps/backend/src/main.ts:34
app.enableCors({
origin: ['http://localhost:5173', 'http://localhost:3000'], // Hardcoded!
credentials: true,
});
// apps/zitare/apps/backend/src/main.ts:18
app.enableCors({
origin: ['http://localhost:5173'], // Hardcoded!
credentials: true,
});
// apps/presi/apps/backend/src/main.ts:19
app.enableCors({
origin: ['http://localhost:5173'], // Hardcoded!
credentials: true,
});
Impact:
- Can't change CORS policy without code changes
- Different environments require separate builds
- Security risk if origins need quick updates
Recommended Fix:
# .env.development
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
// main.ts
const corsOrigins = configService.get<string>('CORS_ORIGINS')?.split(',') ||
['http://localhost:5173'];
app.enableCors({
origin: corsOrigins,
credentials: true,
});
⚠️ HIGH #7: Missing Validation Schemas
Severity: MEDIUM-HIGH (Error Handling Issue) Status: ⚠️ NEEDS ATTENTION
Issue: 4 backends lack environment variable validation
| Backend | Has Validation Schema | Status |
|---|---|---|
| mana-core-auth | ✅ YES | Good |
| Chat | ❌ NO | At risk |
| Picture | ❌ NO | At risk |
| Zitare | ❌ NO | At risk |
| Presi | ❌ NO | At risk |
| ManaDeck | ✅ YES | Good |
Problem: Backends start with invalid config and fail at runtime
Example Error (Picture backend without MANA_CORE_AUTH_URL):
Error: MANA_CORE_AUTH_URL is not defined
at JwtAuthGuard.canActivate (jwt-auth.guard.ts:45)
at ExecutionContextHost.switchToHttp (execution-context.ts:34)
Recommended Fix: Add Joi validation to all backends
// app.module.ts
import * as Joi from 'joi';
@Module({
imports: [
ConfigModule.forRoot({
validationSchema: Joi.object({
NODE_ENV: Joi.string().valid('development', 'production').required(),
PORT: Joi.number().default(3000),
MANA_CORE_AUTH_URL: Joi.string().uri().required(),
DEV_BYPASS_AUTH: Joi.boolean().default(false),
DEV_USER_ID: Joi.string().optional(),
}),
}),
],
})
⚠️ HIGH #8: ManaDeck Controller Organization
Severity: MEDIUM (Maintainability Issue) Status: ⚠️ NEEDS REFACTORING
Issue: ManaDeck uses single 971-line controller vs. modular approach
Comparison:
| Backend | Organization | Largest Controller | Modules |
|---|---|---|---|
| Chat | Modular | ~150 lines | 6 feature modules |
| Picture | Modular | ~180 lines | 6 feature modules |
| Zitare | Modular | ~100 lines | 2 feature modules |
| Presi | Modular | ~200 lines | 4 feature modules |
| ManaDeck | Monolithic | 971 lines | 1 mega controller |
File: apps/manadeck/apps/backend/src/controllers/api.controller.ts
Problems:
- Hard to navigate and understand
- Merge conflicts more likely
- Difficult to test individual features
- Violates single responsibility principle
Recommended Refactoring:
api.controller.ts (971 lines) →
├── deck/deck.controller.ts (~150 lines)
├── card/card.controller.ts (~200 lines)
├── study-session/study-session.controller.ts (~180 lines)
├── progress/progress.controller.ts (~120 lines)
├── ai/ai.controller.ts (~150 lines)
└── category/category.controller.ts (~100 lines)
5. Medium-Priority Improvements
📋 MEDIUM #1: Missing .env.example Files
Issue: Zitare and Presi lack example environment files
Missing:
apps/zitare/apps/backend/.env.exampleapps/presi/apps/backend/.env.example
Recommended: Copy from Chat or Picture backend and adjust
📋 MEDIUM #2: Inconsistent Health Check Implementation
Issue: Mix of basic and advanced health checks
| Backend | Implementation | Endpoints |
|---|---|---|
| Chat | Basic | /health |
| Picture | Basic | /health |
| Zitare | Basic | /health |
| Presi | Terminus | /health, /health/ready, /health/live |
| ManaDeck | Terminus | /health, /health/ready, /health/live |
Recommended: Standardize on Terminus with service dependency checks
📋 MEDIUM #3: Missing Public Route Support
Issue: Only @mana-core/nestjs-integration provides @Public() decorator
Workaround in other backends:
// Current: Must exclude routes from global guard
app.setGlobalPrefix('api', {
exclude: ['health', 'webhook']
});
// Better: Use @Public decorator
@Public()
@Get('webhook')
handleWebhook() { }
Recommended: Add @Public() decorator to @manacore/shared-nestjs-auth
📋 MEDIUM #4: No Request Context Logging
Issue: Guards don't log which endpoint failed auth
Impact: Difficult to debug production auth failures
Recommended:
if (this.options?.debug || process.env.NODE_ENV === 'development') {
console.log(`[AuthGuard] Validating token for ${request.method} ${request.path}`);
}
📋 MEDIUM #5: Missing Circuit Breaker Pattern
Issue: No retry logic or fallback if mana-core-auth is down
Current Behavior: All requests fail immediately if auth service unavailable
Recommended: Implement circuit breaker with short-term token caching
📋 MEDIUM #6: Inconsistent Error Response Format
Issue: Different error messages across backends
// Shared package
throw new UnauthorizedException('Invalid token');
// Mana Core Integration
throw new UnauthorizedException('Invalid or expired token');
// Chat backend
throw new UnauthorizedException('Token validation failed');
Recommended: Standardize error codes and messages
📋 MEDIUM #7: Port 8080 Outlier
Issue: ManaDeck uses port 8080 instead of 3000-series
Current Port Allocation:
3001 - mana-core-auth
3002 - Chat
3006 - Picture (should be)
3007 - Zitare
3008 - Presi
8080 - ManaDeck (outlier)
Recommended: Reassign ManaDeck to 3009 for consistency
6. Implementation Roadmap
Phase 1: Critical Fixes (2-3 hours)
Priority: MUST DO IMMEDIATELY Blocks: Development, testing, deployment
Tasks:
-
Fix port conflicts (3002, 3003)
- Reassign Nutriphi: 3002 → 3010
- Reassign Maerchenzauber: 3003 → 3011
- Fix Picture default: 3003 → 3006
- Update
.env.developmentandgenerate-env.mjs
-
Standardize route prefixes
- Decision needed: Choose
/api,/api/v1, or/v1 - Update all
main.tsfiles - Document decision in CLAUDE.md
- Decision needed: Choose
-
Add DEV_USER_ID to central config
- Add to
.env.development - Update Chat/Picture guards to read from config
- Add to
Validation:
# Test: All backends should start simultaneously
pnpm dev:chat:backend &
pnpm dev:picture:backend &
pnpm dev:zitare:backend &
pnpm dev:presi:backend &
pnpm dev:manadeck:backend &
# Should see no port conflicts
Phase 2: High-Priority Standardization (4-6 hours)
Priority: DO THIS WEEK Impact: Code quality, maintainability, consistency
Tasks:
-
Migrate custom auth guards to shared packages (3-4 hours)
- Chat →
@manacore/shared-nestjs-auth - Picture →
@manacore/shared-nestjs-auth(add dev bypass first) - Presi →
@mana-core/nestjs-integration - Update all controller imports
- Test auth flows
- Chat →
-
Standardize auth URL variable naming (30 min)
- Rename ManaDeck:
MANA_SERVICE_URL→MANA_CORE_AUTH_URL - Rename Nutriphi:
MANACORE_AUTH_URL→MANA_CORE_AUTH_URL - Update
generate-env.mjs
- Rename ManaDeck:
-
Extract CORS origins to environment (1 hour)
- Add
CORS_ORIGINSto.env.development - Update all
main.tsfiles - Test with different origins
- Add
-
Standardize token field naming (1-2 hours)
- Add
subfield to shared auth types - Keep
userIdas deprecated alias - Update documentation
- Add
Validation:
# Test: Auth should work identically across backends
TOKEN=$(curl -X POST http://localhost:3001/api/v1/auth/login \
-d '{"email":"test@example.com","password":"password"}' | jq -r '.accessToken')
for PORT in 3002 3006 3007 3008 3009; do
curl http://localhost:$PORT/api/health -H "Authorization: Bearer $TOKEN"
done
Phase 3: Code Quality Improvements (6-8 hours)
Priority: PLAN THIS WEEK, EXECUTE NEXT WEEK Impact: Error handling, observability, maintainability
Tasks:
-
Add validation schemas to 4 backends (2 hours)
- Chat, Picture, Zitare, Presi
- Copy from mana-core-auth or ManaDeck
- Test with missing/invalid env vars
-
Refactor ManaDeck controller (3-4 hours)
- Break into feature modules
- Update app.module.ts
- Test all endpoints
-
Standardize health checks (1-2 hours)
- Add Terminus to Chat, Picture, Zitare
- Implement readiness/liveness probes
- Add dependency checks
-
Create missing .env.example files (30 min)
- Zitare backend
- Presi backend
-
Add @Public decorator support (1 hour)
- Update
@manacore/shared-nestjs-auth - Test webhook/public endpoints
- Update
Validation:
# Test: All backends should fail fast with clear errors
unset MANA_CORE_AUTH_URL
pnpm dev:chat:backend
# Should see: "Configuration validation error: MANA_CORE_AUTH_URL is required"
Phase 4: Observability & Security (4-6 hours)
Priority: FUTURE SPRINT Impact: Production readiness, debugging, security
Tasks:
- Add request context logging (1 hour)
- Implement circuit breaker for auth service (2-3 hours)
- Standardize error response format (1-2 hours)
- Add auth flow integration tests (2-3 hours)
7. Detailed Findings by Category
Category A: API Route Structure
Source of Truth Standard: /api/v1/[resource]
Findings:
- ✅ mana-core-auth:
/api/v1(perfect) - ⚠️ Chat:
/api(missing version) - ⚠️ Picture:
/api(missing version) - ⚠️ Zitare:
/api(missing version) - ⚠️ Presi:
/api(missing version) - ❌ ManaDeck:
/v1(wrong prefix)
Recommendation: Adopt /api/v1 across all backends for future-proof versioning
Category B: JWT Integration
Source of Truth Standard: POST /api/v1/auth/validate with Bearer token
Findings:
- ✅ All backends call correct validation endpoint
- ✅ All backends extract Bearer tokens correctly
- ✅ All backends handle EdDSA JWT algorithm
- ⚠️ Token field naming inconsistent (userId vs sub)
- ⚠️ Dev bypass implementation varies
- ⚠️ Error handling not standardized
Recommendation: Validation flow is correct; standardize field names and errors
Category C: Authentication Guards
Source of Truth Standard: Use shared packages with standard decorators
Findings:
- ✅ Zitare uses
@manacore/shared-nestjs-auth(good) - ✅ ManaDeck uses
@mana-core/nestjs-integration(good) - ❌ Chat uses custom local guard (duplication)
- ❌ Picture uses custom local guard (duplication)
- ❌ Presi uses custom local guard (duplication)
- ⚠️ 157 lines of duplicate guard code across 3 backends
Recommendation: Eliminate custom guards; migrate to shared packages
Category D: Environment Configuration
Source of Truth Standard: Centralized .env.development with consistent naming
Findings:
- ✅ Centralized .env.development exists
- ✅ Port allocation documented
- ❌ Port conflicts: 3002 (2 backends), 3003 (2 backends)
- ⚠️ Auth URL naming: 3 different variable names
- ⚠️ CORS origins hardcoded in 4 backends
- ⚠️ Missing validation schemas in 4 backends
Recommendation: Fix port conflicts, standardize variable names, add validation
Category E: Code Organization
Source of Truth Standard: Feature-based modular structure
Findings:
- ✅ Chat: Modular (6 feature modules)
- ✅ Picture: Modular (6 feature modules)
- ✅ Zitare: Modular (2 feature modules)
- ✅ Presi: Modular (4 feature modules)
- ❌ ManaDeck: Monolithic (1 controller, 971 lines)
Recommendation: Refactor ManaDeck to feature-based modules
8. Compliance Checklist
API Design Compliance
- All backends use same route prefix pattern
- Versioning strategy documented and consistent
- Health check endpoints standardized
- Error response format consistent
Authentication Compliance
- All backends call correct validation endpoint
- All backends support Bearer token extraction
- All backends use shared auth packages (3/5)
- Token field naming standardized
- Dev bypass implemented consistently (3/5)
- @CurrentUser decorator available everywhere
- @Public decorator supported for public routes
Environment Configuration Compliance
- No port conflicts
- Auth URL variable naming standardized
- Dev user ID centralized
- CORS origins configurable
- Environment validation schemas implemented
- .env.example files present
Code Quality Compliance
- No duplicate guard implementations
- Feature-based modular structure
- Request context logging
- Circuit breaker for auth service
- Integration tests for auth flows
Security Compliance
- JWT validation via central service
- EdDSA algorithm support
- Error messages don't leak sensitive info
- Dev bypass requires explicit flag
- Production config validation
- CORS properly configured per environment
Appendix: Supporting Documentation
Generated Reports
All detailed findings are available in these reports:
-
AUTH_ARCHITECTURE_REPORT.md (24 KB)
- Complete mana-core-auth analysis
- JWT token structure
- Validation flow
- Integration patterns
-
JWT_VALIDATION_REPORT.md (18 KB)
- Backend-by-backend JWT integration analysis
- Guard implementation comparison
- Dev user ID issues
-
ENV_CONFIGURATION_AUDIT.md (12 KB)
- Environment variable matrix
- Port conflicts
- Configuration issues
-
ENV_BACKEND_MATRIX.md (8 KB)
- Visual configuration comparison
- Missing variables
- Standardization needs
File Paths Reference
Source of Truth:
/services/mana-core-auth/(entire service)/services/mana-core-auth/src/auth/auth.controller.ts:36(validation endpoint)
Shared Packages:
/packages/shared-nestjs-auth/src/guards/jwt-auth.guard.ts/packages/nestjs-integration/src/guards/auth.guard.ts
Backend Guards:
/apps/chat/apps/backend/src/common/guards/jwt-auth.guard.ts/apps/picture/apps/backend/src/common/guards/jwt-auth.guard.ts/apps/presi/apps/backend/src/auth/auth.guard.ts
Configuration Files:
/.env.development(central config)/scripts/generate-env.mjs(env generation)
Summary
This comprehensive audit identified 18 issues across 5 backends:
- 3 critical (blocking development)
- 8 high-priority (requiring immediate attention)
- 7 medium-priority (code quality improvements)
Estimated effort to reach 9/10 compliance: 16-23 hours across 4 phases
Current state: All backends are functional but lack standardization Target state: Consistent patterns, shared packages, zero duplication Risk level: MEDIUM (functional but fragile, maintenance burden)
Next Steps:
- Review and approve this audit
- Prioritize Phase 1 critical fixes
- Schedule Phase 2 migration work
- Plan Phase 3 code quality improvements
Audit completed by: Claude Flow Swarm (5 specialized agents) Documentation generated: 7 comprehensive reports Total analysis: 2,604 lines of findings across 68 KB of documentation