--- phase: 05-image-url-server plan: 01 type: execute --- Create local image serving infrastructure for URL-based provider inputs. Purpose: Enable providers like Replicate and fal.ai to receive images as URLs instead of large base64 payloads, improving reliability for larger images and meeting provider API requirements. Output: In-memory image store, serving endpoint, and utility function for URL generation. ~/.claude/get-shit-done/workflows/execute-phase.md ~/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md # Prior phase context: @.planning/phases/03-generate-node-refactor/03-02-SUMMARY.md # Relevant source files: @src/app/api/generate/route.ts @src/lib/providers/cache.ts **Tech stack available:** Next.js API routes, in-memory caching pattern from providers/cache.ts **Established patterns:** TTL-based caching, API route structure **Constraining decisions:** - Phase 03-02: Server-side provider execution, not client-side - Phase 02-03: 10-minute cache TTL pattern established **Provider requirements (from discovery):** - Replicate: Accepts data URIs but recommends URLs for files >256KB. Parameter name varies by model (`image`, `input_image`, etc.) - fal.ai: Accepts both URLs and data URIs via `image_url` parameter Task 1: Create in-memory image store with explicit cleanup src/lib/images/store.ts Create an in-memory store for temporary image hosting with request-scoped lifecycle: - Store structure: Map - `storeImage(base64DataUrl: string): string` - stores image, returns unique ID (use crypto.randomUUID()) - `getImage(id: string): { data: Buffer, mimeType: string } | null` - retrieves image by ID - `deleteImage(id: string): boolean` - removes image, returns true if existed - `deleteImages(ids: string[]): void` - bulk delete for cleanup No TTL - callers are responsible for cleanup after use. This prevents memory accumulation since images are deleted immediately after provider fetches them. Parse base64 data URL format: `data:{mimeType};base64,{data}` to extract mimeType and Buffer. Export store functions. TypeScript compiles without errors: `npx tsc --noEmit` Image store module exists with storeImage, getImage, deleteImage, deleteImages exports Task 2: Create image serving API endpoint src/app/api/images/[id]/route.ts Create Next.js API route to serve stored images: - GET handler that extracts `id` from params - Call `getImage(id)` from store - If not found: return 404 with JSON error - If found: return image with correct Content-Type header and binary data - Set Cache-Control: no-store (images are temporary) Route structure follows Next.js App Router dynamic route pattern. Import getImage from @/lib/images/store. Build succeeds: `npm run build` (route compiles correctly) GET /api/images/[id] returns stored images or 404 Task 3: Create uploadImageForUrl utility src/lib/images/index.ts Create utility function that stores an image and returns its URL plus ID for cleanup: - `uploadImageForUrl(base64DataUrl: string, baseUrl: string): { url: string, id: string }` - Calls storeImage() to store the image - Returns full URL `${baseUrl}/api/images/${id}` AND the id for later cleanup - Export from index.ts along with re-exports from store.ts The baseUrl parameter allows the caller to provide the server's base URL. Returning the ID enables callers to delete the image after use. Also create helper to detect if an image should use URL (size threshold): - `shouldUseImageUrl(base64DataUrl: string): boolean` - Returns true if base64 data exceeds 256KB (Replicate's recommendation threshold) - This allows callers to decide whether to use URL or pass base64 directly TypeScript compiles: `npx tsc --noEmit` uploadImageForUrl (returns url+id) and shouldUseImageUrl functions exported from @/lib/images Before declaring plan complete: - [ ] `npm run build` succeeds without errors - [ ] `npx tsc --noEmit` passes - [ ] Files exist: src/lib/images/store.ts, src/lib/images/index.ts, src/app/api/images/[id]/route.ts - All tasks completed - All verification checks pass - No TypeScript errors - Image store, serving endpoint, and utility functions ready for integration After completion, create `.planning/phases/05-image-url-server/05-01-SUMMARY.md`