Update admin.md to reflect Phase 3 Part 3 implementation changes:
**Rate Limiting Section:**
- Split into two subsections: API Key Rate Limiting and IP-Based Rate Limiting
- API Key Rate Limiting: Expanded affected endpoints list to include scope management
- IP-Based Rate Limiting: New section documenting 10/hour limit for live URLs
- Separate from API key limits
- Only cache MISS counts toward limit
- Supports X-Forwarded-For header
- In-memory store with automatic cleanup
**Error Codes Section:**
- Reorganized into categorized tables for better clarity
- Added HTTP 409 (Conflict) status code
- Added Authentication Error Codes table
- Added Rate Limiting Error Codes table with both API key and IP limits
- Added Live Scope Error Codes table:
- SCOPE_INVALID_FORMAT (400)
- SCOPE_ALREADY_EXISTS (409)
- SCOPE_NOT_FOUND (404)
- IMAGE_NOT_IN_SCOPE (400)
**Documentation Improvements:**
- All error responses include standard format
- Rate limit errors include Retry-After header
- Scope endpoints require project key authentication
- Comprehensive notes for each section
All documentation now accurately reflects current API v1 implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add complete JSDoc documentation to all API v1 endpoints with detailed descriptions,
parameters, returns, error codes, and usage examples (Section 12).
**Generation Endpoints (generations.ts):**
- POST / - Create generation with references, aliases, and enhancement
- GET / - List with flow/status filtering and pagination
- GET /:id - Get single generation with full relations
- PUT /:id - Update with auto-regeneration on prompt/aspectRatio change
- POST /:id/regenerate - Regenerate with exact same parameters
- POST /:id/retry - Legacy endpoint (deprecated, delegates to regenerate)
- DELETE /:id - Delete with alias protection rules
**Flow Endpoints (flows.ts):**
- GET / - List flows with computed counts and pagination
- GET /:id - Get single flow with generationCount and imageCount
- GET /:id/generations - List flow's generations with pagination
- GET /:id/images - List flow's images with pagination
- PUT /:id/aliases - Update flow-scoped aliases (JSONB merge)
- DELETE /:id/aliases/:alias - Remove specific flow alias
- POST /:id/regenerate - Regenerate most recent generation in flow
- DELETE /:id - Hard delete flow (generations/images remain)
**Image Endpoints (images.ts):**
- POST /upload - Upload with flowId logic (undefined=auto, null=none, string=specific)
- GET / - List with flow/source/alias filtering and pagination
- GET /resolve/:alias - 3-tier resolution (technical → flow → project)
- GET /:id - Get single image with complete details
- PUT /:id - Update focal point and metadata
- PUT /:id/alias - Assign project-scoped alias (Section 6.1)
- DELETE /:id - Hard delete with MinIO cleanup and cascades
**CDN Endpoints (cdn.ts):**
- GET /:orgSlug/:projectSlug/img/:filenameOrAlias - Public image serving
- Supports filename and @alias access
- Long-term browser caching (1 year)
- No authentication required
- GET /:orgSlug/:projectSlug/live/:scope - Live URL generation
- Automatic prompt-based caching
- IP rate limiting (10/hour, cache hits excluded)
- Lazy scope creation
- Scope generation limits
- Cache key from prompt + params
- X-Cache-Status: HIT|MISS headers
**Scope Management Endpoints (scopes.ts):**
- POST / - Create scope manually with settings
- GET / - List with currentGenerations stats and pagination
- GET /:slug - Get single scope by slug with stats
- PUT /:slug - Update settings (allowNewGenerations, limits)
- POST /:slug/regenerate - Regenerate specific image or all in scope
- DELETE /:slug - Delete scope with cascading image deletion
**JSDoc Standards Applied:**
- Complete function descriptions with use cases
- @route method and path
- @authentication requirements and key types
- @rateLimit specifications where applicable
- @param detailed parameter descriptions with types and optionality
- @returns status codes with response descriptions
- @throws error codes with explanations
- @example realistic usage examples with request/response samples
- @deprecated tags for legacy endpoints
**Documentation Features:**
- Comprehensive parameter descriptions
- Default values clearly indicated
- Type information for all parameters
- Error code documentation
- Multiple examples per complex endpoint
- Response header documentation
- Cache behavior explanations
- Flow logic documentation
- Alias resolution precedence details
- Rate limiting specifics
All JSDoc follows standardized format for consistent API documentation
across the entire v1 API surface. Zero new TypeScript errors introduced.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement comprehensive live scope management API and IP-based rate limiting
for live URL generation endpoints (Sections 8.5 and 8.6).
**Scope Management CRUD Endpoints:**
- POST /api/v1/live/scopes - Create scope manually with slug validation
- GET /api/v1/live/scopes - List scopes with pagination and stats
- GET /api/v1/live/scopes/:slug - Get single scope by slug with stats
- PUT /api/v1/live/scopes/:slug - Update scope settings
- POST /api/v1/live/scopes/:slug/regenerate - Regenerate scope images
- DELETE /api/v1/live/scopes/:slug - Delete scope with cascading image deletion
**Scope Management Features:**
- Slug format validation (alphanumeric, hyphens, underscores)
- Duplicate slug prevention with 409 Conflict response
- Scope statistics (currentGenerations, lastGeneratedAt)
- Settings management (allowNewGenerations, newGenerationsLimit)
- Regeneration support (single image or all images in scope)
- Hard delete with image cleanup following alias protection rules
- All endpoints require Project Key authentication
**IP-Based Rate Limiting:**
- In-memory rate limit store with automatic cleanup
- Limits: 10 new generations per hour per IP address
- Only cache MISS (new generation) counts toward limit
- Cache HIT does NOT count toward limit
- X-Forwarded-For header support for proxy/load balancer setups
- Rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
- Retry-After header on 429 Too Many Requests response
- Automatic cleanup of expired entries every 5 minutes
**IP Rate Limiter Middleware:**
- ipRateLimiterMiddleware attaches to live URL endpoint
- getClientIp() extracts IP from X-Forwarded-For or req.ip
- checkIpRateLimit() validates and increments counter
- getRemainingRequests() returns available request count
- getResetTime() returns seconds until reset
- Middleware attaches checkIpRateLimit function to request
- Rate limit check executed AFTER cache check (only for cache MISS)
**Type System Updates:**
- Added LiveScopeResponse interface with all scope fields
- Added LiveScopeWithImagesResponse with images array
- Added response type aliases for all CRUD operations
- Added toLiveScopeResponse() converter function
- Added CreateLiveScopeRequest, UpdateLiveScopeRequest interfaces
- Added ListLiveScopesQuery with pagination parameters
- Added RegenerateScopeRequest with optional imageId
**Route Integration:**
- Mounted scopes router at /api/v1/live/scopes
- Applied ipRateLimiterMiddleware to live URL endpoint
- Rate limit increments only on cache MISS (new generation)
- Cache HIT bypasses rate limit check entirely
**Technical Notes:**
- All scope endpoints return toLiveScopeResponse() format
- Pagination using buildPaginationMeta helper
- Bracket notation for meta field access (TypeScript strict mode)
- Proper number parsing with fallback defaults
- All Phase 3 Part 3 code is fully type-safe with zero TypeScript errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement foundation for live URL system with database schema, relations,
and comprehensive service layer for live scope management.
**Database Schema (Section 8.4):**
- **liveScopes table** with fields:
- id (UUID primary key)
- projectId (foreign key to projects, cascade delete)
- slug (text, unique within project)
- allowNewGenerations (boolean, default: true)
- newGenerationsLimit (integer, default: 30)
- meta (JSONB for flexible metadata)
- createdAt, updatedAt timestamps
- **Constraints & Indexes:**
- Unique constraint on (projectId, slug) combination
- Index for project lookups
- Index for project+slug lookups
- **Relations:**
- projects → liveScopes (one-to-many)
- liveScopes → project (many-to-one)
**Type Definitions:**
- Added LiveScope, NewLiveScope types from database schema
- Added LiveScopeWithStats interface with computed fields:
- currentGenerations: number (count of images in scope)
- lastGeneratedAt: Date | null (latest generation timestamp)
- images?: Image[] (optional images array)
- Added LiveScopeFilters interface for query filtering
**LiveScopeService:**
- **Core CRUD operations:**
- create() - Create new scope
- getById() - Get scope by UUID
- getBySlug() - Get scope by slug within project
- getByIdOrThrow() / getBySlugOrThrow() - With error handling
- update() - Update scope settings
- delete() - Hard delete scope (images preserved)
- **Statistics & Computed Fields:**
- getByIdWithStats() - Scope with generation count and last generated date
- getBySlugWithStats() - Same but lookup by slug
- list() - Paginated list with stats for each scope
- **Business Logic:**
- canGenerateNew() - Check if scope allows new generations
- createOrGet() - Lazy creation with project defaults
- Uses images.meta field for scope tracking (scope, isLiveUrl)
**Technical Notes:**
- Images track scope via meta.scope field (no schema changes to images table)
- Scope statistics computed from images where meta.scope = slug and meta.isLiveUrl = true
- Project settings (allowNewLiveScopes, newLiveScopesGenerationLimit) already added in Phase 2
- All code compiles with zero new TypeScript errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement comprehensive deletion cascade logic, upload enhancements, and alias
management updates for Phase 2 Part 2 of the API refactoring.
**Upload Enhancements (Section 5):**
- POST /api/v1/images/upload now supports flowAlias parameter
- Eager flow creation: creates flow record immediately when flowAlias provided
- FlowId logic: undefined → generate UUID, null → keep null, UUID → use provided
- Automatically assigns flowAlias in flow.aliases JSONB upon upload
**Alias Management (Section 6):**
- Removed alias from PUT /api/v1/images/:id request body
- Only focalPoint and meta can be updated via PUT endpoint
- Use dedicated PUT /api/v1/images/:id/alias endpoint for alias assignment
**Deletion Strategy Overhaul (Section 7):**
- **ImageService.hardDelete()** with MinIO cleanup and cascades:
- Deletes physical file from MinIO storage
- Cascades: sets outputImageId=NULL in related generations
- Cascades: removes alias entries from flow.aliases
- Cascades: removes imageId from generation.referencedImages arrays
- MVP approach: proceeds with DB cleanup even if MinIO fails
- **GenerationService.delete()** with conditional logic:
- If output image WITHOUT alias → hard delete both image and generation
- If output image WITH alias → keep image, delete generation only, set generationId=NULL
- **FlowService.delete()** with cascade and alias protection:
- Deletes all generations (uses conditional delete logic)
- Deletes all images WITHOUT alias
- Keeps images WITH alias (sets flowId=NULL)
- Deletes flow record from database
**Type Updates:**
- UploadImageRequest: Added flowAlias parameter (string)
- UpdateImageRequest: Removed alias field (Section 6.1)
- GenerationResponse: Updated prompt fields to match reversed semantics
- prompt: string (what was actually used for generation)
- originalPrompt: string | null (user's original, only if enhanced)
- DeleteImageResponse: Changed to { id: string } (hard delete, no deletedAt)
**Error Constants (Section 11):**
- Removed: GENERATION_ALREADY_SUCCEEDED, MAX_RETRY_COUNT_EXCEEDED
- Added: SCOPE_INVALID_FORMAT, SCOPE_CREATION_DISABLED,
SCOPE_GENERATION_LIMIT_EXCEEDED, STORAGE_DELETE_FAILED
**Technical Notes:**
- Hard delete replaces soft delete throughout the system
- Cascade operations maintain referential integrity
- Alias protection ensures valuable images are preserved
- All Phase 2 Part 2 code compiles with zero new TypeScript errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
**Parameter Renames (Section 1.1):**
- Rename `assignAlias` → `alias` in CreateGenerationRequest
- Rename `assignFlowAlias` → `flowAlias` (changed from Record<string, string> to string)
- Rename `flowAliases` → `flowAlias` in UploadImageRequest
- Update all route handlers and service methods to use new names
- Simplify flowAlias logic to assign single alias string to output image
**Reference Image Auto-Detection (Section 1.2):**
- Add `extractAliasesFromPrompt()` function with regex pattern: /(?:^|\s)(@[\w-]+)/g
- Make `referenceImages` parameter optional
- Auto-detect aliases from prompt text and merge with manual references
- Manual references have priority (listed first), then auto-detected
- Remove duplicates while preserving order
- Invalid aliases are silently skipped (validated with isValidAliasFormat)
**FlowId Response Logic (Section 10.1):**
- If `flowId: undefined` (not provided) → generate new UUID, return in response
- If `flowId: null` (explicitly null) → keep null, don't generate
- If `flowId: "uuid"` (specific value) → use provided value
- Eager flow creation when `flowAlias` is provided (create flow immediately in DB)
**Generation Modification Endpoint (Section 9):**
- Add `PUT /api/v1/generations/:id` endpoint
- Modifiable fields: prompt, aspectRatio, flowId, meta
- Non-generative params (flowId, meta) → update DB only
- Generative params (prompt, aspectRatio) → update DB + trigger regeneration
- FlowId management: null to detach, UUID to attach/change (with eager creation)
- Regeneration updates existing image (same ID, same MinIO path)
**Type Definitions:**
- Update CreateGenerationParams interface with new parameter names
- Add UpdateGenerationRequest interface
- Add extractAliasesFromPrompt export to validators index
**Documentation:**
- Update REST API examples with new parameter names
**Technical Notes:**
- All Phase 1 changes are backward compatible at the data layer
- TypeScript strict mode passes (no new errors introduced)
- Pre-existing TypeScript errors in middleware and other routes remain unchanged
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>