banatie-service/CLAUDE.md

12 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

IMPORTANT: Always refer to docs/environment.md for detailed environment configuration, runtime modes, and known issues. Keep that document updated when making infrastructure or configuration changes.

Project Overview

Banatie is a comprehensive monorepo for AI-powered image generation platform featuring multiple applications:

  • API Service (apps/api-service) - Core REST API using Express.js and TypeScript for image generation with Gemini AI
  • Landing Page (apps/landing) - Next.js public website with demo functionality
  • Studio Platform (apps/studio) - Next.js SaaS application with authentication, billing, and subscriptions. Based on https://github.com/nextjs/saas-starter
  • Admin Dashboard (apps/admin) - Next.js administration interface for monitoring and management

The project uses MinIO for object storage and PostgreSQL for data persistence, all orchestrated with Docker Compose.

Development Commands

The project has two separate environments:

Development Mode (Local API + Docker Infrastructure)

From apps/api-service/:

pnpm dev                # Start infrastructure + API with hot reload
pnpm infra:up           # Start only infrastructure (postgres, minio)
pnpm infra:down         # Stop infrastructure
pnpm infra:logs         # View infrastructure logs

Production Mode (All Services in Docker)

From prod-env/:

docker compose up -d              # Start all services
docker compose up -d --build      # Rebuild and start
docker compose down               # Stop all services
docker compose logs -f app        # API logs
docker compose logs -f landing    # Landing logs

Monorepo Commands (from root)

  • pnpm build - Build all applications
  • pnpm lint - Run ESLint on all applications
  • pnpm typecheck - Run TypeScript checking on all applications
  • pnpm test - Run tests
  • pnpm clean - Clean all build outputs and dependencies

Architecture

Monorepo Structure

banatie-service/
├── apps/
│   ├── api-service/           # Express.js REST API (TypeScript)
│   │   ├── docker-compose.yml # Dev infrastructure only
│   │   ├── .env               # Dev config (localhost)
│   │   └── Dockerfile         # Production build
│   ├── landing/               # Next.js landing page
│   │   └── Dockerfile         # Production build
│   ├── studio/                # Next.js SaaS platform
│   └── admin/                 # Next.js admin dashboard
├── packages/
│   └── database/              # Shared database package (Drizzle ORM)
├── prod-env/                  # Production environment
│   ├── docker-compose.yml     # All services (api, landing, infra)
│   ├── .env                   # Prod config (Docker hostnames)
│   └── README.md              # Deployment instructions
├── data/                      # Docker volume data (postgres, minio)
├── docs/
│   └── environment.md         # Environment configuration guide
├── pnpm-workspace.yaml        # Workspace configuration
└── package.json               # Root workspace scripts

API Service Architecture (apps/api-service/)

  • Express App: Configured in src/app.ts with middleware, CORS, and route mounting
  • Server Entry: src/server.ts starts the HTTP server
  • Database Client: src/db.ts - Drizzle ORM connection to PostgreSQL
  • Authentication: src/services/ApiKeyService.ts - API key management and validation
  • Image Generation: src/services/ImageGenService.ts - Gemini AI integration
  • Storage: src/services/MinioStorageService.ts - File uploads to MinIO
  • Route Handling:
    • src/routes/bootstrap.ts - Bootstrap initial master key (one-time)
    • src/routes/admin/keys.ts - API key management (master key required)
    • src/routes/textToImage.ts - Image generation endpoint (API key required)
    • src/routes/upload.ts - File upload endpoint (project key required)
    • src/routes/images.ts - Image serving endpoint (public)

Middleware Stack (API Service)

  • src/middleware/upload.ts - Multer configuration for file uploads (max 3 reference images, 5MB each; single file upload for /api/upload)
  • src/middleware/validation.ts - Express-validator for request validation
  • src/middleware/errorHandler.ts - Centralized error handling and 404 responses
  • src/middleware/auth/validateApiKey.ts - API key authentication
  • src/middleware/auth/requireMasterKey.ts - Master key authorization
  • src/middleware/auth/rateLimiter.ts - Rate limiting per API key (100 req/hour)

