banatie-service/api-refactoring-final.md

28 KiB

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

1.2 Reference Images Auto-Detection

Parameter behavior:

  • referenceImages parameter is optional
  • If provided (array of aliases or IDs) → use these images as references
  • If empty or not provided → service must automatically parse prompt and find all aliases

Auto-detection logic:

  1. Prompt parsing:

    • Scan prompt text for all alias patterns (@name)
    • Extract all found aliases
    • Resolve each alias to actual image ID
  2. Manual override:

    • If referenceImages parameter is provided and not empty → use only specified images
    • Manual list takes precedence over auto-detected aliases
  3. Combined approach:

    • If referenceImages provided → add to auto-detected aliases (merge)
    • Remove duplicates
    • Maintain order: manual references first, then auto-detected

Example:

// Auto-detection (no referenceImages parameter)
{
  "prompt": "A landscape based on @sunset with elements from @mountain"
  // System automatically detects @sunset and @mountain
}

// Manual specification
{
  "prompt": "A landscape",
  "referenceImages": ["@sunset", "image-uuid-123"]
  // System uses only specified images
}

// Combined
{
  "prompt": "A landscape based on @sunset",
  "referenceImages": ["@mountain"]
  // System uses both @mountain (manual) and @sunset (auto-detected)
}

Implementation notes:

  • Alias detection must use the same validation rules as alias creation
  • Invalid aliases in prompt should be logged but not cause generation failure
  • Maximum reference images limit still applies after combining manual + auto-detected

2. Enhanced Prompt Support - Logic Redesign

2.1 Database Schema Changes

Required schema modifications:

  1. Rename field: enhancedPromptoriginalPrompt
  2. Change field semantics:
    • prompt - ALWAYS contains the prompt that was used for generation (enhanced or original)
    • originalPrompt - ALWAYS contains user's original input (for transparency and audit trail)

Field population logic:

Case 1: autoEnhance = false
  prompt = user input
  originalPrompt = user input (same value, preserved for consistency)

Case 2: autoEnhance = true
  prompt = enhanced prompt (used for generation)
  originalPrompt = user input (preserved)

Rationale: Always storing originalPrompt provides:

  • Audit trail of user's actual input
  • Ability to compare original vs enhanced prompts
  • Consistent API response structure
  • Simplified client logic (no null checks needed)

2.2 API Response Format

Response structure:

{
  "prompt": "detailed enhanced prompt...",  // Always the prompt used for generation
  "originalPrompt": "sunset",               // Always the user's original input
  "autoEnhance": true                       // True if prompt differs from originalPrompt
}

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:

<img src="https://banatie.app/cdn/acme/website/live/hero-section?prompt=beautiful_sunset&aspectRatio=16:9"/>

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

{
  "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:

// 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

12. Code Documentation Standards

12.1 Endpoint JSDoc Comments

Requirement: Every API endpoint must have comprehensive JSDoc comment.

Required sections:

  1. Purpose: What this endpoint does (one sentence)
  2. Logic: Brief description of how it works (2-3 key steps)
  3. Parameters: Description of each parameter and what it affects
  4. Authentication: Required authentication level
  5. Response: What is returned

Example format:

/**
 * Generate new image from text prompt with optional reference images.
 *
 * Logic:
 * 1. Parse prompt to auto-detect reference image aliases
 * 2. Resolve all aliases (auto-detected + manual) to image IDs
 * 3. Trigger AI generation with prompt and reference images
 * 4. Store result with metadata and return generation record
 *
 * @param {string} prompt - Text description for image generation (affects: output style and content)
 * @param {string[]} referenceImages - Optional aliases/IDs for reference images (affects: visual style transfer)
 * @param {string} aspectRatio - Image dimensions ratio (affects: output dimensions, default: 1:1)
 * @param {string} flowId - Optional flow association (affects: organization and flow-scoped aliases)
 * @param {string} alias - Optional project-scoped alias (affects: image referencing across project)
 * @param {string} flowAlias - Optional flow-scoped alias (affects: image referencing within flow)
 * @param {boolean} autoEnhance - Enable AI prompt enhancement (affects: prompt quality and detail)
 * @param {object} meta - Custom metadata (affects: searchability and organization)
 *
 * @authentication Project Key required
 * @returns {GenerationResponse} Generation record with status and output image details
 */
router.post('/generations', ...);

Apply to:

  • All route handlers in /routes/**/*.ts
  • All public service methods that implement core business logic
  • Complex utility functions with non-obvious behavior

Parameter descriptions must include "affects:"

  • Explain what each parameter influences in the system
  • Help developers understand parameter impact
  • Make API more discoverable and self-documenting

Summary of Changes

Database Changes

  1. Rename enhancedPromptoriginalPrompt 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. Make referenceImages parameter optional with auto-detection from prompt
  3. Rename endpoint: POST /generations/:id/retry → /generations/:id/regenerate
  4. Remove endpoint: POST /api/v1/flows (no longer needed)
  5. Add endpoint: POST /api/v1/flows/:id/regenerate
  6. Add endpoint: PUT /api/v1/generations/:id (modification)
  7. Add CDN endpoints:
    • GET /cdn/:org/:project/img/:filenameOrAlias (all images)
    • GET /cdn/:org/:project/live/:scope (live URLs)
  8. Add scope management endpoints (CRUD for live_scopes)
  9. 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)
  9. Auto-detect reference images from prompt aliases

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

Documentation Changes

  1. Add comprehensive JSDoc comments to all endpoints
  2. Include purpose, logic, parameters with "affects" descriptions
  3. Document authentication requirements in comments