Commit Graph

9 Commits

Author SHA1 Message Date
Oleg Proskurin b0e6304e07 fix: urls and storage structure 2025-12-26 01:10:14 +07:00
Oleg Proskurin 7e04fcbbb0 fix: storage structure 2025-12-25 23:54:18 +07:00
Oleg Proskurin 504b1f8395 fix: api & docs 2025-11-28 00:07:06 +07:00
Oleg Proskurin e3ddf1294f fix: prompts storage 2025-11-23 20:47:48 +07:00
Oleg Proskurin a92b1bf482 docs: phase 3 part 4 - comprehensive JSDoc documentation for all v1 API endpoints
Add complete JSDoc documentation to all API v1 endpoints with detailed descriptions,
parameters, returns, error codes, and usage examples (Section 12).

**Generation Endpoints (generations.ts):**
- POST / - Create generation with references, aliases, and enhancement
- GET / - List with flow/status filtering and pagination
- GET /:id - Get single generation with full relations
- PUT /:id - Update with auto-regeneration on prompt/aspectRatio change
- POST /:id/regenerate - Regenerate with exact same parameters
- POST /:id/retry - Legacy endpoint (deprecated, delegates to regenerate)
- DELETE /:id - Delete with alias protection rules

**Flow Endpoints (flows.ts):**
- GET / - List flows with computed counts and pagination
- GET /:id - Get single flow with generationCount and imageCount
- GET /:id/generations - List flow's generations with pagination
- GET /:id/images - List flow's images with pagination
- PUT /:id/aliases - Update flow-scoped aliases (JSONB merge)
- DELETE /:id/aliases/:alias - Remove specific flow alias
- POST /:id/regenerate - Regenerate most recent generation in flow
- DELETE /:id - Hard delete flow (generations/images remain)

**Image Endpoints (images.ts):**
- POST /upload - Upload with flowId logic (undefined=auto, null=none, string=specific)
- GET / - List with flow/source/alias filtering and pagination
- GET /resolve/:alias - 3-tier resolution (technical → flow → project)
- GET /:id - Get single image with complete details
- PUT /:id - Update focal point and metadata
- PUT /:id/alias - Assign project-scoped alias (Section 6.1)
- DELETE /:id - Hard delete with MinIO cleanup and cascades

**CDN Endpoints (cdn.ts):**
- GET /:orgSlug/:projectSlug/img/:filenameOrAlias - Public image serving
  - Supports filename and @alias access
  - Long-term browser caching (1 year)
  - No authentication required
- GET /:orgSlug/:projectSlug/live/:scope - Live URL generation
  - Automatic prompt-based caching
  - IP rate limiting (10/hour, cache hits excluded)
  - Lazy scope creation
  - Scope generation limits
  - Cache key from prompt + params
  - X-Cache-Status: HIT|MISS headers

**Scope Management Endpoints (scopes.ts):**
- POST / - Create scope manually with settings
- GET / - List with currentGenerations stats and pagination
- GET /:slug - Get single scope by slug with stats
- PUT /:slug - Update settings (allowNewGenerations, limits)
- POST /:slug/regenerate - Regenerate specific image or all in scope
- DELETE /:slug - Delete scope with cascading image deletion

**JSDoc Standards Applied:**
- Complete function descriptions with use cases
- @route method and path
- @authentication requirements and key types
- @rateLimit specifications where applicable
- @param detailed parameter descriptions with types and optionality
- @returns status codes with response descriptions
- @throws error codes with explanations
- @example realistic usage examples with request/response samples
- @deprecated tags for legacy endpoints

**Documentation Features:**
- Comprehensive parameter descriptions
- Default values clearly indicated
- Type information for all parameters
- Error code documentation
- Multiple examples per complex endpoint
- Response header documentation
- Cache behavior explanations
- Flow logic documentation
- Alias resolution precedence details
- Rate limiting specifics

All JSDoc follows standardized format for consistent API documentation
across the entire v1 API surface. Zero new TypeScript errors introduced.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 23:32:13 +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 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