# Mana Core Architecture in Storyteller

This document explains the architecture and data flow of the Mana Core integration in the Storyteller project.

## System Architecture

```
┌─────────────────────────────────────────────────────────────────┐
│                         Frontend Layer                          │
│                    (React Native + Expo)                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐         │
│  │ Auth Service │  │ API Client   │  │Token Manager │         │
│  │              │  │              │  │              │         │
│  │ • Sign In    │  │ • fetchWith  │  │ • getValid   │         │
│  │ • Sign Up    │  │   Auth()     │  │   Token()    │         │
│  │ • Sign Out   │  │ • Auto       │  │ • refresh    │         │
│  │ • Device     │  │   Refresh    │  │   Token()    │         │
│  │   Info       │  │ • Error      │  │ • Token      │         │
│  │              │  │   Handling   │  │   Storage    │         │
│  └──────────────┘  └──────────────┘  └──────────────┘         │
│         │                  │                  │                │
└─────────┼──────────────────┼──────────────────┼────────────────┘
          │                  │                  │
          │  HTTP/HTTPS      │  Bearer Token    │  Refresh
          │  Requests        │  in Headers      │  Flow
          ▼                  ▼                  ▼
┌─────────────────────────────────────────────────────────────────┐
│                         Backend Layer                           │
│                    (NestJS + TypeScript)                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌───────────────────────────────────────────────────────────┐ │
│  │            Mana Core NestJS Integration                   │ │
│  ├───────────────────────────────────────────────────────────┤ │
│  │                                                           │ │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐   │ │
│  │  │ AuthGuard    │  │@CurrentUser()│  │ Credit       │   │ │
│  │  │              │  │              │  │ Client       │   │ │
│  │  │ • Validate   │  │ • Extract    │  │ Service      │   │ │
│  │  │   JWT        │  │   User ID    │  │              │   │ │
│  │  │ • Check      │  │ • Extract    │  │ • validate   │   │ │
│  │  │   Expiry     │  │   Email      │  │   Credits()  │   │ │
│  │  │ • Inject     │  │ • Extract    │  │ • consume    │   │ │
│  │  │   User       │  │   Role       │  │   Credits()  │   │ │
│  │  │              │  │              │  │ • get        │   │ │
│  │  │              │  │              │  │   Balance()  │   │ │
│  │  └──────────────┘  └──────────────┘  └──────────────┘   │ │
│  │                                                           │ │
│  └───────────────────────────────────────────────────────────┘ │
│                           │                                     │
│  ┌────────────────────────┼──────────────────────────────────┐ │
│  │   Application Controllers & Services                      │ │
│  ├────────────────────────┼──────────────────────────────────┤ │
│  │                        │                                  │ │
│  │  CharacterController   │   StoryController                │ │
│  │  • generateCharacter   │   • createStory                  │ │
│  │  • getCharacters       │   • getStories                   │ │
│  │  • updateCharacter     │   • updateStory                  │ │
│  │  • deleteCharacter     │   • deleteStory                  │ │
│  │                        │                                  │ │
│  │  SettingsController    │   CreatorsController             │ │
│  │  • getUserSettings     │   • getCreators                  │ │
│  │  • updateSettings      │   • getLanguages                 │ │
│  │                        │                                  │ │
│  └──────────────────────────────────────────────────────────┘ │
│                           │                                     │
└───────────────────────────┼─────────────────────────────────────┘
                            │
                            │  API Requests
                            │  (Auth Validation,
                            │   Credit Operations)
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│                      Mana Core Service                          │
│                 (Authentication & Credits)                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────────────┐  ┌──────────────────────┐           │
│  │ Authentication       │  │ Credit Management    │           │
│  │                      │  │                      │           │
│  │ • User Management    │  │ • Balance Tracking   │           │
│  │ • Token Generation   │  │ • Transaction Log    │           │
│  │ • Token Validation   │  │ • Operation Types    │           │
│  │ • Token Refresh      │  │ • App-Level Track    │           │
│  │ • Device Management  │  │ • Space Credits      │           │
│  │ • OAuth Providers    │  │ • Billing History    │           │
│  │                      │  │                      │           │
│  └──────────────────────┘  └──────────────────────┘           │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

---

## Authentication Flow

### Sign-In Flow

```
┌────────┐                    ┌────────┐                    ┌────────┐
│ Mobile │                    │Backend │                    │  Mana  │
│  App   │                    │ (Nest) │                    │  Core  │
└───┬────┘                    └───┬────┘                    └───┬────┘
    │                             │                             │
    │ 1. Sign In Request          │                             │
    │ POST /auth/signin           │                             │
    │ { email, password,          │                             │
    │   deviceInfo }              │                             │
    ├────────────────────────────►│                             │
    │                             │                             │
    │                             │ 2. Forward to Mana          │
    │                             │ POST /auth/signin           │
    │                             ├────────────────────────────►│
    │                             │                             │
    │                             │                             │ 3. Validate
    │                             │                             │    Credentials
    │                             │                             │
    │                             │ 4. Return Tokens            │
    │                             │ { appToken, refreshToken,   │
    │                             │   user, device }            │
    │                             │◄────────────────────────────┤
    │                             │                             │
    │ 5. Return to Client         │                             │
    │ { appToken, refreshToken }  │                             │
    │◄────────────────────────────┤                             │
    │                             │                             │
    │ 6. Store Tokens             │                             │
    │    in SecureStorage         │                             │
    │                             │                             │
