# Cards Setup Guide ## What's Been Completed Your Mana integration is now **100% complete** with a fully functional credit system! 🎉 ### ✅ Backend (Complete) - [x] ManaModule configured with environment variables - [x] Service key configuration for credit operations - [x] Credit operation types defined (deck creation = 10 mana) - [x] Credit validation before deck creation - [x] Credit consumption after successful operations - [x] Credit balance endpoint (`GET /api/credits/balance`) - [x] AuthGuard protecting all API routes - [x] User profile endpoint with credit balance ### ✅ Frontend (Complete) - [x] Authentication service with sign in/up/out - [x] Token manager with automatic refresh - [x] API client with auth token injection - [x] Device manager for multi-device support - [x] InsufficientCreditsModal component - [x] useInsufficientCredits hook - [x] Credit service for balance checking - [x] Type definitions for credit errors - [x] Example deck creation implementation ### ✅ Documentation (Complete) - [x] README.md with quick start - [x] CREDIT_SYSTEM.md with full documentation - [x] Integration guides (4 files) - [x] Working code example ## Next Steps to Go Live ### 1. Add Your Service Key (5 minutes) ⚠️ REQUIRED The backend needs a service key from Mana to validate and consume credits. **backend/.env**: ```env SERVICE_KEY=your-actual-service-key-here ``` **Where to get it**: Contact Mana admin or check your Mana dashboard. Without this key, credit operations will fail with authentication errors. ### 2. Test the Credit Flow (15 minutes) #### A. Start the backend ```bash cd backend npm run start:dev ``` #### B. Test authentication ```bash # Sign up a test user curl -X POST http://localhost:8080/v1/auth/signup \ -H "Content-Type: application/json" \ -d '{"email":"test@cards.com","password":"test123","username":"testuser"}' # Sign in to get token curl -X POST http://localhost:8080/v1/auth/signin \ -H "Content-Type: application/json" \ -d '{"email":"test@cards.com","password":"test123"}' # Copy the appToken from response export TOKEN="paste-your-token-here" ``` #### C. Test credit balance ```bash curl -H "Authorization: Bearer $TOKEN" \ http://localhost:8080/api/credits/balance ``` Expected response: ```json { "userId": "...", "balance": 100, "currency": "mana", "timestamp": "2025-..." } ``` #### D. Test deck creation (costs 10 mana) ```bash curl -X POST http://localhost:8080/api/decks \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Test Deck","description":"My first deck"}' ``` Expected success response: ```json { "success": true, "userId": "...", "deck": { "id": "deck_...", "name": "Test Deck", "description": "My first deck", "userId": "...", "createdAt": "2025-..." }, "creditsUsed": 10, "message": "Deck created successfully" } ``` #### E. Check updated balance ```bash curl -H "Authorization: Bearer $TOKEN" \ http://localhost:8080/api/credits/balance ``` Should now show `90` instead of `100`. #### F. Test insufficient credits error Create decks until balance < 10, then try one more time: ```bash curl -X POST http://localhost:8080/api/decks \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Another Deck"}' ``` Expected insufficient credits response (400): ```json { "error": "insufficient_credits", "message": "Insufficient mana. Required: 10, Available: 5", "requiredCredits": 10, "availableCredits": 5, "operation": "Create a new deck" } ``` ### 3. Test Frontend Integration (15 minutes) #### A. Start the mobile app ```bash cd apps/mobile npm start ``` Press `i` for iOS, `a` for Android, or `w` for web. #### B. Test authentication 1. Sign up with a new account 2. Verify tokens are stored 3. Sign out and sign in again #### C. Test credit display 1. Navigate to profile or deck creation screen 2. Verify credit balance is displayed 3. Create a deck and see balance update #### D. Test insufficient credits modal 1. Create decks until balance < 10 2. Try creating another deck 3. Verify modal appears with: - Required: 10 mana - Available: [your balance] - Needed: [shortfall] ### 4. Integrate into Your Actual Screens (1-2 hours) Copy the pattern from `apps/mobile/examples/DeckCreationExample.tsx` into your real deck creation screens. #### Quick integration checklist: - [ ] Import `useInsufficientCredits` hook - [ ] Import `InsufficientCreditsModal` component - [ ] Import `creditService` - [ ] Load and display credit balance on screen - [ ] Wrap API calls in try/catch - [ ] Call `insufficientCredits.handleCreditError(error)` in catch - [ ] Render `` ### 5. Add Credit Purchase Flow (Optional) If users can purchase credits: 1. Create a purchase screen in `apps/mobile/app/purchase-credits.tsx` 2. Implement payment integration (Stripe, in-app purchases, etc.) 3. Update `onPurchase` handler in InsufficientCreditsModal: ```typescript onPurchase={() => { insufficientCredits.hideInsufficientCredits(); navigation.navigate('PurchaseCredits'); }} ``` ## Credit Costs Reference These are defined in `backend/src/config/credit-operations.ts`: | Operation | Cost | Location | |-----------|------|----------| | Deck Creation | 10 mana | `POST /api/decks` | | Card Creation | 2 mana | `POST /api/cards` | | AI Card Generation | 5 mana | `POST /api/cards/generate` | | Deck Export | 3 mana | `POST /api/decks/:id/export` | To change costs, edit the `CREDIT_COSTS` object in that file. ## Adding More Billable Operations Example: Make card updates cost 1 mana: ### 1. Add to credit-operations.ts ```typescript export enum CreditOperationType { // ... existing CARD_UPDATE = 'card_update', } export const CREDIT_COSTS = { // ... existing [CreditOperationType.CARD_UPDATE]: 1, }; ``` ### 2. Update the endpoint ```typescript @Put('cards/:id') async updateCard(@CurrentUser() user: any, @Param('id') cardId: string, @Body() data: any) { const operationType = CreditOperationType.CARD_UPDATE; const cost = getCreditCost(operationType); // Validate credits const validation = await this.creditClient.validateCredits(user.id, operationType, cost); if (!validation.hasCredits) { throw new BadRequestException({ error: 'insufficient_credits', requiredCredits: cost, availableCredits: validation.availableCredits, }); } // Update card const updated = await this.updateCardInDatabase(cardId, data); // Consume credits await this.creditClient.consumeCredits( user.id, operationType, cost, `Updated card ${cardId}`, { cardId } ); return { success: true, card: updated, creditsUsed: cost }; } ``` That's it! The frontend automatically handles the error. ## Production Checklist Before deploying to production: ### Backend - [ ] Set `NODE_ENV=production` in production environment - [ ] Add real `SERVICE_KEY` from Mana - [ ] Configure proper CORS for your frontend domain - [ ] Set up proper logging/monitoring - [ ] Add rate limiting - [ ] Set up database backups ### Frontend - [ ] Update `EXPO_PUBLIC_API_URL` to production backend URL - [ ] Test on real devices (iOS + Android) - [ ] Test insufficient credits flow - [ ] Test token refresh - [ ] Test offline behavior - [ ] Build production bundle - [ ] Submit to app stores ## Common Issues & Solutions ### "Service key not configured" **Problem**: Credit operations fail. **Solution**: Add `SERVICE_KEY` to `backend/.env` ### Credits not deducting **Problem**: Balance doesn't change after operations. **Solution**: Check that `consumeCredits()` is called AFTER operation succeeds. ### Modal not showing **Problem**: Error occurs but modal doesn't appear. **Solution**: Make sure: 1. `useInsufficientCredits` hook is used 2. `handleCreditError()` is called in catch block 3. `InsufficientCreditsModal` is rendered ### Android can't connect to backend **Problem**: Frontend can't reach localhost:8080. **Solution**: Use `http://10.0.2.2:8080` for Android emulator. ## Files You Can Customize ### Credit Costs `backend/src/config/credit-operations.ts` - Change costs here ### Modal Appearance `apps/mobile/components/InsufficientCreditsModal.tsx` - Customize UI ### Error Messages `backend/src/controllers/api.controller.ts` - Customize error responses ### Purchase Flow Add `onPurchase` handler to modal in your screens ## Need Help? 1. **Credit System**: See [CREDIT_SYSTEM.md](./CREDIT_SYSTEM.md) 2. **Integration**: See [MANA_CORE_INTEGRATION_GUIDE.md](./MANA_CORE_INTEGRATION_GUIDE.md) 3. **Architecture**: See [MANA_CORE_ARCHITECTURE.md](./MANA_CORE_ARCHITECTURE.md) 4. **Example Code**: See [apps/mobile/examples/DeckCreationExample.tsx](./apps/mobile/examples/DeckCreationExample.tsx) 5. **Mana**: https://github.com/Memo-2023/mana-core-nestjs-package ## Summary You now have: - ✅ Complete authentication system - ✅ Credit validation before operations - ✅ Credit consumption after success - ✅ Insufficient credits modal - ✅ Balance checking - ✅ Full documentation - ✅ Working example **Next action**: Add your `SERVICE_KEY` to `backend/.env` and run the test flow above!