managarten/manadeck
Till-JS be9df4aa85 feat(manadeck): complete Supabase removal from frontend and backend
- Frontend: Updated deckStore to use fetch API calls to backend
- Frontend: Removed supabase.ts utility and @supabase/supabase-js dependency
- Backend: Removed SupabaseService and supabase.service.ts
- Backend: Updated validation schema to use DATABASE_URL
- Backend: Updated health controller to remove Supabase check
- Backend: Marked AI generation endpoint as not implemented (was using Edge Functions)

Phase 4 of PostgreSQL/Drizzle migration complete.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 02:49:34 +01:00
..
.github/workflows chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
apps feat(manadeck): complete Supabase removal from frontend and backend 2025-11-25 02:49:34 +01:00
backend feat(manadeck): complete Supabase removal from frontend and backend 2025-11-25 02:49:34 +01:00
supabase chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
.gitignore chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
CI_CD_SETUP_GUIDE.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
CREDIT_SYSTEM.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
DEPLOYMENT_CHECKLIST.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
EDGE_FUNCTION_FIX.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
MANA_CORE_ARCHITECTURE.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
MANA_CORE_INTEGRATION_CHECKLIST.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
MANA_CORE_INTEGRATION_GUIDE.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
MANA_CORE_README.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
README.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
SETUP_GUIDE.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00

Manadeck

A deck management system with Mana Core authentication and credit system integration.

Features

  • 🔐 Mana Core Authentication - Complete auth system with JWT tokens, device tracking, and automatic token refresh
  • Credit System - Mana-based billing for operations (10 mana to create a deck, 5 for AI features, etc.)
  • 📱 React Native/Expo - Cross-platform mobile app (iOS, Android, Web)
  • 🚀 NestJS Backend - Type-safe API with AuthGuard protection
  • 💾 Supabase - Database and real-time features
  • 🎨 NativeWind - Tailwind CSS for React Native styling

Quick Start

Prerequisites

  • Node.js 18+
  • npm or yarn
  • Expo CLI (npm install -g expo-cli)
  • Supabase account
  • Mana Core credentials (APP_ID, SERVICE_KEY)

Backend Setup

  1. Navigate to backend directory:

    cd backend
    
  2. Install dependencies:

    npm install
    
  3. Configure environment variables:

    cp .env.example .env
    

    Edit .env and add your credentials:

    # Mana Core
    MANA_SERVICE_URL=https://mana-core-middleware-111768794939.europe-west3.run.app
    APP_ID=your-app-id-from-mana-core
    SERVICE_KEY=your-service-key-from-mana-core  # Required for credits
    
    # Supabase
    SUPABASE_URL=https://your-project.supabase.co
    SUPABASE_ANON_KEY=your-anon-key
    SUPABASE_SERVICE_KEY=your-service-key
    
    # Server
    NODE_ENV=development
    PORT=8080
    
  4. Start the backend:

    npm run start:dev
    

    Backend will be available at http://localhost:8080

Frontend Setup

  1. Navigate to mobile app directory:

    cd apps/mobile
    
  2. Install dependencies:

    npm install
    
  3. Configure environment:

    cp .env.example .env
    

    Edit .env:

    # Supabase
    EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
    EXPO_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
    
    # Backend API
    EXPO_PUBLIC_API_URL=http://localhost:8080  # For local development
    # EXPO_PUBLIC_API_URL=https://your-production-backend.com  # For production
    
  4. Start Expo:

    npm start
    
  5. Run on platform:

    • Press i for iOS simulator
    • Press a for Android emulator
    • Press w for web browser

Architecture

┌─────────────────────┐
│   Mobile App        │  React Native + Expo
│   (Frontend)        │  - Authentication UI
│                     │  - Credit balance display
│                     │  - Deck management
└──────────┬──────────┘
           │ HTTPS/JSON
           │ Bearer Token Auth
           ▼
