feature/api-development #1
Loading…
Reference in New Issue
No description provided.
Delete Branch "feature/api-development"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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>Implement public CDN endpoints for serving images and live URL generation with intelligent caching based on prompt hashing. **CDN Routes (Section 8):** - **GET /cdn/:orgSlug/:projectSlug/img/:filenameOrAlias** - Public endpoint (no authentication) - Serve images by filename or project-scoped alias - Resolves org and project from slugs - Supports @alias syntax or filename lookup - Returns image bytes with 1-year cache headers - Headers: Content-Type, Content-Length, Cache-Control, X-Image-Id - **GET /cdn/:orgSlug/:projectSlug/live/:scope** - Public endpoint (no authentication) - Live URL generation with caching - Query params: prompt, aspectRatio, autoEnhance, template - Cache key: SHA-256(projectId + scope + prompt + params) - Cache HIT: Returns cached image immediately - Cache MISS: Generates new image, caches, returns - Scope management: auto-create or check limits - Image meta tracking: scope, isLiveUrl, cacheKey - Headers: X-Cache-Status (HIT/MISS), X-Scope, X-Image-Id, X-Generation-Id **Cache Key Helper:** - computeLiveUrlCacheKey() - SHA-256 hash for live URL caching - computePromptHash() - SHA-256 hash for prompt caching - Normalized parameters for consistent cache keys **Live URL Flow (Section 8.3):** 1. Validate prompt and scope format (alphanumeric + hyphens + underscores) 2. Resolve org, project from slugs 3. Compute cache key from params 4. Check cache via images.meta.cacheKey 5. If HIT: serve cached image 6. If MISS: check scope limits, generate, cache, serve 7. Lazy scope creation with project defaults 8. Enforce newGenerationsLimit per scope **Service Exports:** - Added LiveScopeService to core services index - Available for dependency injection **App Routing:** - Mounted CDN router at /cdn (public, before auth routes) - CDN endpoints are completely public (no API key required) **Technical Notes:** - Images tagged with meta: { scope, isLiveUrl: true, cacheKey } - Scope statistics computed from images with matching meta - Cache controlled via Cache-Control: public, max-age=31536000 - System generations use apiKeyId: null - All code compiles with zero new TypeScript errors 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>