Commit Graph

7 Commits

Author SHA1 Message Date
Oleg Proskurin 855ac3c111 feat: log errors transparent 2026-01-05 22:48:16 +07:00
Oleg Proskurin 3d18fcfeb5 feat(api): change default aspect ratio from 1:1 to 16:9
Update default aspect ratio for image generation to 16:9 widescreen
format, matching common display resolutions and user expectations.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 16:32:18 +07:00
Oleg Proskurin 1f768d4761 feat: phase 3 part 2 - CDN endpoints with live URL caching system
Implement public CDN endpoints for serving images and live URL generation
with intelligent caching based on prompt hashing.

**CDN Routes (Section 8):**
- **GET /cdn/:orgSlug/:projectSlug/img/:filenameOrAlias**
  - Public endpoint (no authentication)
  - Serve images by filename or project-scoped alias
  - Resolves org and project from slugs
  - Supports @alias syntax or filename lookup
  - Returns image bytes with 1-year cache headers
  - Headers: Content-Type, Content-Length, Cache-Control, X-Image-Id

- **GET /cdn/:orgSlug/:projectSlug/live/:scope**
  - Public endpoint (no authentication)
  - Live URL generation with caching
  - Query params: prompt, aspectRatio, autoEnhance, template
  - Cache key: SHA-256(projectId + scope + prompt + params)
  - Cache HIT: Returns cached image immediately
  - Cache MISS: Generates new image, caches, returns
  - Scope management: auto-create or check limits
  - Image meta tracking: scope, isLiveUrl, cacheKey
  - Headers: X-Cache-Status (HIT/MISS), X-Scope, X-Image-Id, X-Generation-Id

**Cache Key Helper:**
- computeLiveUrlCacheKey() - SHA-256 hash for live URL caching
- computePromptHash() - SHA-256 hash for prompt caching
- Normalized parameters for consistent cache keys

**Live URL Flow (Section 8.3):**
1. Validate prompt and scope format (alphanumeric + hyphens + underscores)
2. Resolve org, project from slugs
3. Compute cache key from params
4. Check cache via images.meta.cacheKey
5. If HIT: serve cached image
6. If MISS: check scope limits, generate, cache, serve
7. Lazy scope creation with project defaults
8. Enforce newGenerationsLimit per scope

**Service Exports:**
- Added LiveScopeService to core services index
- Available for dependency injection

**App Routing:**
- Mounted CDN router at /cdn (public, before auth routes)
- CDN endpoints are completely public (no API key required)

**Technical Notes:**
- Images tagged with meta: { scope, isLiveUrl: true, cacheKey }
- Scope statistics computed from images with matching meta
- Cache controlled via Cache-Control: public, max-age=31536000
- System generations use apiKeyId: null
- All 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 22:57:44 +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 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 c185ea3ff4 feat: add Phase 1 foundation for API v2.0
Implement foundational components for Banatie API v2.0 with dual alias system,
flows support, and comprehensive type safety.

**Type Definitions:**
- Add models.ts with database types (Generation, Image, Flow, etc.)
- Add requests.ts with all v2 API request types
- Add responses.ts with standardized response types and converters
- Support for pagination, filters, and complex relations

**Constants:**
- Define technical aliases (@last, @first, @upload)
- Define reserved aliases and validation patterns
- Add rate limits for master/project keys (2-bucket system)
- Add pagination, image, generation, and flow limits
- Comprehensive error messages and codes

**Validators:**
- aliasValidator: Format validation, reserved alias checking
- paginationValidator: Bounds checking with normalization
- queryValidator: UUID, aspect ratio, focal point, date range validation

**Helpers:**
- paginationBuilder: Standardized pagination response construction
- hashHelper: SHA-256 utilities for caching and file deduplication
- queryHelper: Reusable WHERE clause builders with soft delete support

**Core Services:**
- AliasService: 3-tier alias resolution (technical → flow → project)
  - Technical alias computation (@last, @first, @upload)
  - Flow-scoped alias lookup from JSONB
  - Project-scoped alias lookup with uniqueness
  - Conflict detection and validation
  - Batch resolution support

**Dependencies:**
- Add drizzle-orm to api-service for direct ORM usage

All Phase 1 code is 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 21:53:50 +07:00
Oleg Proskurin 6944e6b750 feat: detect network issues 2025-10-10 00:17:29 +07:00