┌─────────────────────┐
│   Backend API       │  NestJS
│                     │  - AuthGuard protection
│                     │  - Credit validation
│                     │  - Business logic
└──────────┬──────────┘
           │
           ├─────────────────────┐
           │                     │
           ▼                     ▼
┌─────────────────┐   ┌──────────────────┐
│  Mana Core      │   │  Supabase        │
│  - Auth         │   │  - Database      │
│  - Credits      │   │  - Storage       │
│  - Transactions │   │  - Real-time     │
└─────────────────┘   └──────────────────┘

Credit System

Manadeck uses Mana as its credit currency. Operations cost credits:

Operation Cost
Create Deck 10 mana
Create Card 2 mana
AI Card Generation 5 mana
Export Deck 3 mana

How it Works

  1. Pre-flight Validation: Backend checks if user has enough credits
  2. Operation: Performs the requested operation (create deck, etc.)
  3. Consumption: Deducts credits only if operation succeeds
  4. Response: Returns success + credits used

Frontend Integration

The frontend automatically handles insufficient credits with a modal:

import { useInsufficientCredits } from '../hooks/useInsufficientCredits';
import { InsufficientCreditsModal } from '../components/InsufficientCreditsModal';

function MyScreen() {
  const insufficientCredits = useInsufficientCredits();

  const handleAction = async () => {
    try {
      await post('/api/decks', data);
    } catch (error) {
      // Automatically shows modal if insufficient credits
      insufficientCredits.handleCreditError(error);
    }
  };

  return (
    <>
      <Button onPress={handleAction} />
      <InsufficientCreditsModal {...insufficientCredits} />
    </>
  );
}

Full documentation: See CREDIT_SYSTEM.md

API Endpoints

Authentication (via Mana Core)

  • POST /v1/auth/signin - Sign in
  • POST /v1/auth/signup - Sign up
  • POST /v1/auth/refresh - Refresh token
  • POST /v1/auth/logout - Sign out

Protected Endpoints (require Bearer token)

  • GET /api/profile - Get user profile + credit balance
  • GET /api/credits/balance - Get credit balance
  • GET /api/decks - List user's decks
  • POST /api/decks - Create deck (costs 10 mana)
  • PUT /api/decks/:id - Update deck
  • DELETE /api/decks/:id - Delete deck
  • GET /api/cards - List cards
  • POST /api/cards - Create card (costs 2 mana)

Public Endpoints

  • GET /public/health - Health check
  • GET /public/version - API version
  • GET /public/featured-decks - Featured decks (optional auth)

Project Structure

manadeck/
├── backend/                    # NestJS backend
│   ├── src/
│   │   ├── config/
│   │   │   ├── credit-operations.ts   # Credit costs & operation types
│   │   │   └── validation.schema.ts   # Environment validation
│   │   ├── controllers/
│   │   │   ├── api.controller.ts      # Protected endpoints
│   │   │   ├── public.controller.ts   # Public endpoints
│   │   │   └── health.controller.ts   # Health checks
│   │   ├── services/
│   │   │   └── supabase.service.ts    # Supabase integration
│   │   ├── app.module.ts              # Main module (Mana Core config)
│   │   └── main.ts                    # Entry point
│   ├── .env                    # Environment variables
│   └── package.json
│
├── apps/
│   ├── mobile/                # React Native/Expo app
│   ├── web/                   # Web app
│   └── landing/               # Landing page
│   ├── app/                    # Expo Router screens
│   │   ├── (tabs)/            # Tab navigation
│   │   └── _layout.tsx        # Root layout
│   ├── components/
│   │   └── InsufficientCreditsModal.tsx   # Credit error modal
│   ├── services/
│   │   ├── authService.ts     # Authentication
│   │   ├── tokenManager.ts    # Token refresh & management
│   │   └── creditService.ts   # Credit operations
│   ├── hooks/
│   │   └── useInsufficientCredits.ts  # Credit error handling
│   ├── types/
│   │   ├── auth.ts            # Auth types
│   │   └── credits.ts         # Credit types
│   ├── utils/
│   │   ├── apiClient.ts       # Authenticated API client
│   │   └── deviceManager.ts   # Device info
│   ├── examples/
│   │   └── DeckCreationExample.tsx    # Usage example
│   ├── .env                   # Environment variables
│   └── package.json
│
├── CREDIT_SYSTEM.md           # Credit system documentation
├── MANA_CORE_INTEGRATION_GUIDE.md
├── MANA_CORE_INTEGRATION_CHECKLIST.md
├── MANA_CORE_ARCHITECTURE.md
├── MANA_CORE_README.md
└── README.md                  # This file