```

### Token Refresh Flow

```
┌────────┐                    ┌────────┐                    ┌────────┐
│ Mobile │                    │Backend │                    │  Mana  │
│  App   │                    │ (Nest) │                    │  Core  │
└───┬────┘                    └───┬────┘                    └───┬────┘
    │                             │                             │
    │ 1. API Request              │                             │
    │    with Expired Token       │                             │
    ├────────────────────────────►│                             │
    │                             │                             │
    │                             │ 2. Validate Token           │
    │                             │    (Expired!)               │
    │                             │                             │
    │ 3. 401 Unauthorized         │                             │
    │◄────────────────────────────┤                             │
    │                             │                             │
    │ 4. Token Refresh Request    │                             │
    │ POST /auth/refresh          │                             │
    │ { refreshToken, deviceInfo }│                             │
    ├────────────────────────────►│                             │
    │                             │                             │
    │                             │ 5. Forward to Mana          │
    │                             ├────────────────────────────►│
    │                             │                             │
    │                             │                             │ 6. Validate
    │                             │                             │    Refresh
    │                             │                             │    Token
    │                             │                             │
    │                             │ 7. New Tokens               │
    │                             │◄────────────────────────────┤
    │                             │                             │
    │ 8. Return New Tokens        │                             │
    │◄────────────────────────────┤                             │
    │                             │                             │
    │ 9. Store New Tokens         │                             │
    │                             │                             │
    │ 10. Retry Original Request  │                             │
    │     with New Token          │                             │
    ├────────────────────────────►│                             │
    │                             │                             │
    │ 11. Success Response        │                             │
    │◄────────────────────────────┤                             │
```

---

## Protected Route Flow

### With AuthGuard

```
┌────────┐                    ┌────────┐                    ┌────────┐
│ Mobile │                    │Backend │                    │  Mana  │
│  App   │                    │ (Nest) │                    │  Core  │
└───┬────┘                    └───┬────┘                    └───┬────┘
    │                             │                             │
    │ 1. GET /character           │                             │
    │    Authorization: Bearer    │                             │
    │    eyJhbGc...               │                             │
    ├────────────────────────────►│                             │
    │                             │                             │
    │                             │ 2. AuthGuard                │
    │                             │    intercepts               │
    │                             │                             │
    │                             │ 3. Validate Token           │
    │                             ├────────────────────────────►│
    │                             │                             │
    │                             │ 4. Token Valid              │
    │                             │    + User Payload           │
    │                             │◄────────────────────────────┤
    │                             │                             │
    │                             │ 5. Inject user into         │
    │                             │    request object           │
    │                             │                             │
    │                             │ 6. Execute Controller       │
    │                             │    Method                   │
    │                             │    @CurrentUser()           │
    │                             │    extracts user            │
    │                             │                             │
    │ 7. Response with Data       │                             │
    │◄────────────────────────────┤                             │
    │                             │                             │
