banatie-service/CLAUDE.md

314 lines
12 KiB
Markdown

# 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](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/`:
```bash
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/`:
```bash
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](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**:
```bash
curl -X POST http://localhost:3000/api/bootstrap/initial-key
```
Save the returned key securely!
3. **Create Project Key** (for testing):
```bash
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
```bash
# 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)