diff --git a/api-refactoring-final.md b/api-refactoring-final.md new file mode 100644 index 0000000..8826467 --- /dev/null +++ b/api-refactoring-final.md @@ -0,0 +1,817 @@ +# Banatie API v1 - Technical Changes and Refactoring + +## Context + +Project is in active development with no existing clients. All changes can be made without backward compatibility concerns. **Priority: high-quality and correct API implementation.** + +--- + +## 1. Parameter Naming Cleanup ✅ + +### 1.1 POST /api/v1/generations + +**Current parameters:** +- `assignAlias` → rename to `alias` +- `assignFlowAlias` → rename to `flowAlias` + +**Rationale:** Shorter, clearer, no need for "assign" prefix when assignment is obvious from endpoint context. + +**Affected areas:** +- Request type definitions +- Route handlers +- Service methods +- API documentation + +--- + +## 2. Enhanced Prompt Support - Logic Redesign + +### 2.1 Database Schema Changes + +**Required schema modifications:** + +1. **Rename field:** `enhancedPrompt` → `originalPrompt` +2. **Change field semantics:** + - `prompt` - ALWAYS contains the prompt that was used for generation (enhanced or original) + - `originalPrompt` - contains user's original input ONLY if autoEnhance was used (nullable) + +**Field population logic:** + +``` +Case 1: autoEnhance = false + prompt = user input + originalPrompt = NULL + +Case 2: autoEnhance = true + prompt = enhanced prompt (used for generation) + originalPrompt = user input (preserved) +``` + +### 2.2 API Response Format + +**Response structure:** +```json +{ + "prompt": "detailed enhanced prompt...", // Always the prompt used for generation + "originalPrompt": "sunset" // Only present if enhancement was used +} +``` + +**Affected endpoints:** +- `POST /api/v1/generations` response +- `GET /api/v1/generations/:id` response +- `GET /api/v1/generations` list response + +--- + +## 3. Regeneration Endpoint Refactoring ✅ + +### 3.1 Endpoint Rename + +**Change:** +- ❌ OLD: `POST /api/v1/generations/:id/retry` +- ✅ NEW: `POST /api/v1/generations/:id/regenerate` + +### 3.2 Remove Status Checks + +- Remove `if (original.status === 'success') throw error` check +- Remove `GENERATION_ALREADY_SUCCEEDED` error constant +- Allow regeneration for any status (pending, processing, success, failed) + +### 3.3 Remove Retry Logic + +- Remove `retryCount >= MAX_RETRY_COUNT` check +- Remove retryCount increment +- Remove `MAX_RETRY_COUNT` constant + +### 3.4 Remove Override Parameters + +- Remove `prompt` and `aspectRatio` parameters from request body +- Always regenerate with exact same parameters as original + +### 3.5 Image Update Behavior + +**Update existing image instead of creating new:** + +**Preserve:** +- `imageId` (UUID remains the same) +- `storageKey` (MinIO path) +- `storageUrl` +- `alias` (if assigned) +- `createdAt` (original creation timestamp) + +**Update:** +- Physical file in MinIO (overwrite) +- `fileSize` (if changed) +- `updatedAt` timestamp + +**Generation record:** +- Update `status` → processing → success/failed +- Update `processingTimeMs` +- Keep `outputImageId` (same value) +- Keep `flowId` (if present) + +### 3.6 Additional Endpoint + +**Add for Flow:** +- `POST /api/v1/flows/:id/regenerate` +- Regenerates the most recent generation in flow +- Returns `FLOW_HAS_NO_GENERATIONS` error if flow is empty +- Uses parameters from the last generation in flow + +--- + +## 4. Flow Auto-Creation (Lazy Flow Pattern) + +### 4.1 Lazy Flow Creation Strategy + +**Concept:** +1. **First request without flowId** → return generated `flowId` in response, but **DO NOT create in DB** +2. **Any request with valid flowId** → create flow in DB if doesn't exist, add this request to flow +3. **If flowAlias specified in request** → create flow immediately (eager creation) + +### 4.2 Implementation Details + +**Flow ID Generation:** +- When generation/upload has no flowId, generate UUID for potential flow +- Return this flowId in response +- Save `flowId` in generation/image record, but DO NOT create flow record + +**Flow Creation in DB:** + +**Trigger:** ANY request with valid flowId value + +**Logic:** +1. Check if flow record exists in DB +2. Check if there are existing generations/images with this flowId +3. If flow doesn't exist: + - Create flow record with provided flowId + - Include all existing records with this flowId + - Maintain chronological order based on createdAt timestamps +4. If flow exists: + - Add new record to existing flow + +**Eager creation:** +- If request includes `flowAlias` → create flow immediately +- Set alias in `flow.aliases` object + +**Database Schema:** +- `generations` table already has `flowId` field (foreign key to flows.id) +- `images` table already has `flowId` field (foreign key to flows.id) +- No schema changes needed + +**Orphan flowId handling:** +- If `flowId` exists in generation/image record but not in `flows` table - this is normal +- Such records are called "orphans" and simply not shown in `GET /api/v1/flows` list +- No cleanup job needed +- Do NOT delete such records automatically +- System works correctly with orphan flowIds until flow record is created + +### 4.3 Endpoint Changes + +**Remove:** +- ❌ `POST /api/v1/flows` endpoint (no longer needed) + +**Modify responses:** +- `POST /api/v1/generations` → always return `flowId` in response (see section 10.1) +- `POST /api/v1/images/upload` → always return `flowId` in response (see section 10.1) + +--- + +## 5. Upload Image Enhancements + +### 5.1 Add Parameters + +**POST /api/v1/images/upload:** + +**Parameters:** +- `alias` (optional, string) - project-scoped alias +- `flowAlias` (optional, string) - flow-scoped alias for uploaded image +- `flowId` (optional, string) - flow association + +**Behavior:** +- If `flowAlias` and `flowId` specified: + - Ensure flow exists (or create via lazy pattern) + - Add alias to `flow.aliases` object +- If `flowAlias` WITHOUT `flowId`: + - Apply lazy flow creation with eager pattern + - Create flow immediately, set flowAlias +- If only `alias` specified: + - Set project-scoped alias on image + +### 5.2 Alias Conflict Resolution + +**Validation rules:** + +1. **Technical aliases are forbidden:** + - Cannot use: `@last`, `@first`, `@upload` or any reserved technical alias + - Return validation error if attempted + +2. **Alias override behavior:** + - If alias already exists → new request has higher priority + - Alias points to new image + - Previous image loses its alias but is NOT deleted + - Same logic applies to both project aliases and flow aliases + +3. **Applies to both:** + - Image upload with alias + - Generation with alias/flowAlias + +**Example:** +``` +State: Image A has alias "@hero" +Request: Upload Image B with alias "@hero" +Result: + - Image B now has alias "@hero" + - Image A loses alias (alias = NULL) + - Image A is NOT deleted +``` + +--- + +## 6. Image Alias Management Refactoring + +### 6.1 Endpoint Consolidation + +**Remove alias handling from:** +- ❌ `PUT /api/v1/images/:id` (body: { alias, focalPoint, meta }) + - Remove `alias` parameter + - Keep only `focalPoint` and `meta` + +**Single method for project-scoped alias management:** +- ✅ `PUT /api/v1/images/:id/alias` (body: { alias }) + - Set new alias + - Change existing alias + - Remove alias (pass `alias: null`) + +**Rationale:** Explicit intent, dedicated endpoint for alias operations, simpler validation. + +### 6.2 Alias as Image Identifier + +**Support alias in path parameters:** + +**Syntax:** +- UUID: `GET /api/v1/images/550e8400-e29b-41d4-a716-446655440000` +- Alias: `GET /api/v1/images/@hero` +- `@` symbol distinguishes alias from UUID (UUIDs never contain `@`) + +**UUID validation:** UUIDs can NEVER contain `@` symbol - this guarantees no conflicts + +**Flow-scoped resolution:** +- `GET /api/v1/images/@hero?flowId=uuid-123` +- Searches for alias `@hero` in context of flow `uuid-123` +- Uses 3-tier precedence (technical → flow → project) + +**Endpoints with alias support:** +- `GET /api/v1/images/:id_or_alias` +- `PUT /api/v1/images/:id_or_alias` (for focalPoint, meta) +- `PUT /api/v1/images/:id_or_alias/alias` +- `DELETE /api/v1/images/:id_or_alias` + +**Implementation:** +- Check first character of path parameter +- If starts with `@` → resolve via AliasService +- If doesn't start with `@` → treat as UUID +- After resolution, work with imageId as usual + +### 6.3 CDN-style Image URLs with Alias Support + +**Current URL format must be changed.** + +**New standardized URL patterns:** + +**For all generated and uploaded images:** +``` +GET /cdn/:orgSlug/:projectSlug/img/:filenameOrAlias +``` + +**For live URLs:** +``` +GET /cdn/:orgSlug/:projectSlug/live/:scope?prompt=...&aspectRatio=... +``` + +**All image URLs returned by API must follow this pattern.** + +**Resolution Logic:** +1. Check if `:filenameOrAlias` starts with `@` +2. If yes → resolve alias via AliasService +3. If no → search by filename/storageKey +4. Return image bytes with proper content-type headers + +**Response Headers:** +- Content-Type: image/jpeg (or appropriate MIME type) +- Cache-Control: public, max-age=31536000 +- ETag: based on imageId or fileHash + +**URL Encoding for prompts:** +- Spaces can be replaced with underscores `_` for convenience +- Both `prompt=beautiful%20sunset` and `prompt=beautiful_sunset` are valid +- System should handle both formats + +**Examples:** +``` +GET /cdn/acme/website/img/@hero → resolve @hero alias +GET /cdn/acme/website/img/logo.png → find by filename +GET /cdn/acme/website/img/@product-1 → resolve @product-1 alias +``` + +**Error Handling:** +- Alias not found → 404 +- Filename not found → 404 +- Multiple matches → alias takes priority over filename + +--- + +## 7. Deletion Strategy Overhaul + +### 7.1 Image Deletion (Hard Delete) + +**DELETE /api/v1/images/:id** + +**Operations:** +1. Delete physical file from MinIO storage +2. Delete record from `images` table (hard delete) +3. Cascade: set `outputImageId = NULL` in related generations +4. Cascade: **completely remove alias entries** from all `flow.aliases` where imageId is referenced + - Remove entire key-value pairs, not just values +5. Cascade: remove imageId from `generation.referencedImages` JSON arrays + +**Example cascade for flow.aliases:** +``` +Before: flow.aliases = { "@hero": "img-123", "@product": "img-456" } +Delete img-123 +After: flow.aliases = { "@product": "img-456" } +``` + +**Rationale:** User wants to delete - remove completely, free storage. Alias entries are also completely removed. + +### 7.2 Generation Deletion (Conditional) + +**DELETE /api/v1/generations/:id** + +**Behavior depends on output image alias:** + +**Case 1: Output image WITHOUT project alias** +1. Delete output image completely (hard delete with MinIO cleanup) +2. Delete generation record (hard delete) + +**Case 2: Output image WITH project alias** +1. Keep output image (do not delete) +2. Delete only generation record (hard delete) +3. Set `generationId = NULL` in image record + +**Decision Logic:** +- If `outputImage.alias !== null` → keep image, delete only generation +- If `outputImage.alias === null` → delete both image and generation + +**Rationale:** +- Image with project alias is used as standalone asset, preserve it +- Image without alias was created only for this generation, delete together + +**No regeneration of deleted generations** - deleted generations cannot be regenerated + +### 7.3 Flow Deletion (Cascade with Alias Protection) + +**DELETE /api/v1/flows/:id** + +**Operations:** +1. Delete flow record from DB +2. Cascade: delete all generations associated with this flowId +3. Cascade: delete all images associated with this flowId **EXCEPT** images with project alias + +**Detailed Cascade Logic:** + +**For Generations:** +- Delete each generation (follows conditional delete from 7.2) +- If output image has no alias → delete image +- If output image has alias → keep image, set generationId = NULL, set flowId = NULL + +**For Images (uploaded):** +- If image has no alias → delete (with MinIO cleanup) +- If image has alias → keep, set flowId = NULL + +**Summary:** +- Flow record → DELETE +- All generations → DELETE +- Images without alias → DELETE (with MinIO cleanup) +- Images with project alias → KEEP (unlink: flowId = NULL) + +**Rationale:** +Flow deletion removes all content except images with project aliases (used globally in project). + +### 7.4 Transactional Delete Pattern + +**All delete operations must be transactional:** + +1. Delete from MinIO storage first +2. Delete from database (with cascades) +3. If MinIO delete fails → rollback DB transaction +4. If DB delete fails → cleanup MinIO file (or rollback if possible) +5. Log all delete operations for audit trail + +**Principle:** System must be designed so orphaned files in MinIO NEVER occur. + +**Database Constraints:** +- ON DELETE CASCADE for appropriate foreign keys +- ON DELETE SET NULL where related records must be preserved +- Proper referential integrity + +**No background cleanup jobs needed** - system is self-sufficient and always consistent. + +--- + +## 8. Live URL System + +### 8.1 Core Concept + +**Purpose:** Permanent URLs that can be immediately inserted into HTML and work forever. + +**Use Case:** +```html + +``` + +**Key Points:** +- URL is constructed immediately and used permanently +- No preliminary generation through API needed +- No signed URLs or tokens in query params +- First request → generation, subsequent → cache + +### 8.2 URL Format & Structure + +**URL Pattern:** +``` +/cdn/:orgSlug/:projectSlug/live/:scope?prompt=...&aspectRatio=... +``` + +**URL Components:** +``` +/cdn/acme/website/live/hero-section?prompt=beautiful_sunset&aspectRatio=16:9 + │ │ │ │ │ + │ │ │ │ └─ Generation params (query string) + │ │ │ └─ Scope identifier + │ │ └─ "live" prefix + │ └─ Project slug + └─ Organization slug +``` + +**Scope Parameter:** +- Name: `scope` (confirmed) +- Purpose: logical separation of live URLs within project +- Format: alphanumeric + hyphens + underscores +- Any user can specify any scope (no validation/signature required) + +### 8.3 First Request Flow + +**Cache MISS (first request):** +1. Parse orgSlug, projectSlug, scope from URL +2. Compute cache key: hash(projectId + scope + prompt + params) +3. Check if image exists in cache +4. If NOT found: + - Check scope settings (allowNewGenerations, limit) + - Trigger image generation + - Create database records (generation, image, cache entry) + - Wait for generation to complete + - Return image bytes + +**Response:** +- Content-Type: image/jpeg +- Cache-Control: public, max-age=31536000 +- X-Cache-Status: MISS +- X-Scope: hero-section +- X-Image-Id: uuid + +**Cache HIT (subsequent requests):** +1. Same cache key lookup +2. Found existing image +3. Return cached image bytes immediately + +**Response:** +- Content-Type: image/jpeg +- Cache-Control: public, max-age=31536000 +- X-Cache-Status: HIT +- X-Image-Id: uuid + +**Generation in Progress:** +- If image is not in cache but generation is already running: +- System must have internal status to track this +- Wait for generation to complete +- Return image bytes immediately when ready +- This ensures consistent behavior for concurrent requests + +### 8.4 Scope Management + +**Database Table: `live_scopes`** + +Create dedicated table with fields: +- `id` (UUID, primary key) +- `project_id` (UUID, foreign key to projects) +- `slug` (TEXT, unique within project) - used in URL +- `allowNewGenerations` (BOOLEAN, default: true) - controls if new generations can be triggered +- `newGenerationsLimit` (INTEGER, default: 30) - max number of generations in this scope +- `created_at` (TIMESTAMP) +- `updated_at` (TIMESTAMP) + +**Scope Behavior:** + +**allowNewGenerations:** +- Controls whether new generations can be triggered in this scope +- Already generated images are ALWAYS served publicly regardless of this setting +- Default: true + +**newGenerationsLimit:** +- Limit on number of generations in this scope +- Only affects NEW generations, does not affect regeneration +- Default: 30 + +**Scope Creation:** +- Manual: via dedicated endpoint (see below) +- Automatic: when new scope is used in live URL (if project allows) + +**Project-level Settings:** + +Add to projects table or settings: +- `allowNewLiveScopes` (BOOLEAN, default: true) - allows creating new scopes via live URLs + - If false: new scopes cannot be created via live URL + - If false: scopes can still be created via API endpoint +- `newLiveScopesGenerationLimit` (INTEGER, default: 30) - generation limit for auto-created scopes + - This value is set as `newGenerationsLimit` for newly created scopes + +### 8.5 Scope Management API + +**Create scope (manual):** +``` +POST /api/v1/live/scopes +Headers: X-API-Key: bnt_project_key +Body: { + "slug": "hero-section", + "allowNewGenerations": true, + "newGenerationsLimit": 50 +} +``` + +**List scopes:** +``` +GET /api/v1/live/scopes +Headers: X-API-Key: bnt_project_key +Response: { + "scopes": [ + { + "id": "uuid", + "slug": "hero-section", + "allowNewGenerations": true, + "newGenerationsLimit": 50, + "currentGenerations": 23, + "lastGeneratedAt": "2024-01-15T10:30:00Z" + } + ] +} +``` + +**Get scope details:** +``` +GET /api/v1/live/scopes/:slug +Headers: X-API-Key: bnt_project_key +Response: { + "id": "uuid", + "slug": "hero-section", + "allowNewGenerations": true, + "newGenerationsLimit": 50, + "currentGenerations": 23, + "images": [...] +} +``` + +**Update scope:** +``` +PUT /api/v1/live/scopes/:slug +Headers: X-API-Key: bnt_project_key +Body: { + "allowNewGenerations": false, + "newGenerationsLimit": 100 +} +``` + +**Regenerate scope images:** +``` +POST /api/v1/live/scopes/:slug/regenerate +Headers: X-API-Key: bnt_project_key +Body: { "imageId": "uuid" } // Optional: regenerate specific image +Response: { + "regenerated": 1, + "images": [...] +} +``` + +**Delete scope:** +``` +DELETE /api/v1/live/scopes/:slug +Headers: X-API-Key: bnt_project_key +``` + +**Deletion behavior:** Deletes all images in this scope (follows standard image deletion with alias protection). + +### 8.6 Security & Rate Limiting + +**Rate Limiting by IP:** +- Aggressive limits for live URLs (e.g., 10 new generations per hour per IP) +- Separate from API key limits +- Cache hits do NOT count toward limit +- Only new generations count + +**Scope Quotas:** +- Maximum N unique prompts per scope (newGenerationsLimit) +- After limit reached → return existing images, do not generate new +- Regeneration does not count toward limit + +### 8.7 Caching Strategy + +**Cache Key:** +``` +cacheKey = hash(projectId + scope + prompt + aspectRatio + otherParams) +``` + +**Cache Invalidation:** +- Manual: via API endpoint regenerate +- Automatic: never (images cached forever unless explicitly regenerated) + +**Scope Naming:** `scope` (confirmed) + +**URL Encoding:** +- Prompt in query string: URL-encoded or underscores for spaces +- Both formats supported: `prompt=beautiful%20sunset` and `prompt=beautiful_sunset` +- Scope in path: alphanumeric + hyphens + underscores + +### 8.8 Error Handling + +**Detailed errors for live URLs:** + +- Invalid scope format → 400 "Invalid scope format. Use alphanumeric characters, hyphens, and underscores" +- New scope creation disabled → 403 "Creating new live scopes is disabled for this project" +- Generation limit exceeded → 429 "Scope generation limit exceeded. Maximum N generations per scope" +- Generation fails → 500 with retry logic +- Rate limit by IP exceeded → 429 "Rate limit exceeded. Try again in X seconds" with Retry-After header + +--- + +## 9. Generation Modification + +### 9.1 Update Generation Endpoint + +**New endpoint:** +``` +PUT /api/v1/generations/:id +``` + +**Modifiable Fields:** +- `prompt` - change prompt +- `aspectRatio` - change aspect ratio +- `flowId` - change/remove/add flow association +- `meta` - update metadata + +**Behavior:** + +**Case 1: Non-generative parameters (flowId, meta)** +- Simply update fields in DB +- Do NOT regenerate image + +**Case 2: Generative parameters (prompt, aspectRatio)** +- Update fields in DB +- Automatically trigger regeneration +- Update existing image (same imageId, path, URL) + +### 9.2 FlowId Management + +**FlowId handling:** +- `flowId: null` → detach from flow +- `flowId: "new-uuid"` → attach to different flow + - If flow doesn't exist → create new flow eagerly (with this flowId) + - If flow exists → add generation to existing flow +- `flowId: undefined` → do not change current value + +**Use Case - "Detach from Flow":** +- Set `flowId: null` to detach generation from flow +- Output image is preserved (if has alias) +- Useful before deleting flow to protect important generations + +### 9.3 Validation Rules + +**Use existing validation logic from generation creation:** +- Prompt validation (existing rules) +- AspectRatio validation (existing rules) +- FlowId validation: + - If provided (not null): must be valid UUID format + - Flow does NOT need to exist (will be created eagerly if missing) + - Allow null explicitly (for detachment) + +### 9.4 Response Format + +```json +{ + "success": true, + "data": { + "id": "gen-uuid", + "prompt": "updated prompt", + "aspectRatio": "16:9", + "flowId": null, + "status": "processing", // If regeneration triggered + "regenerated": true, // Flag indicating regeneration started + "outputImage": { ... } // Current image (updates when regeneration completes) + } +} +``` + +--- + +## 10. Response Format Consistency + +### 10.1 FlowId in Responses + +**Rule for flowId in generation and upload responses:** + +**If request has `flowId: undefined` (not provided):** +- Generate new flowId +- Return in response: `"flowId": "new-uuid"` + +**If request has `flowId: null` (explicitly null):** +- Do NOT generate flowId +- Flow is definitely not needed +- Return in response: `"flowId": null` + +**If request has `flowId: "uuid"` (specific value):** +- Use provided flowId +- Return in response: `"flowId": "uuid"` + +**Examples:** +```json +// Request without flowId +POST /api/v1/generations +Body: { "prompt": "sunset" } +Response: { "flowId": "generated-uuid", ... } + +// Request with explicit null +POST /api/v1/generations +Body: { "prompt": "sunset", "flowId": null } +Response: { "flowId": null, ... } + +// Request with specific flowId +POST /api/v1/generations +Body: { "prompt": "sunset", "flowId": "my-flow-uuid" } +Response: { "flowId": "my-flow-uuid", ... } +``` + +--- + +## 11. Error Messages Updates + +**Remove constants:** +- `GENERATION_ALREADY_SUCCEEDED` (no longer needed) +- `MAX_RETRY_COUNT_EXCEEDED` (no longer needed) + +**Add constants:** +- `SCOPE_INVALID_FORMAT` - "Invalid scope format. Use alphanumeric characters, hyphens, and underscores" +- `SCOPE_CREATION_DISABLED` - "Creating new live scopes is disabled for this project" +- `SCOPE_GENERATION_LIMIT_EXCEEDED` - "Scope generation limit exceeded. Maximum {limit} generations per scope" +- `STORAGE_DELETE_FAILED` - "Failed to delete file from storage" + +**Update constants:** +- `GENERATION_FAILED` - include details about network/storage errors +- `IMAGE_NOT_FOUND` - distinguish between deleted and never existed + +--- + +## Summary of Changes + +### Database Changes +1. Rename `enhancedPrompt` → `originalPrompt` in generations table +2. Create `live_scopes` table with fields: id, project_id, slug, allowNewGenerations, newGenerationsLimit +3. Add project settings: allowNewLiveScopes, newLiveScopesGenerationLimit +4. Add `scope` and `isLiveUrl` fields to images table (optional, can use meta) + +### API Changes +1. Rename parameters: assignAlias → alias, assignFlowAlias → flowAlias +2. Rename endpoint: POST /generations/:id/retry → /generations/:id/regenerate +3. Remove endpoint: POST /api/v1/flows (no longer needed) +4. Add endpoint: POST /api/v1/flows/:id/regenerate +5. Add endpoint: PUT /api/v1/generations/:id (modification) +6. Add CDN endpoints: + - GET /cdn/:org/:project/img/:filenameOrAlias (all images) + - GET /cdn/:org/:project/live/:scope (live URLs) +7. Add scope management endpoints (CRUD for live_scopes) +8. Update all image URLs in API responses to use CDN format + +### Behavior Changes +1. Lazy flow creation (create on second request or when flowAlias present) +2. Alias conflict resolution (new overwrites old) +3. Regenerate updates existing image (same ID, path, URL) +4. Hard delete for images (with MinIO cleanup) +5. Conditional delete for generations (based on alias) +6. Cascade delete for flows (with alias protection) +7. Live URL caching and scope management +8. FlowId in responses (generate if undefined, keep if null) + +### Validation Changes +1. @ symbol distinguishes aliases from UUIDs +2. Technical aliases forbidden in user input +3. Flow creation on-the-fly for non-existent flowIds +4. Scope format validation for live URLs diff --git a/docs/api/image-generation.rest b/docs/api/image-generation.rest index 924f8e3..4483cb6 100644 --- a/docs/api/image-generation.rest +++ b/docs/api/image-generation.rest @@ -208,5 +208,5 @@ X-API-Key: {{apiKey}} ### Generate with Prompt Caching # Generate images with intelligent caching based on prompt hash # Returns raw image bytes (not JSON) -GET {{base}}/api/v1/live?prompt=A beautiful sunset&aspectRatio=16:9 +GET {{base}}/api/v1/live?prompt=грузовик едет по горной дороге&aspectRatio=16:9 X-API-Key: {{apiKey}} diff --git a/docs/api/references.rest b/docs/api/references.rest new file mode 100644 index 0000000..7c8dba7 --- /dev/null +++ b/docs/api/references.rest @@ -0,0 +1,127 @@ +@base = http://localhost:3000 +@apiKey = bnt_71e7e16732ac5e21f597edc56e99e8c3696e713552ec9d1f44dfeffb2ef7c495 + +############################################################################### +# IMAGE REFERENCES & ALIASES TESTING +# This file demonstrates the complete flow of: +# 1. Generating an image with an alias +# 2. Verifying the alias is assigned +# 3. Using that alias as a reference in another generation +############################################################################### + + +############################################################################### +# STEP 1: Generate Simple Logo (1:1 aspect ratio) +############################################################################### + +# @name generateLogo +POST {{base}}/api/v1/generations +Content-Type: application/json +X-API-Key: {{apiKey}} + +{ + "prompt": "A sleek and modern company logo featuring a stylized character @ turning it into a snail in blue and brown colors, minimalist design, vector art", + "aspectRatio": "1:1", + "assignAlias": "@logo-snail", + "autoEnhance": false +} + +### + +@logoGenerationId = {{generateLogo.response.body.$.data.id}} +@logoImageId = {{generateLogo.response.body.$.data.outputImageId}} + + +############################################################################### +# STEP 2: Verify Logo Alias Assignment +############################################################################### + +### Resolve @logo Alias +# Confirm that @logo alias is properly assigned and retrieve image metadata +GET {{base}}/api/v1/images/resolve/@logo-snail +X-API-Key: {{apiKey}} + +### + +### Get Logo Generation Details +# View complete generation record with output image +GET {{base}}/api/v1/generations/{{logoGenerationId}} +X-API-Key: {{apiKey}} + +### + +### Get Logo Image Details +# View image record directly by ID +GET {{base}}/api/v1/images/{{logoImageId}} +X-API-Key: {{apiKey}} + + +############################################################################### +# STEP 3: Generate Lorry with Logo Reference +############################################################################### + +# @name generateLorry +POST {{base}}/api/v1/generations +Content-Type: application/json +X-API-Key: {{apiKey}} + +{ + "prompt": "A modern lorry truck driving on a winding mountain road during sunset, the truck has a large @logo-snail prominently displayed on its side panel, photorealistic style, golden hour lighting, detailed commercial vehicle, scenic mountain landscape", + "aspectRatio": "16:9", + "referenceImages": ["@logo-snail"], + "assignAlias": "@lorry-branded", + "autoEnhance": false +} + +### + +@lorryGenerationId = {{generateLorry.response.body.$.data.id}} +@lorryImageId = {{generateLorry.response.body.$.data.outputImageId}} + + +############################################################################### +# VERIFICATION: Check Both Generations +############################################################################### + +### List All Generations +# View both logo and lorry generations in the project +GET {{base}}/api/v1/generations?limit=10&offset=0 +X-API-Key: {{apiKey}} + +### + +### Resolve @lorry-branded Alias +# Confirm the lorry image alias is assigned +GET {{base}}/api/v1/images/resolve/@lorry-branded +X-API-Key: {{apiKey}} + +### + +### Get Lorry Generation Details +# View complete generation with reference images +GET {{base}}/api/v1/generations/{{lorryGenerationId}} +X-API-Key: {{apiKey}} + +### + +### List All Images +# View both logo and lorry images +GET {{base}}/api/v1/images?limit=10&offset=0 +X-API-Key: {{apiKey}} + + +############################################################################### +# BONUS: Test Technical Aliases +############################################################################### + +### Resolve @last (Most Recent Image) +# Should return the lorry image (most recently generated) +GET {{base}}/api/v1/images/resolve/@last +X-API-Key: {{apiKey}} + +### + +### Resolve @first (First Generated Image) +# Should return the logo image (first generated in this flow) +GET {{base}}/api/v1/images/resolve/@first +X-API-Key: {{apiKey}}