chore: update documentation
This commit is contained in:
parent
1236dd78e2
commit
df84e400f5
|
|
@ -0,0 +1,840 @@
|
|||
# Banatie REST API Implementation Plan
|
||||
|
||||
**Version:** 2.0
|
||||
**Status:** Ready for Implementation
|
||||
**Executor:** Claude Code
|
||||
**Database Schema:** v2.0 (banatie-database-design.md)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
REST API for Banatie image generation service. All endpoints use `/api/v1/` prefix for versioning.
|
||||
|
||||
**Core Features:**
|
||||
- AI image generation with Google Gemini Flash
|
||||
- Dual alias system (project-scoped + flow-scoped)
|
||||
- Technical aliases (@last, @first, @upload)
|
||||
- Flow-based generation chains
|
||||
- Live generation endpoint with caching
|
||||
- Upload and reference images
|
||||
|
||||
**Authentication:** API keys only (`bnt_` prefix)
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
All endpoints require API key in header:
|
||||
|
||||
```
|
||||
X-API-Key: bnt_xxx...
|
||||
```
|
||||
|
||||
**API Key Types:**
|
||||
- `master`: Full access to all projects in organization
|
||||
- `project`: Access to specific project only
|
||||
|
||||
**Unauthorized Response (401):**
|
||||
```json
|
||||
{
|
||||
"error": "Unauthorized",
|
||||
"message": "Invalid or missing API key"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase 1: Foundation
|
||||
**Goal:** Core utilities and services
|
||||
|
||||
**Tasks:**
|
||||
- Create TypeScript type definitions for all models
|
||||
- Build validation utilities (alias format, pagination, query params)
|
||||
- Build helper utilities (pagination, hash, query helpers)
|
||||
- Create `AliasService` with 3-tier resolution (technical → flow → project)
|
||||
|
||||
**Git Commit:**
|
||||
```
|
||||
feat: add foundation utilities and alias service
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Core Generation Flow
|
||||
**Goal:** Main generation endpoints
|
||||
|
||||
**Services:**
|
||||
- `ImageService` - CRUD operations with soft delete
|
||||
- `GenerationService` - Full lifecycle management
|
||||
|
||||
**Endpoints:**
|
||||
- `POST /api/v1/generations` - Create with reference images & dual aliases
|
||||
- `GET /api/v1/generations` - List with filters
|
||||
- `GET /api/v1/generations/:id` - Get details with related data
|
||||
|
||||
**Git Commit:**
|
||||
```
|
||||
feat: implement core generation endpoints
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: Flow Management
|
||||
**Goal:** Flow operations
|
||||
|
||||
**Services:**
|
||||
- `FlowService` - CRUD with computed counts & alias management
|
||||
|
||||
**Endpoints:**
|
||||
- `POST /api/v1/flows` - Create flow
|
||||
- `GET /api/v1/flows` - List flows with computed counts
|
||||
- `GET /api/v1/flows/:id` - Get details with generations and images
|
||||
- `PUT /api/v1/flows/:id/aliases` - Update flow aliases
|
||||
- `DELETE /api/v1/flows/:id/aliases/:alias` - Remove specific alias
|
||||
- `DELETE /api/v1/flows/:id` - Delete flow
|
||||
|
||||
**Git Commit:**
|
||||
```
|
||||
feat: implement flow management endpoints
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: Enhanced Image Management
|
||||
**Goal:** Complete image operations
|
||||
|
||||
**Endpoints:**
|
||||
- `POST /api/v1/images/upload` - Upload with alias, flow, metadata
|
||||
- `GET /api/v1/images` - List with filters
|
||||
- `GET /api/v1/images/:id` - Get details with usage info
|
||||
- `GET /api/v1/images/resolve/:alias` - Resolve alias with precedence
|
||||
- `PUT /api/v1/images/:id` - Update metadata
|
||||
- `DELETE /api/v1/images/:id` - Soft/hard delete
|
||||
|
||||
**Git Commit:**
|
||||
```
|
||||
feat: implement image management endpoints
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: Generation Refinements
|
||||
**Goal:** Additional generation operations
|
||||
|
||||
**Endpoints:**
|
||||
- `POST /api/v1/generations/:id/retry` - Retry failed generation
|
||||
- `DELETE /api/v1/generations/:id` - Delete generation
|
||||
|
||||
**Git Commit:**
|
||||
```
|
||||
feat: add generation retry and delete endpoints
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 6: Live Generation
|
||||
**Goal:** URL-based generation with caching
|
||||
|
||||
**Services:**
|
||||
- `PromptCacheService` - SHA-256 caching with hit tracking
|
||||
|
||||
**Endpoints:**
|
||||
- `GET /api/v1/live` - Generate image via URL with streaming proxy
|
||||
|
||||
**Important:** Stream image directly from MinIO (no 302 redirect) for better performance.
|
||||
|
||||
**Git Commit:**
|
||||
```
|
||||
feat: implement live generation endpoint with caching
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 7: Analytics
|
||||
**Goal:** Project statistics and metrics
|
||||
|
||||
**Services:**
|
||||
- `AnalyticsService` - Aggregation queries
|
||||
|
||||
**Endpoints:**
|
||||
- `GET /api/v1/analytics/summary` - Project statistics
|
||||
- `GET /api/v1/analytics/generations/timeline` - Time-series data
|
||||
|
||||
**Git Commit:**
|
||||
```
|
||||
feat: add analytics endpoints
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 8: Testing & Documentation
|
||||
**Goal:** Quality assurance
|
||||
|
||||
**Tasks:**
|
||||
- Unit tests for all services (target >80% coverage)
|
||||
- Integration tests for critical flows
|
||||
- Error handling consistency review
|
||||
- Update API documentation
|
||||
|
||||
**Git Commit:**
|
||||
```
|
||||
test: add comprehensive test coverage and documentation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints Specification
|
||||
|
||||
### GENERATIONS
|
||||
|
||||
#### POST /api/v1/generations
|
||||
|
||||
Create new image generation.
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
{
|
||||
prompt: string; // Required: 1-2000 chars
|
||||
aspectRatio?: string; // Optional: '16:9', '1:1', '4:3', '9:16'
|
||||
width?: number; // Optional: 1-8192
|
||||
height?: number; // Optional: 1-8192
|
||||
referenceImages?: string[]; // Optional: ['@logo', '@product', '@last']
|
||||
flowId?: string; // Optional: Add to existing flow
|
||||
assignAlias?: string; // Optional: Project-scoped alias '@brand'
|
||||
assignFlowAlias?: string; // Optional: Flow-scoped alias '@hero' (requires flowId)
|
||||
meta?: Record<string, unknown>;
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
generation: Generation;
|
||||
image?: Image; // If generation completed
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:** 400, 401, 404, 422, 429, 500
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/generations
|
||||
|
||||
List generations with filtering.
|
||||
|
||||
**Query Params:**
|
||||
```typescript
|
||||
{
|
||||
flowId?: string;
|
||||
status?: 'pending' | 'processing' | 'success' | 'failed';
|
||||
limit?: number; // Default: 20, max: 100
|
||||
offset?: number; // Default: 0
|
||||
sortBy?: 'createdAt' | 'updatedAt';
|
||||
order?: 'asc' | 'desc'; // Default: desc
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
generations: Generation[];
|
||||
pagination: PaginationInfo;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/generations/:id
|
||||
|
||||
Get generation details.
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
generation: Generation;
|
||||
image?: Image;
|
||||
referencedImages: Image[];
|
||||
flow?: FlowSummary;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### POST /api/v1/generations/:id/retry
|
||||
|
||||
Retry failed generation.
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
generation: Generation; // New generation with incremented retry_count
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:** 404, 422
|
||||
|
||||
---
|
||||
|
||||
#### DELETE /api/v1/generations/:id
|
||||
|
||||
Delete generation.
|
||||
|
||||
**Query Params:**
|
||||
```typescript
|
||||
{
|
||||
hard?: boolean; // Default: false
|
||||
}
|
||||
```
|
||||
|
||||
**Response (204):** No content
|
||||
|
||||
---
|
||||
|
||||
### IMAGES
|
||||
|
||||
#### POST /api/v1/images/upload
|
||||
|
||||
Upload image file.
|
||||
|
||||
**Request:** multipart/form-data
|
||||
|
||||
**Fields:**
|
||||
```typescript
|
||||
{
|
||||
file: File; // Required, max 5MB
|
||||
alias?: string; // Project-scoped: '@logo'
|
||||
flowAlias?: string; // Flow-scoped: '@hero' (requires flowId)
|
||||
flowId?: string;
|
||||
description?: string;
|
||||
tags?: string[]; // JSON array as string
|
||||
focalPoint?: string; // JSON: '{"x":0.5,"y":0.5}'
|
||||
meta?: string; // JSON object as string
|
||||
}
|
||||
```
|
||||
|
||||
**Response (201):**
|
||||
```typescript
|
||||
{
|
||||
image: Image;
|
||||
flow?: FlowSummary; // If flowAlias assigned
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:** 400, 409, 422
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/images
|
||||
|
||||
List images.
|
||||
|
||||
**Query Params:**
|
||||
```typescript
|
||||
{
|
||||
flowId?: string;
|
||||
source?: 'generated' | 'uploaded';
|
||||
alias?: string;
|
||||
limit?: number; // Default: 20, max: 100
|
||||
offset?: number;
|
||||
sortBy?: 'createdAt' | 'fileSize';
|
||||
order?: 'asc' | 'desc';
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
images: Image[];
|
||||
pagination: PaginationInfo;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/images/:id
|
||||
|
||||
Get image details.
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
image: Image;
|
||||
generation?: Generation;
|
||||
usedInGenerations: GenerationSummary[];
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/images/resolve/:alias
|
||||
|
||||
Resolve alias to image.
|
||||
|
||||
**Query Params:**
|
||||
```typescript
|
||||
{
|
||||
flowId?: string; // Provide flow context
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
image: Image;
|
||||
scope: 'flow' | 'project' | 'technical';
|
||||
flow?: FlowSummary;
|
||||
}
|
||||
```
|
||||
|
||||
**Resolution Order:**
|
||||
1. Technical aliases (@last, @first, @upload) if flowId provided
|
||||
2. Flow aliases from flows.aliases if flowId provided
|
||||
3. Project aliases from images.alias
|
||||
|
||||
**Errors:** 404
|
||||
|
||||
---
|
||||
|
||||
#### PUT /api/v1/images/:id
|
||||
|
||||
Update image metadata.
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
{
|
||||
alias?: string;
|
||||
description?: string;
|
||||
tags?: string[];
|
||||
focalPoint?: { x: number; y: number };
|
||||
meta?: Record<string, unknown>;
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
image: Image;
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:** 404, 409, 422
|
||||
|
||||
---
|
||||
|
||||
#### DELETE /api/v1/images/:id
|
||||
|
||||
Delete image.
|
||||
|
||||
**Query Params:**
|
||||
```typescript
|
||||
{
|
||||
hard?: boolean; // Default: false
|
||||
}
|
||||
```
|
||||
|
||||
**Response (204):** No content
|
||||
|
||||
---
|
||||
|
||||
### FLOWS
|
||||
|
||||
#### POST /api/v1/flows
|
||||
|
||||
Create new flow.
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
{
|
||||
meta?: Record<string, unknown>;
|
||||
}
|
||||
```
|
||||
|
||||
**Response (201):**
|
||||
```typescript
|
||||
{
|
||||
flow: Flow;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/flows
|
||||
|
||||
List flows.
|
||||
|
||||
**Query Params:**
|
||||
```typescript
|
||||
{
|
||||
limit?: number; // Default: 20, max: 100
|
||||
offset?: number;
|
||||
sortBy?: 'createdAt' | 'updatedAt';
|
||||
order?: 'asc' | 'desc';
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
flows: Array<Flow & {
|
||||
generationCount: number; // Computed
|
||||
imageCount: number; // Computed
|
||||
}>;
|
||||
pagination: PaginationInfo;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/flows/:id
|
||||
|
||||
Get flow details.
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
flow: Flow;
|
||||
generations: Generation[]; // Ordered by created_at ASC
|
||||
images: Image[];
|
||||
resolvedAliases: Record<string, Image>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### PUT /api/v1/flows/:id/aliases
|
||||
|
||||
Update flow aliases.
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
{
|
||||
aliases: Record<string, string>; // { "@hero": "image-uuid" }
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
flow: Flow;
|
||||
}
|
||||
```
|
||||
|
||||
**Validation:**
|
||||
- Keys must match `^@[a-zA-Z0-9_-]+$`
|
||||
- Values must be valid image UUIDs
|
||||
- Cannot use reserved: @last, @first, @upload
|
||||
|
||||
**Errors:** 404, 422
|
||||
|
||||
---
|
||||
|
||||
#### DELETE /api/v1/flows/:id/aliases/:alias
|
||||
|
||||
Remove specific alias from flow.
|
||||
|
||||
**Response (204):** No content
|
||||
|
||||
**Errors:** 404
|
||||
|
||||
---
|
||||
|
||||
#### DELETE /api/v1/flows/:id
|
||||
|
||||
Delete flow.
|
||||
|
||||
**Response (204):** No content
|
||||
|
||||
**Note:** Cascades to images, sets NULL on generations.flow_id
|
||||
|
||||
---
|
||||
|
||||
### LIVE GENERATION
|
||||
|
||||
#### GET /api/v1/live
|
||||
|
||||
Generate image via URL with caching and streaming.
|
||||
|
||||
**Query Params:**
|
||||
```typescript
|
||||
{
|
||||
prompt: string; // Required
|
||||
aspectRatio?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
reference?: string | string[]; // '@logo' or ['@logo','@style']
|
||||
}
|
||||
```
|
||||
|
||||
**Response:** Image stream with headers
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
Content-Type: image/jpeg
|
||||
Cache-Control: public, max-age=31536000
|
||||
X-Cache-Status: HIT | MISS
|
||||
```
|
||||
|
||||
**Implementation:**
|
||||
1. Compute cache key: SHA256(prompt + sorted params)
|
||||
2. Check prompt_url_cache table
|
||||
3. If HIT: increment hit_count, stream from MinIO
|
||||
4. If MISS: generate, cache, stream from MinIO
|
||||
5. Stream image bytes directly (no 302 redirect)
|
||||
|
||||
**Errors:** 400, 404, 500
|
||||
|
||||
---
|
||||
|
||||
### ANALYTICS
|
||||
|
||||
#### GET /api/v1/analytics/summary
|
||||
|
||||
Get project statistics.
|
||||
|
||||
**Query Params:**
|
||||
```typescript
|
||||
{
|
||||
startDate?: string; // ISO 8601
|
||||
endDate?: string;
|
||||
flowId?: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
period: { startDate: string; endDate: string };
|
||||
metrics: {
|
||||
totalGenerations: number;
|
||||
successfulGenerations: number;
|
||||
failedGenerations: number;
|
||||
successRate: number;
|
||||
totalImages: number;
|
||||
uploadedImages: number;
|
||||
generatedImages: number;
|
||||
avgProcessingTimeMs: number;
|
||||
totalCacheHits: number;
|
||||
cacheHitRate: number;
|
||||
totalCost: number;
|
||||
};
|
||||
flows: FlowSummary[];
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/analytics/generations/timeline
|
||||
|
||||
Get generation statistics over time.
|
||||
|
||||
**Query Params:**
|
||||
```typescript
|
||||
{
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
flowId?: string;
|
||||
groupBy?: 'hour' | 'day' | 'week'; // Default: day
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```typescript
|
||||
{
|
||||
data: Array<{
|
||||
timestamp: string;
|
||||
total: number;
|
||||
successful: number;
|
||||
failed: number;
|
||||
avgProcessingTimeMs: number;
|
||||
}>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Guidelines
|
||||
|
||||
### Alias Resolution Algorithm
|
||||
|
||||
**Priority Order:**
|
||||
1. Technical aliases (@last, @first, @upload) - compute from flow data
|
||||
2. Flow-scoped aliases - from flows.aliases JSONB
|
||||
3. Project-scoped aliases - from images.alias column
|
||||
|
||||
**Technical Aliases:**
|
||||
- `@last`: Latest generation output in flow (any status)
|
||||
- `@first`: First generation output in flow
|
||||
- `@upload`: Latest uploaded image in flow
|
||||
|
||||
### Dual Alias Assignment
|
||||
|
||||
When creating generation or uploading image:
|
||||
- `assignAlias` → set images.alias (project scope)
|
||||
- `assignFlowAlias` → add to flows.aliases (flow scope)
|
||||
- Both can be assigned simultaneously
|
||||
|
||||
### Flow Updates
|
||||
|
||||
Update `flows.updated_at` on:
|
||||
- New generation created with flowId
|
||||
- New image uploaded with flowId
|
||||
- Flow aliases modified
|
||||
|
||||
### Audit Trail
|
||||
|
||||
Track `api_key_id` in:
|
||||
- `images.api_key_id` - who uploaded/generated
|
||||
- `generations.api_key_id` - who requested
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
In-memory rate limiting (defer Redis for MVP):
|
||||
- Master key: 1000 req/hour, 100 generations/hour
|
||||
- Project key: 500 req/hour, 50 generations/hour
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
X-RateLimit-Limit: 500
|
||||
X-RateLimit-Remaining: 487
|
||||
X-RateLimit-Reset: 1698765432
|
||||
```
|
||||
|
||||
### Error Response Format
|
||||
|
||||
```typescript
|
||||
{
|
||||
error: string;
|
||||
message: string;
|
||||
details?: unknown;
|
||||
requestId?: string;
|
||||
}
|
||||
```
|
||||
|
||||
### MinIO Integration
|
||||
|
||||
Use streaming for `/api/v1/live`:
|
||||
```typescript
|
||||
const stream = await minioClient.getObject(bucket, storageKey);
|
||||
res.set('Content-Type', mimeType);
|
||||
stream.pipe(res);
|
||||
```
|
||||
|
||||
Generate presigned URLs for other endpoints:
|
||||
```typescript
|
||||
const url = await minioClient.presignedGetObject(bucket, storageKey, 24 * 60 * 60);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation Rules
|
||||
|
||||
**Alias Format:**
|
||||
- Pattern: `^@[a-zA-Z0-9_-]+$`
|
||||
- Reserved: @last, @first, @upload
|
||||
- Length: 3-100 chars
|
||||
|
||||
**File Upload:**
|
||||
- Max size: 5MB
|
||||
- MIME types: image/jpeg, image/png, image/webp
|
||||
- Max dimensions: 8192x8192
|
||||
|
||||
**Prompt:**
|
||||
- Min: 1 char
|
||||
- Max: 2000 chars
|
||||
|
||||
**Aspect Ratio:**
|
||||
- Pattern: `^\d+:\d+$`
|
||||
- Examples: 16:9, 1:1, 4:3, 9:16
|
||||
|
||||
---
|
||||
|
||||
## Service Architecture
|
||||
|
||||
### Core Services
|
||||
|
||||
**AliasService:**
|
||||
- Resolve aliases with 3-tier precedence
|
||||
- Compute technical aliases
|
||||
- Validate alias format
|
||||
|
||||
**ImageService:**
|
||||
- CRUD operations
|
||||
- Soft delete support
|
||||
- Usage tracking
|
||||
|
||||
**GenerationService:**
|
||||
- Generation lifecycle
|
||||
- Status transitions
|
||||
- Error handling
|
||||
- Retry logic
|
||||
|
||||
**FlowService:**
|
||||
- Flow CRUD
|
||||
- Alias management
|
||||
- Computed counts
|
||||
|
||||
**PromptCacheService:**
|
||||
- Cache key computation (SHA-256)
|
||||
- Hit tracking
|
||||
- Cache lookup
|
||||
|
||||
**AnalyticsService:**
|
||||
- Aggregation queries
|
||||
- Time-series grouping
|
||||
|
||||
### Reusable Utilities
|
||||
|
||||
**Validators:**
|
||||
- Alias format
|
||||
- Pagination params
|
||||
- Query filters
|
||||
|
||||
**Helpers:**
|
||||
- Pagination builder
|
||||
- SHA-256 hashing
|
||||
- Query helpers
|
||||
|
||||
---
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
**Unit Tests:**
|
||||
- All services must have unit tests
|
||||
- Target coverage: >80%
|
||||
- Mock database calls
|
||||
|
||||
**Integration Tests:**
|
||||
- Critical flows end-to-end
|
||||
- Real database transactions
|
||||
- API endpoint testing with supertest
|
||||
|
||||
**Test Scenarios:**
|
||||
- Alias resolution precedence
|
||||
- Flow-scoped vs project-scoped aliases
|
||||
- Technical alias computation
|
||||
- Dual alias assignment
|
||||
- Cache hit/miss behavior
|
||||
- Error handling
|
||||
- Rate limiting
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
✅ All endpoints functional per specification
|
||||
✅ >80% test coverage on services
|
||||
✅ Consistent error handling across all endpoints
|
||||
✅ All validation rules implemented
|
||||
✅ Rate limiting working
|
||||
✅ Documentation updated
|
||||
✅ Git commits after each phase
|
||||
|
||||
---
|
||||
|
||||
*Document Version: 2.0*
|
||||
*Created: 2025-11-09*
|
||||
*Target: Claude Code Implementation*
|
||||
*Database Schema: v2.0*
|
||||
Loading…
Reference in New Issue