10 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
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
Use docker compose command for Docker services (v3 version).
Infrastructure
docker compose up -d postgres minio storage-init- Start database and storage servicesdocker compose up -d- Start all services including the API app containerdocker compose down- Stop all services
Monorepo Commands (from root)
pnpm dev- Start all applications in development modepnpm dev:api- Start API service only (apps/api-service)pnpm dev:landing- Start landing page only (apps/landing)pnpm dev:studio- Start studio platform only (apps/studio)pnpm dev:admin- Start admin dashboard only (apps/admin)
Build & Production
pnpm build- Build all applicationspnpm build:api- Build API service onlypnpm start:api- Start API service in production modepnpm start:landing- Start landing page in production mode
Code Quality (runs across all apps)
pnpm lint- Run ESLint on all applicationspnpm typecheck- Run TypeScript checking on all applicationspnpm test- Run tests (currently API service only)pnpm clean- Clean all build outputs and dependencies
Architecture
Monorepo Structure
banatie-service/
├── apps/
│ ├── api-service/ # Express.js REST API (TypeScript)
│ ├── landing/ # Next.js landing page
│ ├── studio/ # Next.js SaaS platform
│ └── admin/ # Next.js admin dashboard
├── packages/
│ └── database/ # Shared database package (Drizzle ORM)
├── data/ # Docker volume data (postgres, minio)
├── docker-compose.yml # Infrastructure services
├── pnpm-workspace.yaml # Workspace configuration
└── package.json # Root workspace scripts
API Service Architecture (apps/api-service/)
- Express App: Configured in
src/app.tswith middleware, CORS, and route mounting - Server Entry:
src/server.tsstarts 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 validationsrc/middleware/errorHandler.ts- Centralized error handling and 404 responsessrc/middleware/auth/validateApiKey.ts- API key authenticationsrc/middleware/auth/requireMasterKey.ts- Master key authorizationsrc/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 tosrc/*@/types/*maps tosrc/types/*@/services/*maps tosrc/services/*@/middleware/*maps tosrc/middleware/*@/routes/*maps tosrc/routes/*@/utils/*maps tosrc/utils/*
Storage & Data
- MinIO: Object storage for generated images and uploads (port 9000)
- PostgreSQL: Database for API keys, user data, and metadata (port 5434)
- Database name:
banatie_db - User:
banatie_user - Tables:
api_keys,organizations,projects,users,images,upload_sessions
- Database name:
- 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) andproject(90-day expiration) - Soft delete via
is_activeflag - Audit trail with
createdBy,lastUsedAt,createdAt
Environment Configuration
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_USERandMINIO_ROOT_PASSWORD- MinIO admin credentials- All variables are passed to the app container via docker-compose.yml environment section
API Service .env (Local Development Only)
Located at apps/api-service/.env - used ONLY when running pnpm dev:api locally:
DATABASE_URL=postgresql://banatie_user:banatie_secure_password@localhost:5434/banatie_db(port-forwarded)MINIO_ENDPOINT=localhost:9000(port-forwarded)- NOTE: This file is excluded from Docker builds (see Dockerfile.mono)
Required Environment Variables
DATABASE_URL- PostgreSQL connection stringGEMINI_API_KEY- Google Gemini API key (required)MINIO_ENDPOINT- MinIO endpointMINIO_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 passwordPORT- Server port (default: 3000)NODE_ENV- Environment modeCORS_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 | 5434 | 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 statusGET /api/info- API information and limitsPOST /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 keysDELETE /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 storageGET /api/images- List generated images
Authentication: All protected endpoints require X-API-Key header
Authentication Setup
First-Time Setup
-
Start Services:
docker compose up -d -
Create Master Key:
curl -X POST http://localhost:3000/api/bootstrap/initial-keySave the returned key securely!
-
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_activeflag
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 Dockerfile (
Dockerfile.mono) that includes workspace packages