Commit Graph

150 Commits

Author SHA1 Message Date
Oleg Proskurin fba243cfbd feat: add test 2025-11-23 23:01:46 +07:00
Oleg Proskurin 7da1973072 chore: update manual test 2025-11-23 21:44:39 +07:00
Oleg Proskurin 191a745133 fix: remove url field 2025-11-23 21:28:31 +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 3cd7eb316d feat: new tests 2025-11-18 19:20:18 +07:00
Oleg Proskurin 85e68bcb31 doc: update documentation 2025-11-18 00:04:10 +07:00
Oleg Proskurin a1c47a37f0 docs: update admin documentation with IP rate limiting and scope error codes
Update admin.md to reflect Phase 3 Part 3 implementation changes:

**Rate Limiting Section:**
- Split into two subsections: API Key Rate Limiting and IP-Based Rate Limiting
- API Key Rate Limiting: Expanded affected endpoints list to include scope management
- IP-Based Rate Limiting: New section documenting 10/hour limit for live URLs
  - Separate from API key limits
  - Only cache MISS counts toward limit
  - Supports X-Forwarded-For header
  - In-memory store with automatic cleanup

**Error Codes Section:**
- Reorganized into categorized tables for better clarity
- Added HTTP 409 (Conflict) status code
- Added Authentication Error Codes table
- Added Rate Limiting Error Codes table with both API key and IP limits
- Added Live Scope Error Codes table:
  - SCOPE_INVALID_FORMAT (400)
  - SCOPE_ALREADY_EXISTS (409)
  - SCOPE_NOT_FOUND (404)
  - IMAGE_NOT_IN_SCOPE (400)

**Documentation Improvements:**
- All error responses include standard format
- Rate limit errors include Retry-After header
- Scope endpoints require project key authentication
- Comprehensive notes for each section

All documentation now accurately reflects current API v1 implementation.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 23:45:17 +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 fa65264410 feat: phase 3 part 3 - scope management and IP rate limiting
Implement comprehensive live scope management API and IP-based rate limiting
for live URL generation endpoints (Sections 8.5 and 8.6).

**Scope Management CRUD Endpoints:**
- POST /api/v1/live/scopes - Create scope manually with slug validation
- GET /api/v1/live/scopes - List scopes with pagination and stats
- GET /api/v1/live/scopes/:slug - Get single scope by slug with stats
- PUT /api/v1/live/scopes/:slug - Update scope settings
- POST /api/v1/live/scopes/:slug/regenerate - Regenerate scope images
- DELETE /api/v1/live/scopes/:slug - Delete scope with cascading image deletion

**Scope Management Features:**
- Slug format validation (alphanumeric, hyphens, underscores)
- Duplicate slug prevention with 409 Conflict response
- Scope statistics (currentGenerations, lastGeneratedAt)
- Settings management (allowNewGenerations, newGenerationsLimit)
- Regeneration support (single image or all images in scope)
- Hard delete with image cleanup following alias protection rules
- All endpoints require Project Key authentication

**IP-Based Rate Limiting:**
- In-memory rate limit store with automatic cleanup
- Limits: 10 new generations per hour per IP address
- Only cache MISS (new generation) counts toward limit
- Cache HIT does NOT count toward limit
- X-Forwarded-For header support for proxy/load balancer setups
- Rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
- Retry-After header on 429 Too Many Requests response
- Automatic cleanup of expired entries every 5 minutes

**IP Rate Limiter Middleware:**
- ipRateLimiterMiddleware attaches to live URL endpoint
- getClientIp() extracts IP from X-Forwarded-For or req.ip
- checkIpRateLimit() validates and increments counter
- getRemainingRequests() returns available request count
- getResetTime() returns seconds until reset
- Middleware attaches checkIpRateLimit function to request
- Rate limit check executed AFTER cache check (only for cache MISS)

**Type System Updates:**
- Added LiveScopeResponse interface with all scope fields
- Added LiveScopeWithImagesResponse with images array
- Added response type aliases for all CRUD operations
- Added toLiveScopeResponse() converter function
- Added CreateLiveScopeRequest, UpdateLiveScopeRequest interfaces
- Added ListLiveScopesQuery with pagination parameters
- Added RegenerateScopeRequest with optional imageId

**Route Integration:**
- Mounted scopes router at /api/v1/live/scopes
- Applied ipRateLimiterMiddleware to live URL endpoint
- Rate limit increments only on cache MISS (new generation)
- Cache HIT bypasses rate limit check entirely