TypeScript Configuration (API Service)

  • Path aliases configured in apps/api-service/tsconfig.json:
    • @/* maps to src/*
    • @/types/* maps to src/types/*
    • @/services/* maps to src/services/*
    • @/middleware/* maps to src/middleware/*
    • @/routes/* maps to src/routes/*
    • @/utils/* maps to src/utils/*

Storage & Data

  • MinIO: Object storage for generated images and uploads (port 9000)
  • PostgreSQL: Database for API keys, user data, and metadata (port 5460)
    • Database name: banatie_db
    • User: banatie_user
    • Tables: api_keys, organizations, projects, users, images, upload_sessions
  • File Organization: orgId/projectId/category/year-month/filename.ext

Database Package (packages/database/)

Shared Drizzle ORM package used by API service and future apps:

  • Schema: src/schema/apiKeys.ts - API keys table definition
  • Client Factory: src/client.ts - Database connection creator
  • Migrations: migrations/ - SQL migration files
  • Configuration: drizzle.config.ts - Drizzle Kit configuration

Key table: api_keys

  • Stores hashed API keys (SHA-256)
  • Two types: master (admin, never expires) and project (90-day expiration)
  • Soft delete via is_active flag
  • Audit trail with createdBy, lastUsedAt, createdAt

Environment Configuration

CRITICAL: See docs/environment.md for complete configuration details, known issues, and solutions.

Important: We use TWO .env files with different purposes:

Root .env (Docker Compose Infrastructure)

Used by Docker Compose services (MinIO, Postgres, API container). Key differences from local:

  • DATABASE_URL=postgresql://banatie_user:banatie_secure_password@postgres:5432/banatie_db (Docker network hostname)
  • MINIO_ENDPOINT=minio:9000 (Docker network hostname)
  • MINIO_ROOT_USER and MINIO_ROOT_PASSWORD - MinIO admin credentials
  • All variables are passed to the app container via docker-compose.yml environment section

Development .env (apps/api-service/.env)

Used when running pnpm dev locally (connects to Docker via port forwarding):

  • DATABASE_URL=postgresql://banatie_user:banatie_secure_password@localhost:5460/banatie_db
  • MINIO_ENDPOINT=localhost:9000
  • NOTE: This file is excluded from Docker builds

Production .env (prod-env/.env)

Used when running docker compose in prod-env (internal Docker hostnames):

  • DATABASE_URL=postgresql://banatie_user:banatie_secure_password@postgres:5432/banatie_db
  • MINIO_ENDPOINT=minio:9000
  • IS_DOCKER=true environment variable is set

Secrets (secrets.env)

Sensitive values stored separately (NOT in git):

  • GEMINI_API_KEY - Required for image generation
  • MASTER_KEY, API_KEY - Optional testing keys

See secrets.env.example in each directory for template.

Required Environment Variables

  • DATABASE_URL - PostgreSQL connection string
  • GEMINI_API_KEY - Google Gemini API key (required)
  • MINIO_ENDPOINT - MinIO endpoint
  • MINIO_ACCESS_KEY - MinIO service account key (banatie_service)
  • MINIO_SECRET_KEY - MinIO service account secret (banatie_service_key_2024)
  • MINIO_BUCKET_NAME - Storage bucket name (default: banatie)
  • MINIO_ROOT_USER - MinIO admin user (banatie_admin)
  • MINIO_ROOT_PASSWORD - MinIO admin password
  • PORT - Server port (default: 3000)
  • NODE_ENV - Environment mode
  • CORS_ORIGIN - CORS origin setting

Key Dependencies

API Service

  • @banatie/database - Shared database package (workspace dependency)
  • @google/genai - Google Gemini AI client
  • drizzle-orm - TypeScript ORM (via database package)
  • postgres - PostgreSQL client for Node.js (via database package)
  • express v5 - Web framework
  • multer - File upload handling
  • minio - MinIO client for object storage
  • express-validator - Request validation
  • winston - Logging
  • helmet - Security middleware

Database Package

  • drizzle-orm - TypeScript ORM for SQL databases
  • drizzle-kit - CLI tools for migrations
  • postgres - PostgreSQL client for Node.js

Frontend Apps (Next.js)

  • next - React framework
  • tailwindcss - Utility-first CSS framework
  • typescript - Type safety
  • supabase - Authentication and database (studio app)
  • stripe - Payment processing (studio app)

Service Ports

Service Port Description
API Service 3000 REST API endpoints
Landing Page 3001 Public website
Studio Platform 3002 SaaS application
Admin Dashboard 3003 Administration
PostgreSQL 5460 Database
MinIO API 9000 Object storage
MinIO Console 9001 Storage management

API Endpoints (API Service)

Public Endpoints (No Authentication)

  • GET /health - Health check with uptime and status
  • GET /api/info - API information and limits
  • POST /api/bootstrap/initial-key - Create first master key (one-time only)

Admin Endpoints (Master Key Required)

  • POST /api/admin/keys - Create new API keys (master or project)
  • GET /api/admin/keys - List all API keys
  • DELETE /api/admin/keys/:keyId - Revoke an API key

Protected Endpoints (API Key Required)

  • POST /api/text-to-image - Generate images from text only (JSON)
  • POST /api/upload - Upload single image file to project storage
  • GET /api/images - List generated images

Authentication: All protected endpoints require X-API-Key header

Authentication Setup

First-Time Setup

  1. Start Services: docker compose up -d

  2. Create Master Key:

    curl -X POST http://localhost:3000/api/bootstrap/initial-key
    

    Save the returned key securely!

  3. Create Project Key (for testing):

    curl -X POST http://localhost:3000/api/admin/keys \
      -H "X-API-Key: YOUR_MASTER_KEY" \
      -H "Content-Type: application/json" \
      -d '{"type": "project", "projectId": "test", "name": "Test Key"}'
    

Using API Keys

# Image generation with project key
curl -X POST http://localhost:3000/api/text-to-image \
  -H "X-API-Key: YOUR_PROJECT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "a sunset",
    "filename": "test_image"
  }'

# File upload with project key
curl -X POST http://localhost:3000/api/upload \
  -H "X-API-Key: YOUR_PROJECT_KEY" \
  -F "file=@image.png"

Key Management

  • Master Keys: Never expire, can create/revoke other keys, admin access
  • Project Keys: Expire in 90 days, for image generation only
  • Rate Limits: 100 requests per hour per key
  • Revocation: Soft delete via is_active flag

Development Notes

  • Uses pnpm workspaces for monorepo management (required >= 8.0.0)
  • Node.js >= 18.0.0 required
  • TypeScript with strict mode enabled across all apps
  • ESLint configured with TypeScript and Prettier integration
  • Jest for testing with ts-jest preset (API service)
  • Each app can be developed and deployed independently
  • Docker: Uses monorepo-aware Dockerfiles in each app directory
  • Environment: Two separate configs (dev: apps/api-service/, prod: prod-env/)
  • Secrets: Stored in secrets.env (not tracked in git)