Commit Graph

3 Commits

Author SHA1 Message Date
Oleg Proskurin 7d87202934 feat: phase 2 part 2 - upload enhancements and deletion strategy overhaul
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>
2025-11-17 11:38:51 +07:00
Oleg Proskurin 874cc4fcba fix: add resolve endpoint and correct live path
CRITICAL FIXES:
- Add GET /api/v1/images/resolve/:alias endpoint with 3-tier alias resolution
  - Supports optional flowId query parameter
  - Returns image, scope (technical/flow/project), and flowId
  - Placed before GET /:id to avoid route conflict
- Change live endpoint from /api/v1/live/generate to /api/v1/live
  - Corrects path to match specification

PARAMETER NAMING:
- Rename outputAlias to assignAlias in requests and service
- Rename flowAliases to assignFlowAlias in requests and service
- Update generations route to use new parameter names

FLOW TIMESTAMP UPDATES:
- Add flow.updatedAt trigger in ImageService.create()
  - Updates flow timestamp when image is uploaded to a flow
- Flow.updatedAt already updated in GenerationService.create()

AUDIT TRAIL VERIFICATION:
- Confirmed apiKeyId is properly saved in generations table
- Confirmed apiKeyId is properly saved in images table (both upload and generation)

TYPE FIXES:
- Add explicit | undefined to AliasResolutionResponse.flowId

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 23:40:31 +07:00
Oleg Proskurin 4785d23179 feat: implement Phase 4 image management with upload and CRUD endpoints
Implement complete image management system with file upload, listing, retrieval,
updates, alias assignment, and soft deletion.

**v1 API Routes:**
- `POST /api/v1/images/upload` - Upload single image file with database record
- `GET /api/v1/images` - List images with filters and pagination
- `GET /api/v1/images/:id` - Get single image by ID
- `PUT /api/v1/images/:id` - Update image metadata (alias, focal point, meta)
- `PUT /api/v1/images/:id/alias` - Assign project-scoped alias to image
- `DELETE /api/v1/images/:id` - Soft delete image

**Upload Endpoint Features:**
- Uses uploadSingleImage middleware for file handling
- Creates database record with image metadata
- Stores file in MinIO storage (uploads category)
- Supports optional alias and flowId parameters
- Returns ImageResponse with all metadata

**Route Features:**
- Authentication via validateApiKey middleware
- Project key requirement
- Rate limiting on upload endpoint
- Request validation with pagination
- Error handling with proper status codes
- Response transformation with toImageResponse converter
- Project ownership verification for all operations

**ImageService Integration:**
- Uses existing ImageService methods
- Supports filtering by flowId, source, alias
- Soft delete with deletedAt timestamp
- Alias validation and conflict detection

**Type Updates:**
- Updated ImageFilters with explicit | undefined for optional properties
- All response types already defined in responses.ts

**Technical Notes:**
- Upload creates both storage record and database entry atomically
- Focal point stored as JSON with x/y coordinates
- Meta field for flexible metadata storage
- File hash set to null (TODO: implement hashing)
- All Phase 4 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>
2025-11-09 22:41:59 +07:00