**Technical Notes:**
- All scope endpoints return toLiveScopeResponse() format
- Pagination using buildPaginationMeta helper
- Bracket notation for meta field access (TypeScript strict mode)
- Proper number parsing with fallback defaults
- All Phase 3 Part 3 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-17 23:15:29 +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 1ad5b483ef feat: phase 3 part 1 - live scopes database schema and service
Implement foundation for live URL system with database schema, relations,
and comprehensive service layer for live scope management.

**Database Schema (Section 8.4):**
- **liveScopes table** with fields:
  - id (UUID primary key)
  - projectId (foreign key to projects, cascade delete)
  - slug (text, unique within project)
  - allowNewGenerations (boolean, default: true)
  - newGenerationsLimit (integer, default: 30)
  - meta (JSONB for flexible metadata)
  - createdAt, updatedAt timestamps

- **Constraints & Indexes:**
  - Unique constraint on (projectId, slug) combination
  - Index for project lookups
  - Index for project+slug lookups

- **Relations:**
  - projects → liveScopes (one-to-many)
  - liveScopes → project (many-to-one)

**Type Definitions:**
- Added LiveScope, NewLiveScope types from database schema
- Added LiveScopeWithStats interface with computed fields:
  - currentGenerations: number (count of images in scope)
  - lastGeneratedAt: Date | null (latest generation timestamp)
  - images?: Image[] (optional images array)
- Added LiveScopeFilters interface for query filtering

**LiveScopeService:**
- **Core CRUD operations:**
  - create() - Create new scope
  - getById() - Get scope by UUID
  - getBySlug() - Get scope by slug within project
  - getByIdOrThrow() / getBySlugOrThrow() - With error handling
  - update() - Update scope settings
  - delete() - Hard delete scope (images preserved)

- **Statistics & Computed Fields:**
  - getByIdWithStats() - Scope with generation count and last generated date
  - getBySlugWithStats() - Same but lookup by slug
  - list() - Paginated list with stats for each scope

- **Business Logic:**
  - canGenerateNew() - Check if scope allows new generations
  - createOrGet() - Lazy creation with project defaults
  - Uses images.meta field for scope tracking (scope, isLiveUrl)

**Technical Notes:**
- Images track scope via meta.scope field (no schema changes to images table)
- Scope statistics computed from images where meta.scope = slug and meta.isLiveUrl = true
- Project settings (allowNewLiveScopes, newLiveScopesGenerationLimit) already added in Phase 2
- 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:50:20 +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 ed3931a2bd feat: update refactor requirements 2025-11-17 00:46:44 +07:00
Oleg Proskurin 8d1da7364a fix: references 2025-11-17 00:39:18 +07:00
Oleg Proskurin 2656b208c5 feat: testing references 2025-11-17 00:23:51 +07:00
Oleg Proskurin 3e3f15cd9c fix: live endpoint 2025-11-16 22:46:39 +07:00
Oleg Proskurin bbc007bccd feat: add images references 2025-11-16 18:57:23 +07:00
Oleg Proskurin a38c2dd954 doc: update rest examples 2025-11-16 18:17:18 +07:00
Oleg Proskurin 213a378532 doc: update the documentation 2025-11-16 17:44:24 +07:00
Oleg Proskurin d6ca79152c fix: service and tests 2025-11-10 00:57:06 +07:00
Oleg Proskurin 4e7eb7b5b5 fix: tests 2025-11-10 00:09:40 +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 e55c02d158 feat: update testing 2025-11-09 23:05:52 +07:00
Oleg Proskurin ca112886e5 feat: implement Phase 5 live generation with prompt caching
Implement cached generation endpoint that streams image bytes directly with
intelligent caching based on prompt hashing for optimal performance.

**Core Service:**
- **PromptCacheService**: Prompt-based cache management
  - SHA-256 hashing of prompts for cache lookup
  - Cache hit/miss tracking with statistics
  - Support for cache entry creation and retrieval
  - Hit count and last accessed timestamp tracking
  - Cache statistics per project

**v1 API Routes:**
- `GET /api/v1/live/generate` - Generate with caching, stream image bytes

**Endpoint Features:**
- Prompt-based caching with SHA-256 hashing
- Cache HIT: Streams existing image with X-Cache-Status: HIT header
- Cache MISS: Generates new image, caches it, streams with X-Cache-Status: MISS
- Direct image byte streaming (not JSON response)
- Cache-Control headers for browser caching (1 year max-age)
- Hit count tracking for cache analytics
- Integration with promptUrlCache database table