Development

Backend

cd backend

# Development with hot reload
npm run start:dev

# Build for production
npm run build

# Run production build
npm run start:prod

# Linting
npm run lint

# Tests
npm run test

Frontend

cd apps/mobile

# Start Expo dev server
npm start

# Run on iOS
npm run ios

# Run on Android
npm run android

# Run on web
npm run web

# Linting & formatting
npm run lint
npm run format

# Build with EAS
npm run build:dev      # Development build
npm run build:preview  # Preview build
npm run build:prod     # Production build

Environment Variables

Backend Required Variables

Variable Description Example
MANA_SERVICE_URL Mana Core service URL https://mana-core-middleware-*.run.app
APP_ID Your app ID from Mana Core cea4bfc6-a4de-4e17-91e2-54275940156e
SERVICE_KEY Service key for credit operations Get from Mana Core
SUPABASE_URL Supabase project URL https://abc.supabase.co
SUPABASE_ANON_KEY Supabase anonymous key Your anon key
PORT Backend port 8080

Frontend Required Variables

Variable Description Example
EXPO_PUBLIC_SUPABASE_URL Supabase project URL https://abc.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY Supabase anonymous key Your anon key
EXPO_PUBLIC_API_URL Backend API URL http://localhost:8080

Testing

Backend Testing

The backend includes example tests in backend/src/app.controller.spec.ts. To add credit system tests:

import { CreditClientService } from '@mana-core/nestjs-integration/services';

// Mock in test setup
{
  provide: CreditClientService,
  useValue: {
    validateCredits: jest.fn().mockResolvedValue({
      hasCredits: true,
      availableCredits: 100,
    }),
    consumeCredits: jest.fn(),
  },
}

Manual Testing

  1. Test authentication:

    # Sign up
    curl -X POST http://localhost:8080/v1/auth/signup \
      -H "Content-Type: application/json" \
      -d '{"email":"test@example.com","password":"password123","username":"testuser"}'
    
    # Sign in
    curl -X POST http://localhost:8080/v1/auth/signin \
      -H "Content-Type: application/json" \
      -d '{"email":"test@example.com","password":"password123"}'
    
  2. Test protected endpoint:

    export TOKEN="your-jwt-token-from-signin"
    
    curl -H "Authorization: Bearer $TOKEN" \
      http://localhost:8080/api/profile
    
  3. Test credit system:

    # Check balance
    curl -H "Authorization: Bearer $TOKEN" \
      http://localhost:8080/api/credits/balance
    
    # Create deck (costs 10 mana)
    curl -X POST http://localhost:8080/api/decks \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name":"My Deck","description":"Test deck"}'
    

Troubleshooting

Backend won't start

  • Check all environment variables are set
  • Verify Mana Core credentials are correct
  • Check if port 8080 is available

Credits not working

  • Ensure SERVICE_KEY is set in backend .env
  • Check backend logs for credit validation errors
  • Verify user has credits in Mana Core dashboard

Frontend can't connect to backend

  • Check EXPO_PUBLIC_API_URL is correct
  • For Android emulator, use http://10.0.2.2:8080 instead of localhost
  • Verify backend is running

Token refresh fails

  • Check device info is being sent with refresh requests
  • Verify refresh token is stored correctly
  • Check network connectivity

Documentation

Resources

License

Private project - All rights reserved

Support

For issues related to: