Commit Graph

11 Commits

Author SHA1 Message Date
Oleg Proskurin 8623442157 fix: aliases 2025-11-25 22:47:54 +07:00
Oleg Proskurin 5e52d4ff9c fix: show image dimentions 2025-11-23 21:03:55 +07:00
Oleg Proskurin e3ddf1294f fix: prompts storage 2025-11-23 20:47:48 +07:00
Oleg Proskurin 6235736f4f fix: flow creation 2025-11-23 14:34:54 +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 9b9c47e2bf feat: phase 2 part 1 - schema changes, regeneration, and lazy flows
**Database Schema Changes (Section 2.1):**
- Rename generations.enhancedPrompt → generations.prompt (prompt used for generation)
- Rename generations.originalPrompt semantics → user's original (only if enhanced)
- Reverse semantics: prompt = what was used, originalPrompt = preserved user input
- Add projects.allowNewLiveScopes (BOOLEAN, default: true)
- Add projects.newLiveScopesGenerationLimit (INTEGER, default: 30)

**Prompt Semantics Update:**
- If autoEnhance=false: prompt=user input, originalPrompt=null
- If autoEnhance=true: prompt=enhanced, originalPrompt=user input
- Updated GenerationService.create() to implement new logic
- Updated retry() and update() methods to use new prompt field

**Regeneration Refactoring (Section 3):**
- Add POST /api/v1/generations/:id/regenerate endpoint
- Remove status checks (allow regeneration for any status)
- Remove retry count logic (no longer tracked)
- Remove parameter overrides (uses exact same params as original)
- Updates existing image (same imageId, storageKey, storageUrl)
- Keep /retry endpoint for backward compatibility (delegates to regenerate)
- GenerationService.regenerate() method created
- Physical file in MinIO overwritten by ImageGenService

**Flow Regeneration (Section 3.6):**
- Add POST /api/v1/flows/:id/regenerate endpoint
- Regenerates most recent generation in flow
- Returns FLOW_HAS_NO_GENERATIONS error if flow is empty
- Uses parameters from last generation

**Lazy Flow Creation (Section 4.3):**
- Remove POST /api/v1/flows endpoint (commented out with explanation)
- Flows now created automatically when:
  - Generation/upload specifies a flowId
  - Generation/upload provides flowAlias (eager creation)
- Eager creation logic already implemented in Phase 1

**Technical Notes:**
- All Phase 2 Part 1 changes maintain data integrity
- No migration needed (dev mode per user confirmation)
- Regeneration preserves image metadata (alias, createdAt, etc.)
- Processing time tracked for regeneration

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 01:43:49 +07:00
Oleg Proskurin 647f66db7a feat: phase 1 - parameter renames, auto-detection, and flowId logic
**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>
2025-11-17 01:20:49 +07:00
Oleg Proskurin bbc007bccd feat: add images references 2025-11-16 18:57:23 +07:00
Oleg Proskurin d6ca79152c fix: service and tests 2025-11-10 00:57:06 +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