docs: update

This commit is contained in:
Oleg Proskurin 2025-10-01 00:23:55 +07:00
parent 298898f79d
commit c2b161d71c
2 changed files with 289 additions and 14 deletions

103
CLAUDE.md
View File

@ -56,6 +56,8 @@ banatie-service/
│ ├── 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
@ -66,15 +68,23 @@ banatie-service/
- **Express App**: Configured in `src/app.ts` with middleware, CORS, and route mounting
- **Server Entry**: `src/server.ts` starts the HTTP server
- **Image Generation**: `src/services/ImageGenService.ts` handles Gemini AI integration
- **Storage**: `src/services/MinioStorageService.ts` handles file uploads to MinIO
- **Route Handling**: `src/routes/generate.ts` contains the main API endpoint logic
- **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/generate.ts` - Image generation endpoint (API key required)
### Middleware Stack (API Service)
- `src/middleware/upload.ts` - Multer configuration for file uploads (max 3 files, 5MB each)
- `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)
@ -89,13 +99,32 @@ banatie-service/
### Storage & Data
- **MinIO**: Object storage for generated images and uploads (port 9000)
- **PostgreSQL**: Database for user data, metadata (port 5434)
- **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`
- **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
### Root Environment (`.env.docker`)
- `DATABASE_URL` - PostgreSQL connection string (for Docker: `postgresql://banatie_user:banatie_secure_password@postgres:5432/banatie_db`)
- `MINIO_ROOT_USER` - MinIO admin username
- `MINIO_ROOT_PASSWORD` - MinIO admin password
@ -103,6 +132,7 @@ banatie-service/
Required environment variables:
- `DATABASE_URL` - PostgreSQL connection string (for local dev: `postgresql://banatie_user:banatie_secure_password@localhost:5434/banatie_db`)
- `GEMINI_API_KEY` - Google Gemini API key (required)
- `MINIO_ENDPOINT` - MinIO endpoint (`localhost:9000` for local dev, `minio:9000` for Docker)
- `MINIO_ACCESS_KEY` - MinIO service account key
@ -110,20 +140,28 @@ Required environment variables:
- `MINIO_BUCKET_NAME` - Storage bucket name (default: `banatie`)
- `PORT` - Server port (default: 3000)
- `NODE_ENV` - Environment mode
- `CORS_ORIGIN` - CORS origin setting (default: \*)
- `CORS_ORIGIN` - CORS origin setting (default: multiple localhost URLs for frontend apps)
## 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
- **express-rate-limit** - Rate limiting
### 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)
@ -147,9 +185,59 @@ Required environment variables:
## 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/generate` - Main image generation endpoint (multipart/form-data)
- `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/generate` - Generate images from text + optional reference images
- `POST /api/text-to-image` - Generate images from text only (JSON)
- `POST /api/enhance` - Enhance and optimize text prompts
- `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/generate \
-H "X-API-Key: YOUR_PROJECT_KEY" \
-F "prompt=a sunset" \
-F "filename=test_image"
```
### 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
@ -159,3 +247,4 @@ Required environment variables:
- 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

View File

