feat: upload wizard refactor + vision AI tags + artwork versioning
Upload wizard:
- Refactored UploadWizard into modular steps (Step1FileUpload, Step2Details, Step3Publish)
- Extracted reusable hooks: useUploadMachine, useFileValidation, useVisionTags
- Extracted reusable components: CategorySelector, ContentTypeSelector
- Added TagPicker component (studio-style list picker with AI badge + new-tag insertion)
- Fixed TagInput auto-open bug (hasFocusedRef guard)
- Replaced TagInput with TagPicker in UploadSidebar
Vision AI tag suggestions:
- Add UploadVisionSuggestController: sync POST /api/uploads/{id}/vision-suggest
- Calls vision.klevze.net/analyze/all on upload completion (before step 2 opens)
- Two-phase useVisionTags: immediate gateway call + background DB polling
- Trigger fires on uploadReady (not step change) so tags arrive before user sees step 2
- Added vision.gateway config block with VISION_GATEWAY_URL env
Artwork versioning system:
- ArtworkVersion / ArtworkVersionEvent models
- ArtworkVersioningService: createNewVersion, restoreVersion, rate limiting, ranking decay
- Migrations: artwork_versions, artwork_version_events, versioning columns on artworks
- Studio API routes: GET versions, POST restore/{version_id}
- Feature tests: ArtworkVersioningTest (13 cases)
This commit is contained in:
@@ -3,6 +3,15 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'files_url' => env('FILES_CDN_URL', 'https://files.skinbase.org'),
|
||||
'files_url' => env('FILES_CDN_URL', 'https://files.skinbase.org'),
|
||||
'avatar_url' => env('AVATAR_CDN_URL', 'https://files.skinbase.org'),
|
||||
|
||||
/**
|
||||
* Optional CDN purge webhook URL.
|
||||
* When set, the artwork versioning system will POST { paths: [...] }
|
||||
* after every file replacement to bust stale thumbnails.
|
||||
*
|
||||
* Example: https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache
|
||||
*/
|
||||
'purge_url' => env('CDN_PURGE_URL', null),
|
||||
];
|
||||
|
||||
@@ -32,6 +32,18 @@ return [
|
||||
// Which derivative variant to send to vision services.
|
||||
'image_variant' => env('VISION_IMAGE_VARIANT', 'md'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Vision Gateway (aggregates CLIP + BLIP + YOLO via /analyze/all)
|
||||
|--------------------------------------------------------------------------
|
||||
| Falls back to CLIP base_url when VISION_GATEWAY_URL is not set.
|
||||
*/
|
||||
'gateway' => [
|
||||
'base_url' => env('VISION_GATEWAY_URL', env('CLIP_BASE_URL', '')),
|
||||
'timeout_seconds' => (int) env('VISION_GATEWAY_TIMEOUT', 10),
|
||||
'connect_timeout_seconds'=> (int) env('VISION_GATEWAY_CONNECT_TIMEOUT', 3),
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| LM Studio – local multimodal inference (tag generation)
|
||||
|
||||
Reference in New Issue
Block a user