Commit Graph

9 Commits

Author SHA1 Message Date
Oleg Proskurin 504b1f8395 fix: api & docs 2025-11-28 00:07:06 +07:00
Oleg Proskurin 0ca1a4576e fix: api 2025-11-26 23:32:13 +07:00
Oleg Proskurin 6803a23aa3 fix: basic 2025-11-26 00:11:48 +07:00
Oleg Proskurin 8623442157 fix: aliases 2025-11-25 22:47:54 +07:00
Oleg Proskurin 88cb1f2c61 fix: upload 2025-11-24 00:14:46 +07:00
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 8d1da7364a fix: references 2025-11-17 00:39:18 +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 2c67dad9c2 feat: implement Phase 2 core generation flow with services and endpoints
Implement the complete image generation lifecycle with ImageService, GenerationService,
and v1 API endpoints. This enables end-to-end generation with alias support and flow management.

**Core Services:**
- **ImageService**: Full CRUD for images table
  - Create/read/update/delete operations
  - Soft delete support with deletedAt
  - Project and flow alias assignment
  - Storage key and file hash tracking
  - Pagination and filtering

- **GenerationService**: Complete generation lifecycle orchestration
  - Create generation records with pending status
  - Resolve reference images via AliasService
  - Call ImageGenService for AI generation
  - Create image records in database
  - Link images to generations
  - Update generation status (processing → success/failed)
  - Support for flow association and alias assignment
  - Retry failed generations
  - Soft/hard delete operations

**v1 API Routes:**
- `POST /api/v1/generations` - Create with references & aliases
- `GET /api/v1/generations` - List with filters & pagination
- `GET /api/v1/generations/:id` - Get with full relations
- `POST /api/v1/generations/:id/retry` - Retry failed generation
- `DELETE /api/v1/generations/:id` - Delete generation & output

**Route Features:**
- Authentication via validateApiKey middleware
- Project key requirement
- Rate limiting per API key
- Request validation with pagination
- Error handling with proper status codes
- Response transformation with type converters

**Type Updates:**
- Add explicit undefined to optional properties for exactOptionalPropertyTypes
- CreateGenerationParams interface for service layer
- GenerationFilters with proper optionals

**Infrastructure:**
- Mount v1Router at /api/v1 in app.ts
- Keep legacy routes for backward compatibility
- Versioned API structure for future iterations

**Technical Notes:**
- Reference image download temporarily skipped (TODO: storage key parsing)
- File hash computation temporarily disabled (TODO: helper method)
- File size set to 0 (TODO: get from storage)
- All Phase 2 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:14:49 +07:00