```

---

## Credit Management Flow

### Character Creation (20 Credits)

```
┌────────┐                    ┌────────┐                    ┌────────┐
│ Mobile │                    │Backend │                    │  Mana  │
│  App   │                    │ (Nest) │                    │  Core  │
└───┬────┘                    └───┬────┘                    └───┬────┘
    │                             │                             │
    │ 1. Create Character Request │                             │
    │ POST /character/generate    │                             │
    │ { name, description }       │                             │
    ├────────────────────────────►│                             │
    │                             │                             │
    │                             │ 2. Pre-flight Check         │
    │                             │    validateCredits()        │
    │                             │    userId, "character_      │
    │                             │    creation", 20            │
    │                             ├────────────────────────────►│
    │                             │                             │
    │                             │                             │ 3. Check
    │                             │                             │    Balance
    │                             │                             │
    │                             │ 4. Validation Result        │
    │                             │ { hasCredits: true,         │
    │                             │   availableCredits: 100 }   │
    │                             │◄────────────────────────────┤
    │                             │                             │
    │                             │ 5. If hasCredits = false    │
    │                             │    Return error             │
    │◄────────────────────────────┤                             │
    │                             │                             │
    │ 6. Show "Buy Credits" Modal │                             │
    │                             │                             │
    │                             │ 7. If hasCredits = true     │
    │                             │    Proceed with creation    │
    │                             │    • Generate images        │
    │                             │    • Store in database      │
    │                             │                             │
    │                             │ 8. Consume Credits          │
    │                             │    consumeCredits()         │
    │                             │    userId, "character_      │
    │                             │    creation", 20,           │
    │                             │    "Created: Cat"           │
    │                             ├────────────────────────────►│
    │                             │                             │
    │                             │                             │ 9. Deduct
    │                             │                             │    Credits
    │                             │                             │
    │                             │ 10. Transaction Receipt     │
    │                             │ { transactionId,            │
    │                             │   remainingBalance: 80 }    │
    │                             │◄────────────────────────────┤
    │                             │                             │
    │ 11. Success Response        │                             │
    │ { data: { characterId,      │                             │
    │   images, ... } }           │                             │
    │◄────────────────────────────┤                             │
    │                             │                             │
```

### Story Creation (100 Credits)

```
Same flow as character creation, but with:
- operationType: "story_creation"
- amount: 100
- More expensive due to:
  * Story text generation
  * Multiple image generations (10 pages)
  * Translation to German
```

---

## Credit Operation Types in Storyteller

```typescript
// Defined in Storyteller
type StorytellerOperations =
  | 'character_creation'  // 20 credits
  | 'story_creation';     // 100 credits

// Credit Costs
const CREDIT_COSTS = {
  character_creation: 20,  // 3 image variants
  story_creation: 100,     // 10-page story with images + translation
};
```

---

## Data Flow: Complete Example

### Creating a Story with Credits

1. **Frontend**: User fills story form
   ```typescript
   const createStory = async () => {
     const response = await fetchWithAuth('/story', {
       method: 'POST',
       body: JSON.stringify({
         characters: [characterId],
         storyDescription: 'A magical forest adventure',
         authorId: 'author-1',
         illustratorId: 'illustrator-1',
       }),
     });

     const data = await response.json();

     if (data.error === 'insufficient_credits') {
       navigation.navigate('PurchaseCredits', {
         required: 100,
         available: data.availableCredits,
       });
     }
   };
   ```

2. **Backend Controller**: Story creation endpoint
   ```typescript
   @Post()
   @UseGuards(AuthGuard)
   async createStory(
     @Body() dto: CreateStoryDto,
     @CurrentUser() user: JwtPayload,
   ) {
     // Pre-flight check
     const validation = await this.creditClient.validateCredits(
       user.sub,
       'story_creation',
       100,
     );

     if (!validation.hasCredits) {
       throw new BadRequestException({
         error: 'insufficient_credits',
         requiredCredits: 100,
         availableCredits: validation.availableCredits,
       });
     }

     // Create story
     const result = await this.storyService.createStory({
       userId: user.sub,
       characterId: dto.characters[0],
       storyDescription: dto.storyDescription,
     });

     // Consume credits
     await this.creditClient.consumeCredits(
       user.sub,
       'story_creation',
       100,
       `Created story: ${result.storyData.title}`,
       { storyId: result.storyData.id },
     );

     return result;
   }
   ```

3. **Mana Core**: Processes credit operations
   - Validates user has sufficient credits
   - Deducts credits from user's balance
   - Records transaction in ledger
   - Returns transaction ID and new balance
   - Tracks operation by app ID

---

## Security Architecture

### Token Security

```
┌─────────────────────────────────────────────────────────┐
│                    Token Structure                      │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Access Token (appToken):                              │
│  • JWT format                                           │
│  • Short-lived (15 minutes)                             │
│  • Contains: { sub, email, role, exp, iat }            │
│  • Used for API authentication                          │
│  • Stored in SecureStorage (mobile)                     │
│                                                         │
│  Refresh Token:                                         │
│  • Long-lived (30 days)                                 │
│  • Used to get new access token                         │
│  • Single-use (rotated on refresh)                      │
│  • Device-specific                                      │
│  • Stored in SecureStorage (mobile)                     │
│                                                         │
└─────────────────────────────────────────────────────────┘
```

### AuthGuard Protection

```typescript
// All routes under @UseGuards(AuthGuard) are protected:

