mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:01:09 +02:00
- Add Swagger/OpenAPI documentation at /docs endpoint - Add admin module for system-wide API key management - Add scheduler for monthly credit reset and usage cleanup - Add Docker Compose entry for Mac Mini deployment - Document all endpoints with descriptions and examples
9.1 KiB
9.1 KiB
Mana API Gateway
Custom NestJS API Gateway for monetizing ManaCore services (mana-search, mana-stt, mana-tts).
Overview
- Port: 3030
- Technology: NestJS 10 + Drizzle ORM + Redis
- Purpose: API Key Management, Usage Tracking, Rate Limiting, Credit-based Billing
Architecture
┌─────────────────────────┐
│ API Gateway │
│ (Port 3030) │
│ │
Clients ───────────>│ • API Key Validation │
(X-API-Key Header) │ • Rate Limiting │
│ • Usage Tracking │
│ • Credit Deduction │
└───────────┬─────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ mana-search │ │ mana-stt │ │ mana-tts │
│ (Port 3021) │ │ (Port 3020) │ │ (Port 3022) │
└───────────────┘ └───────────────┘ └───────────────┘
Quick Start
Development
# Install dependencies
pnpm install
# Push database schema
pnpm db:push
# Start in development mode
pnpm dev
Production
# Build
pnpm build
# Start
pnpm start
API Endpoints
Public API (with API Key)
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| POST | /v1/search |
Web search | 1 |
| POST | /v1/extract |
Content extraction | 1 |
| POST | /v1/extract/bulk |
Bulk extraction | 1 per URL |
| GET | /v1/search/engines |
Available search engines | 0 |
| POST | /v1/stt/transcribe |
Audio → Text | 10/min |
| GET | /v1/stt/models |
Available STT models | 0 |
| GET | /v1/stt/languages |
Supported languages | 0 |
| POST | /v1/tts/synthesize |
Text → Audio | 1/1000 chars |
| GET | /v1/tts/voices |
Available voices | 0 |
| GET | /v1/tts/languages |
Supported languages | 0 |
Management API (with JWT)
| Method | Endpoint | Description |
|---|---|---|
| POST | /api-keys |
Create new API key |
| GET | /api-keys |
List all API keys |
| GET | /api-keys/:id |
Get API key details |
| PATCH | /api-keys/:id |
Update API key |
| DELETE | /api-keys/:id |
Delete API key |
| POST | /api-keys/:id/regenerate |
Regenerate API key |
| GET | /api-keys/:id/usage |
Get usage statistics |
| GET | /api-keys/:id/usage/summary |
Get usage summary |
Admin API (with JWT + Admin Role)
| Method | Endpoint | Description |
|---|---|---|
| GET | /admin/api-keys |
List all API keys (paginated) |
| GET | /admin/api-keys/:id |
Get any API key details |
| PATCH | /admin/api-keys/:id |
Update any key (tier, credits, limits) |
| DELETE | /admin/api-keys/:id |
Delete any API key |
| GET | /admin/usage/summary |
System-wide usage stats |
| GET | /admin/usage/top-users |
Top users by usage |
System
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /metrics |
Prometheus metrics |
| GET | /docs |
Swagger/OpenAPI documentation |
Pricing Tiers
| Tier | Rate Limit | Monthly Credits | Endpoints | Price |
|---|---|---|---|---|
| Free | 10 req/min | 100 | Search only | Free |
| Pro | 100 req/min | 5,000 | All | €19/month |
| Enterprise | 1,000 req/min | 50,000 | All | €99/month |
Credit Costs
| Operation | Cost |
|---|---|
| Search | 1 credit |
| Extract | 1 credit |
| STT | 10 credits/minute |
| TTS | 1 credit/1000 chars |
Usage Examples
Create an API Key
# First, get a JWT token from mana-core-auth
TOKEN=$(curl -s -X POST http://localhost:3001/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "password"}' | jq -r '.accessToken')
# Create an API key
curl -X POST http://localhost:3030/api-keys \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "My API Key", "tier": "free"}'
Use the API
# Search
curl -X POST http://localhost:3030/v1/search \
-H "X-API-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"query": "quantum computing"}'
# Extract content
curl -X POST http://localhost:3030/v1/extract \
-H "X-API-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/article"}'
# Text-to-Speech
curl -X POST http://localhost:3030/v1/tts/synthesize \
-H "X-API-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"text": "Hello, world!", "voice": "en-US-1"}' \
--output audio.mp3
# Speech-to-Text
curl -X POST http://localhost:3030/v1/stt/transcribe \
-H "X-API-Key: sk_live_xxx" \
-F "file=@audio.wav"
Check Usage
curl http://localhost:3030/api-keys/{id}/usage \
-H "Authorization: Bearer $TOKEN"
Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT |
3030 | API port |
DATABASE_URL |
- | PostgreSQL connection URL |
REDIS_HOST |
localhost | Redis host |
REDIS_PORT |
6379 | Redis port |
SEARCH_SERVICE_URL |
http://localhost:3021 | mana-search URL |
STT_SERVICE_URL |
http://localhost:3020 | mana-stt URL |
TTS_SERVICE_URL |
http://localhost:3022 | mana-tts URL |
MANA_CORE_AUTH_URL |
http://localhost:3001 | Auth service URL |
ADMIN_USER_IDS |
- | Comma-separated admin user IDs |
Development Commands
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Build for production
pnpm build
# Start production server
pnpm start
# Type checking
pnpm type-check
# Linting
pnpm lint
# Database commands
pnpm db:push # Push schema to database
pnpm db:generate # Generate migrations
pnpm db:migrate # Run migrations
pnpm db:studio # Open Drizzle Studio
Database Schema
The gateway uses its own schema (api_gateway) in the shared ManaCore database:
api_gateway.api_keys- API key storage and configurationapi_gateway.api_usage- Detailed usage logsapi_gateway.api_usage_daily- Aggregated daily usage for billing
Rate Limiting
Rate limiting uses Redis with a sliding window algorithm:
- Each API key has a configurable rate limit (requests per minute)
- Rate limit headers are included in responses:
X-RateLimit-Limit- Maximum requests per minuteX-RateLimit-Remaining- Remaining requestsX-RateLimit-Reset- Unix timestamp when limit resets
Authentication
Two types of authentication:
- X-API-Key header - For public API endpoints (
/v1/*) - Bearer JWT token - For management endpoints (
/api-keys/*)
The JWT token is validated against mana-core-auth service.
Project Structure
services/mana-api-gateway/
├── src/
│ ├── main.ts # Application entry point
│ ├── app.module.ts # Root module
│ ├── config/
│ │ ├── configuration.ts # App configuration
│ │ └── pricing.ts # Pricing tiers and credit costs
│ ├── db/
│ │ ├── schema/ # Drizzle schemas
│ │ ├── database.module.ts # Database provider
│ │ ├── connection.ts # DB connection
│ │ └── migrate.ts # Migration script
│ ├── api-keys/ # API key management
│ ├── usage/ # Usage tracking
│ ├── proxy/ # Proxy services to backends
│ ├── guards/ # Auth, rate limit, credits guards
│ ├── common/ # Decorators, filters, interceptors
│ ├── credits/ # Credits service (mana-core-auth client)
│ ├── metrics/ # Prometheus metrics
│ └── health/ # Health check endpoint
├── drizzle.config.ts # Drizzle Kit configuration
├── package.json
├── tsconfig.json
└── Dockerfile
Troubleshooting
API Key not working
- Check the key is valid:
curl -H "X-API-Key: $KEY" http://localhost:3030/health - Check the key is active in the database
- Check the key hasn't expired
- Check the endpoint is allowed for the key's tier
Rate limit exceeded
Wait for the X-RateLimit-Reset timestamp, or upgrade to a higher tier.
Credits exhausted
Check usage with the management API, or wait for monthly reset.