@ -10,7 +10,40 @@ http://localhost:3000
## Authentication
API key required via `GEMINI_API_KEY` environment variable (server-side configuration).
All API endpoints (except `/health`, `/api/info`, and `/api/bootstrap/*`) require authentication via API key.
### API Key Types
1. **Master Keys** - Full admin access, never expire, can create/revoke other keys
2. **Project Keys** - Standard access for image generation, expire in 90 days
### Using API Keys
Include your API key in the `X-API-Key` header:
```bash
curl -X POST http://localhost:3000/api/generate \
-H "X-API-Key: bnt_your_key_here" \
-F "prompt=..." \
-F "filename=..."
```
### Getting Your First API Key
1. **Bootstrap** - Create initial master key (one-time only):
```bash
curl -X POST http://localhost:3000/api/bootstrap/initial-key
```
2. **Create Project Key** - Use master key to create project keys:
```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": "my-project", "name": "My Project Key"}'
```
**Important:** Save keys securely when created - they cannot be retrieved later!
## Content Types
@ -19,12 +52,126 @@ API key required via `GEMINI_API_KEY` environment variable (server-side configur
## Rate Limits
Standard Express rate limiting applies. Configure via environment variables.
- **Per API Key:** 100 requests per hour
- Rate limit information included in response headers:
- `X-RateLimit-Limit`: Maximum requests per window
- `X-RateLimit-Remaining`: Requests remaining
- `X-RateLimit-Reset`: When the limit resets (ISO 8601)
- **429 Too Many Requests:** Returned when limit exceeded
---
## Endpoints
### Authentication & Admin
#### `POST /api/bootstrap/initial-key`
Create the first master API key. This endpoint works only once when no keys exist.
**Authentication:** None required (public endpoint, one-time use)
**Response (201):**
```json
{
"apiKey": "bnt_...",
"type": "master",
"name": "Initial Master Key",
"expiresAt": null,
"message": "IMPORTANT: Save this key securely. You will not see it again!"
}
```
**Error (403):**
```json
{
"error": "Bootstrap not allowed",
"message": "API keys already exist. Use /api/admin/keys to create new keys."
}
```
---
#### `POST /api/admin/keys`
Create a new API key (master or project).
**Authentication:** Master key required via `X-API-Key` header
**Request Body:**
```json
{
"type": "master | project",
"projectId": "required-for-project-keys",
"name": "optional-friendly-name",
"expiresInDays": 90
}
```
**Response (201):**
```json
{
"apiKey": "bnt_...",
"metadata": {
"id": "uuid",
"type": "project",
"projectId": "my-project",
"name": "My Project Key",
"expiresAt": "2025-12-29T17:08:02.536Z",
"scopes": ["generate", "read"],
"createdAt": "2025-09-30T17:08:02.553Z"
},
"message": "IMPORTANT: Save this key securely. You will not see it again!"
}
```
---
#### `GET /api/admin/keys`
List all API keys.
**Authentication:** Master key required
**Response (200):**
```json
{
"keys": [
{
"id": "uuid",
"type": "master",
"projectId": null,
"name": "Initial Master Key",
"scopes": ["*"],
"isActive": true,
"createdAt": "2025-09-30T17:01:23.456Z",
"expiresAt": null,
"lastUsedAt": "2025-09-30T17:08:45.123Z",
"createdBy": null
}
],
"total": 1
}
```
---
#### `DELETE /api/admin/keys/:keyId`
Revoke an API key (soft delete).
**Authentication:** Master key required
**Response (200):**
```json
{
"message": "API key revoked successfully",
"keyId": "uuid"
}
```
---
### Health Check
#### `GET /health`
@ -79,6 +226,8 @@ Returns API metadata and configuration limits.
Generate images from text prompts with optional reference images.
**Authentication:** API key required (master or project)
**Content-Type:** `multipart/form-data`
**Parameters:**
@ -105,6 +254,7 @@ Generate images from text prompts with optional reference images.
**Example Request:**
```bash
curl -X POST http://localhost:3000/api/generate \
-H "X-API-Key: bnt_your_api_key_here" \
-F "prompt=A majestic mountain landscape at sunset" \
-F "filename=mountain-sunset" \
-F "autoEnhance=true" \
@ -151,6 +301,8 @@ curl -X POST http://localhost:3000/api/generate \
Generate images from text prompts only using JSON payload. Simplified endpoint for text-only requests without file uploads.
**Authentication:** API key required (master or project)
**Content-Type:** `application/json`
**Request Body:**
@ -180,6 +332,7 @@ Generate images from text prompts only using JSON payload. Simplified endpoint f
**Example Request:**
```bash
curl -X POST http://localhost:3000/api/text-to-image \
-H "X-API-Key: bnt_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A beautiful sunset over mountains with golden clouds",
@ -237,6 +390,8 @@ curl -X POST http://localhost:3000/api/text-to-image \
Enhance and optimize text prompts for better image generation results.
**Authentication:** API key required (master or project)
**Content-Type:** `application/json`
**Request Body:**
@ -299,17 +454,33 @@ Enhance and optimize text prompts for better image generation results.
| Code | Description |
|------|-------------|
| 400 | Bad Request - Invalid parameters or validation failure |
| 404 | Not Found - Endpoint does not exist |
| 401 | Unauthorized - Missing, invalid, expired, or revoked API key |
| 403 | Forbidden - Insufficient permissions (e.g., master key required) |
| 404 | Not Found - Endpoint or resource does not exist |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error - Server configuration or processing error |
## Common Error Messages
### Authentication Errors
- `"Missing API key"` - No X-API-Key header provided
- `"Invalid API key"` - The provided API key is invalid, expired, or revoked
- `"Master key required"` - This endpoint requires a master API key
- `"Bootstrap not allowed"` - API keys already exist, cannot bootstrap again
### Validation Errors
- `"Prompt is required"` - Missing or empty prompt parameter
- `"Reference image validation failed"` - Invalid file format or size
- `"Server configuration error"` - Missing GEMINI_API_KEY
- `"Image generation failed"` - AI service error
- `"Validation failed"` - Parameter validation error
### Rate Limiting
- `"Rate limit exceeded"` - Too many requests, retry after specified time
### Server Errors
- `"Server configuration error"` - Missing GEMINI_API_KEY or database connection
- `"Image generation failed"` - AI service error
- `"Authentication failed"` - Error during authentication process
---
## File Upload Specifications
@ -323,8 +494,23 @@ Enhance and optimize text prompts for better image generation results.
| Header | Value | Description |
|--------|-------|-------------|
| `X-Request-ID` | string | Unique request identifier (auto-generated) |
| `X-API-Key` | string | API key for authentication (required for most endpoints) |
| `X-Request-ID` | string | Unique request identifier (auto-generated by server) |
## Response Headers
| Header | Description |
|--------|-------------|
| `X-Request-ID` | Request identifier for tracking |
| `X-RateLimit-Limit` | Maximum requests allowed per window |
| `X-RateLimit-Remaining` | Requests remaining in current window |
| `X-RateLimit-Reset` | When the rate limit resets (ISO 8601) |
## CORS
Cross-origin requests supported. Configure via `CORS_ORIGIN` environment variable.
Cross-origin requests supported from:
- `http://localhost:3001` (Landing Page)
- `http://localhost:3002` (Studio Platform)
- `http://localhost:3003` (Admin Dashboard)
Configure additional origins via `CORS_ORIGIN` environment variable.