✅ Validates JWT signature
✅ Checks token expiration
✅ Extracts user payload
✅ Injects user into request
✅ Returns 401 if invalid

// Usage:
@Controller('character')
@UseGuards(AuthGuard)  // ← Protects all routes in controller
export class CharacterController {
  @Get()
  getCharacters(@CurrentUser() user: JwtPayload) {
    // user is automatically available here
  }
}
```

---

## Database Integration (Supabase RLS)

### Row Level Security with JWT

Storyteller uses Supabase with Row Level Security (RLS). The `@UserToken()` decorator extracts the raw JWT for RLS:

```typescript
@Get()
async getCharacters(
  @CurrentUser() user: JwtPayload,  // Validated user
  @UserToken() token: string,       // Raw JWT for RLS
) {
  // Pass token to Supabase client
  const characters = await this.supabase
    .from('characters')
    .select('*')
    .eq('user_id', user.sub)
    .setAuth(token);  // RLS enforces user_id match

  return { data: characters };
}
```

**Why Both Decorators?**
- `@CurrentUser()`: Validated user data for business logic
- `@UserToken()`: Raw JWT for database RLS enforcement

---

## Environment Configuration

### Backend `.env`

```env
# Mana Core (Required)
MANA_SERVICE_URL=https://mana-core-middleware-111768794939.europe-west3.run.app
APP_ID=8d2f5ddb-e251-4b3b-8802-84022a7ac77f
MANA_SUPABASE_SECRET_KEY=your-service-key

# Application
NODE_ENV=development
PORT=3002

# Database (Supabase)
MAERCHENZAUBER_SUPABASE_URL=your-supabase-url
MAERCHENZAUBER_SUPABASE_ANON_KEY=your-anon-key
```

### Frontend `.env`

```env
# Backend URL
EXPO_PUBLIC_STORYTELLER_BACKEND_URL=http://localhost:3002

# For production:
# EXPO_PUBLIC_STORYTELLER_BACKEND_URL=https://your-api.com
```

---

## Key Takeaways

### What Mana Core Provides

1. **Authentication System**
   - ✅ Email/password sign-in/sign-up
   - ✅ Google OAuth integration
   - ✅ Apple Sign-in integration
   - ✅ JWT token generation and validation
   - ✅ Token refresh mechanism
   - ✅ Multi-device management

2. **Credit Management**
   - ✅ Balance tracking per user
   - ✅ Pre-flight validation
   - ✅ Transaction recording
   - ✅ Operation type tracking
   - ✅ App-level tracking
   - ✅ Metadata support

3. **Developer Experience**
   - ✅ Simple module configuration
   - ✅ Guards for route protection
   - ✅ Decorators for data extraction
   - ✅ TypeScript support
   - ✅ Error handling utilities
   - ✅ Debug logging

### What You Need to Implement

1. **Application Logic**
   - Define operation types
   - Set credit costs
   - Implement business logic
   - Handle errors

2. **Frontend Integration**
   - Token storage
   - API client with auto-refresh
   - Error handling UI
   - Purchase flow (if needed)

3. **Testing**
   - Unit tests with mocked services
   - Integration tests
   - End-to-end flows

---

## Performance Considerations

### Token Caching
- Frontend caches tokens in SecureStorage
- Token validation is fast (local check + remote if needed)
- Refresh only when needed (5-minute buffer)

### Credit Operations
- Pre-flight validation is lightweight
- Consumption happens after success
- No blocking during operations

### Best Practices
1. Always validate credits BEFORE expensive operations
2. Consume credits AFTER successful operations
3. Handle `InsufficientCreditsException` gracefully
4. Log all credit transactions for audit

---

## Next Steps

After understanding the architecture:

1. **Review the Integration Guide**: See `MANA_CORE_INTEGRATION_GUIDE.md`
2. **Follow the Checklist**: Use `MANA_CORE_INTEGRATION_CHECKLIST.md`
3. **Study the Code**: Examine Storyteller's implementation
4. **Test Thoroughly**: Ensure all flows work correctly
5. **Monitor in Production**: Track usage and errors

---

## Questions?

- **Full Guide**: `MANA_CORE_INTEGRATION_GUIDE.md`
- **Checklist**: `MANA_CORE_INTEGRATION_CHECKLIST.md`
- **Mana Docs**: https://docs.mana-core.com
- **GitHub**: https://github.com/Memo-2023/mana-core-nestjs-package