**Caching Logic:**
- Compute SHA-256 hash of prompt for cache key
- Check cache by promptHash and projectId
- On HIT: Fetch image from database, download from storage, stream bytes
- On MISS: Generate new image, create cache entry, stream bytes
- Record cache hits with incremented hit count

**Response Headers:**
- Content-Type: image/jpeg (or appropriate MIME type)
- Content-Length: Actual byte length
- Cache-Control: public, max-age=31536000 (1 year)
- X-Cache-Status: HIT | MISS
- X-Cache-Hit-Count: Number of cache hits (on HIT)
- X-Generation-Id: UUID (on MISS)
- X-Image-Id: UUID (always)

**Technical Notes:**
- Uses ImageService to fetch cached images by ID
- Uses StorageFactory to download image buffers from MinIO
- Parses storage keys to extract org/project/category/filename
- Validates storage key format before download
- All Phase 5 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 23:00:10 +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
Oleg Proskurin 071736c076 feat: add test scripts 2025-11-09 22:27:23 +07:00
Oleg Proskurin 85395084b7 feat: implement Phase 3 flow management with service and endpoints
Implement complete flow management system with CRUD operations, computed counts,
and alias management capabilities for organizing generation chains.

**Core Service:**
- **FlowService**: Complete flow lifecycle management
  - Create flows with initial empty aliases
  - CRUD operations (create, read, update, delete)
  - Computed counts for generations and images per flow
  - Alias management (add, update, remove)
  - Get flow's generations and images with pagination
  - No soft delete (flows use hard delete)

**v1 API Routes:**
- `POST /api/v1/flows` - Create new flow
- `GET /api/v1/flows` - List flows with pagination and counts
- `GET /api/v1/flows/:id` - Get single flow with computed counts
- `GET /api/v1/flows/:id/generations` - List flow's generations
- `GET /api/v1/flows/:id/images` - List flow's images
- `PUT /api/v1/flows/:id/aliases` - Update flow aliases (add/modify)
- `DELETE /api/v1/flows/:id/aliases/:alias` - Remove specific alias
- `DELETE /api/v1/flows/:id` - Delete flow (hard delete)

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

**Type Updates:**
- Added ListFlowGenerationsResponse and ListFlowImagesResponse
- Updated GetFlowResponse to return FlowResponse (not FlowWithDetailsResponse)
- FlowService methods return FlowWithCounts where appropriate

**Technical Notes:**
- Flows don't have deletedAt column (no soft delete support)
- All count queries filter active generations/images only
- Alias updates are merged with existing aliases
- Empty flows return generationCount: 0, imageCount: 0
- All Phase 3 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:24:40 +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
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 df84e400f5 chore: update documentation 2025-11-09 21:24:14 +07:00
Oleg Proskurin 1236dd78e2 Merge branch 'feature/db-for-generation' 2025-11-09 17:50:19 +07:00
Oleg Proskurin 047c924193 fix: update schemes 2025-10-26 23:14:05 +07:00
Oleg Proskurin dbf82d2801 feat: update DB schemas 2025-10-26 23:00:10 +07:00
Oleg Proskurin e88617b430 feat: add documentation 2025-10-26 22:26:02 +07:00
Oleg Proskurin a7dc96d1a5 fix: update config 2025-10-26 19:28:31 +07:00
Oleg Proskurin a397de80e9 fix: upload page 2025-10-26 19:13:48 +07:00
Oleg Proskurin 349abc2071 fix: scroll position 2025-10-26 18:38:44 +07:00
Oleg Proskurin b4e5a05ae6 feat: improve 2025-10-26 18:03:17 +07:00
Oleg Proskurin d6a9cd6990 feat: add page-context 2025-10-26 17:37:23 +07:00
Oleg Proskurin 2f8d239da0 feat: switch to sections 2025-10-26 16:33:18 +07:00
Oleg Proskurin ab85b5e1fa feat: add sections components 2025-10-25 22:01:26 +07:00
Oleg Proskurin f46a8d66d3 Merge branch 'feature/apikey-api' 2025-10-25 20:04:54 +07:00
Oleg Proskurin d7c230fae8 feat: add sub nav to admin section 2025-10-25 20:04:43 +07:00
Oleg Proskurin b9a8ca8368 refactor: switch landing from DB to api requests 2025-10-25 18:58:01 +07:00
Oleg Proskurin d1806bfd7e feat: enhance api key api 2025-10-25 18:57:19 +07:00
Oleg Proskurin f1335fb4d3 Merge branch 'feature/global-apikey-widget' 2025-10-25 18:20:12 +07:00