Projects included: - maerchenzauber (NestJS backend + Expo mobile + SvelteKit web + Astro landing) - manacore (Expo mobile + SvelteKit web + Astro landing) - manadeck (NestJS backend + Expo mobile + SvelteKit web) - memoro (Expo mobile + SvelteKit web + Astro landing) This commit preserves the current state before monorepo restructuring. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
9.8 KiB
Mana Core Integration Checklist
Use this checklist when integrating @mana-core/nestjs-integration into a new NestJS project.
Prerequisites ✓
- NestJS v10+ application set up
@nestjs/configinstalled- Node.js v18+ and npm/yarn
- Mana Core credentials obtained:
MANA_SERVICE_URLAPP_IDMANA_SUPABASE_SECRET_KEY(service key)
Backend Integration Steps
1. Installation
-
Install the package:
npm install git+https://github.com/Memo-2023/mana-core-nestjs-package.git -
Verify in
package.json:"@mana-core/nestjs-integration": "git+https://github.com/..."
2. Environment Configuration
-
Create/update
.envfile:MANA_SERVICE_URL=https://your-mana-instance.com APP_ID=your-app-id MANA_SUPABASE_SECRET_KEY=your-service-key NODE_ENV=development -
Add to
.env.example(for team reference) -
Add
.envto.gitignore
3. Module Configuration
-
Import
ManaCoreModuleinapp.module.ts -
Configure with
forRootAsync():ManaCoreModule.forRootAsync({ imports: [ConfigModule], useFactory: (configService: ConfigService) => ({ manaServiceUrl: 'your-mana-url', appId: 'your-app-id', serviceKey: configService.get('MANA_SUPABASE_SECRET_KEY'), debug: configService.get('NODE_ENV') === 'development', }), inject: [ConfigService], }) -
Test backend starts without errors
4. Protect Routes with AuthGuard
-
Import
AuthGuardin controller:import { AuthGuard } from '@mana-core/nestjs-integration'; -
Apply to controller or route:
@Controller('protected') @UseGuards(AuthGuard) export class ProtectedController {} -
Test: Verify 401 without token
5. Extract User Information
-
Import
@CurrentUser()decorator:import { CurrentUser } from '@mana-core/nestjs-integration'; -
Use in route handlers:
@Get('profile') async getProfile(@CurrentUser() user: JwtPayload) { return { userId: user.sub, email: user.email }; } -
Test: Verify user data is extracted correctly
6. Integrate Credit System
-
Inject
CreditClientService:constructor(private creditClient: CreditClientService) {} -
Add pre-flight credit validation:
const validation = await this.creditClient.validateCredits( userId, 'operation_type', creditCost, ); -
Add credit consumption after success:
await this.creditClient.consumeCredits( userId, 'operation_type', creditCost, 'Description', metadata, ); -
Handle
InsufficientCreditsException:import { InsufficientCreditsException } from '@mana-core/nestjs-integration'; -
Test: Verify credits are deducted
7. (Optional) Custom Token Decorator
-
Create
@UserToken()decorator for RLS:// decorators/user.decorator.ts export const UserToken = createParamDecorator( (_data: unknown, ctx: ExecutionContext): string => { const request = ctx.switchToHttp().getRequest(); const authHeader = request.headers.authorization; if (authHeader?.startsWith('Bearer ')) { return authHeader.substring(7); } return request.token; }, ); -
Use for database RLS:
@Get() async getData( @CurrentUser() user: JwtPayload, @UserToken() token: string, ) { return await this.db.query(userId, token); }
Frontend Integration Steps
1. Configure API Base URL
-
Create
.envfile:EXPO_PUBLIC_STORYTELLER_BACKEND_URL=http://localhost:3002 -
Create API utility (
utils/api.ts):export const API_BASE_URL = process.env.EXPO_PUBLIC_BACKEND_URL;
2. Create Auth Service
-
Create
services/authService.ts -
Implement sign-in:
signIn: async (email: string, password: string) => { const deviceInfo = await getDeviceInfo(); const response = await fetch(`${BACKEND_URL}/auth/signin`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password, deviceInfo }), }); const data = await response.json(); await storeTokens(data.appToken, data.refreshToken); } -
Implement sign-up
-
Implement sign-out
-
Test: Verify tokens are stored securely
3. Create Token Manager
-
Create
services/tokenManager.ts -
Implement
getValidToken():getValidToken: async () => { let token = await storage.getItem('appToken'); if (isExpiringSoon(token)) { await this.refreshToken(); token = await storage.getItem('appToken'); } return token; } -
Implement
refreshToken():refreshToken: async () => { const refreshToken = await storage.getItem('refreshToken'); const deviceInfo = await getDeviceInfo(); const response = await fetch(`${BACKEND_URL}/auth/refresh`, { method: 'POST', body: JSON.stringify({ refreshToken, deviceInfo }), }); const data = await response.json(); await storeTokens(data.appToken, data.refreshToken); } -
Test: Verify automatic refresh works
4. Create Authenticated API Client
-
Create
fetchWithAuth()function:export async function fetchWithAuth(endpoint: string, options = {}) { const token = await tokenManager.getValidToken(); const response = await fetch(`${API_BASE_URL}${endpoint}`, { ...options, headers: { ...options.headers, 'Authorization': `Bearer ${token}`, }, }); if (response.status === 401) { await tokenManager.refreshToken(); // Retry request } return response; } -
Test: Verify authenticated requests work
5. Handle Credit Errors
-
Create error handling utility:
export function isInsufficientCreditsError(error: any) { return error?.error === 'insufficient_credits'; } -
Handle in UI:
if (data.error === 'insufficient_credits') { showPurchaseCreditsModal({ required: data.requiredCredits, available: data.availableCredits, }); } -
Test: Verify error is displayed correctly
6. Device Management
-
Create
utils/deviceManager.ts:export class DeviceManager { static async getDeviceInfo() { return { deviceId: await getOrCreateDeviceId(), deviceName: Platform.OS, deviceType: Platform.OS as 'ios' | 'android' | 'web', userAgent: getUserAgent(), }; } } -
Include in auth requests
-
Test: Verify device info is sent
Testing Steps
Backend Tests
-
Create unit tests with mocked services:
{ provide: CreditClientService, useValue: { validateCredits: jest.fn().mockResolvedValue({ hasCredits: true, }), consumeCredits: jest.fn(), }, } -
Create integration tests with real Mana Core module
-
Test credit validation flow
-
Test insufficient credits error
-
Run tests:
npm run test
Frontend Tests
-
Test authentication flow
-
Test token refresh
-
Test authenticated API calls
-
Test credit error handling
-
Run tests:
npm run test
Production Deployment
Backend
-
Set production environment variables:
MANA_SERVICE_URL=https://production-mana.com APP_ID=production-app-id MANA_SUPABASE_SECRET_KEY=production-key NODE_ENV=production -
Disable debug logging (
debug: false) -
Test health endpoint
-
Deploy and monitor logs
Frontend
-
Update
.envfor production:EXPO_PUBLIC_BACKEND_URL=https://your-api.com -
Build production bundle
-
Test authentication flow
-
Test API calls
-
Deploy to stores (iOS/Android) or web
Post-Integration Verification
-
Sign-up flow works end-to-end
-
Sign-in flow works end-to-end
-
Token refresh works automatically
-
Protected routes require authentication
-
Credit validation prevents operations
-
Credit consumption records transactions
-
Insufficient credits error handled gracefully
-
Sign-out clears tokens
-
Multi-device support works
Documentation
-
Update README with Mana Core setup instructions
-
Document custom operation types and credit costs
-
Add environment variable documentation
-
Create troubleshooting guide
-
Document API endpoints
Common Issues Checklist
If something doesn't work, check:
- Environment variables are set correctly
- Backend is running and accessible
- Service key is configured (for credit operations)
- Tokens are being stored and retrieved correctly
- Token expiration is being checked
- Device info is being sent with auth requests
- CORS is configured (if using web frontend)
- Network requests are not being blocked
- Debug logging is enabled for troubleshooting
Support Resources
- Full Integration Guide: See
MANA_CORE_INTEGRATION_GUIDE.md - Mana Core Docs: https://docs.mana-core.com
- GitHub Issues: https://github.com/Memo-2023/mana-core-nestjs-package/issues
- Example Code: Check Storyteller project for working implementation
Integration Complete! 🎉
Once all items are checked, your application is fully integrated with Mana Core.
Estimated Time: 2-4 hours for basic integration, 1-2 days for complete implementation with testing.
Next Steps:
- Define your operation types and credit costs
- Implement purchase flow for credits
- Add analytics and monitoring
- Set up role-based access control (if needed)