22 KiB
Project Reconstruction Plan (PRP) for AI StyleGallery
This document outlines the architecture, functionality, and implementation details of the "AI StyleGallery" web application. It is intended to serve as a comprehensive guide for another AI agent or LLM to understand and potentially reconstruct a similar system.
1. Application Overview
Primary Goal: AI StyleGallery is a web application designed to allow users to transform their uploaded images by applying various AI-generated artistic styles. Users can manage their image gallery, apply styles via external AI services, and save or discard the results.
Core Functionality:
- Image Upload: Users can upload their own images to the gallery.
- Style Application: Users can select an image and choose from a predefined set of AI styles to apply.
- AI Processing Integration: The application interacts with external AI web services (e.g., ComfyUI, RunwareAI) to perform image transformations.
- Gallery Management: Users can view their original and styled images, and decide to keep (make permanent) or discard (delete) styled images.
- Admin Panel: An administrative interface for managing AI models, API providers, styles, users, and roles.
2. Core Technologies & Stack
- Languages: PHP 8.3, JavaScript
- Frameworks & Runtimes: Laravel 12.21.0, Vue.js 3.5.18, Inertia.js 1.3.0, Livewire 3.6.4, Vite 5.4.19
- Databases: SQLite. Redis is used for caching.
- Key PHP Libraries/Dependencies:
- Filament 3.3.34 (for the admin panel)
- Guzzle 7.9.3 (for HTTP requests)
- Laravel Sanctum 4.2.0 (for API authentication)
- Laravel Breeze 2.3.8 (authentication scaffolding)
- Laravel Pint 1.24.0 (code formatter)
- Laravel Prompts 0.3.6 (CLI prompts)
- Laravel Sail 1.44.0 (Docker development environment)
- Laravel Serializable Closure 2.0.4
- Laravel Tinker 2.10.1
- nesbot/carbon 3.10.2 (date/time library)
- predis/predis 3.1.0 (Redis client)
- phpunit/php-code-coverage 12.3.2
- phpunit/php-file-iterator 6.0.0
- phpunit/php-invoker 6.0.0
- phpunit/php-text-template 5.0.0
- phpunit/php-timer 8.0.0
- phpunit/phpunit 12.3.0
- ramsey/uuid 4.9.0 (UUID generation)
- spatie/laravel-package-tools 1.92.7
- tightenco/ziggy 2.5.3 (Laravel routes in JS)
- symfony/clock 7.3.0
- symfony/console 7.3.2
- symfony/css-selector 7.3.0
- symfony/deprecation-contracts 3.6.0
- symfony/error-handler 7.3.2
- symfony/event-dispatcher 7.3.0
- symfony/event-dispatcher-contracts 3.6.0
- symfony/finder 7.3.2
- symfony/html-sanitizer 7.3.2
- symfony/http-foundation 7.3.2
- symfony/http-kernel 7.3.2
- symfony/mailer 7.3.2
- symfony/mime 7.3.2
- symfony/polyfill-ctype 1.32.0
- symfony/polyfill-intl-grapheme 1.32.0
- symfony/polyfill-intl-idn 1.32.0
- symfony/polyfill-intl-normalizer 1.32.0
- symfony/polyfill-mbstring 1.32.0
- symfony/polyfill-php80 1.32.0
- symfony/polyfill-php83 1.32.0
- symfony/polyfill-uuid 1.32.0
- symfony/process 7.3.0
- symfony/routing 7.3.2
- symfony/service-contracts 3.6.0
- symfony/string 7.3.2
- symfony/translation 7.3.2
- symfony/translation-contracts 3.6.0
- symfony/uid 7.3.1
- symfony/var-dumper 7.3.2
- symfony/yaml 7.3.2
- Key JavaScript Libraries/Dependencies:
- axios 1.11.0 (for frontend HTTP requests)
- tailwindcss 3.4.17 (for styling)
- @inertiajs/vue3 1.3.0
- @vitejs/plugin-vue 5.2.4
- @tailwindcss/forms 0.5.10
- autoprefixer 10.4.21
- postcss 8.5.6
- laravel-echo 2.1.7 (WebSocket client)
- pusher-js 8.4.0 (Pusher client for WebSockets)
- @fortawesome/fontawesome-svg-core 7.0.0
- @fortawesome/free-solid-svg-icons 7.0.0
- @fortawesome/vue-fontawesome 3.1.1
- vanilla-lazyload 19.1.3 (lazy loading images)
- Package Manager(s): Composer for PHP, npm for JavaScript.
2. UI Structure (Frontend / Backend)
2.1. Frontend (Vue.js 3 with Inertia.js)
The frontend is a Single Page Application (SPA) built with Vue.js and Inertia.js, providing a dynamic user experience.
- Gallery View (
resources/js/Pages/Home.vue):- Displays a grid of images (both original and styled).
- Images are fetched from
/api/images. - Includes pagination for large galleries.
- Periodically polls
/api/imagesto refresh the gallery and show newly styled images.
- Image Context Menu (
resources/js/Components/ImageContextMenu.vue):- Appears when a user taps on an image in the gallery.
- Provides options: "Drucken" (Print), "Stil ändern" (Change Style), "Schließen" (Close).
- Dynamically adjusts its position based on the tap location.
- Layout: Image preview (60% width) and options list (40% width).
- Style Selector (
resources/js/Components/StyleSelector.vue):- Displayed when "Stil ändern" is selected from the context menu.
- Fetches and lists available AI styles from
/api/styles. - Allows users to select a style.
- Lazy loads style preview images using
IntersectionObserverfor performance. - Includes a "back" arrow to return to the main context menu.
- Styled Image Display (Implicit):
- Styled images appear in the main gallery after processing.
- User Authentication/Profile:
- Login/Logout functionality (handled by Laravel Breeze/Fortify and Inertia.js).
- User profile management (via Laravel's built-in features and Filament admin panel).
2.2. Backend (Laravel 12 with Filament Admin Panel)
The backend is a monolithic Laravel application, with Filament providing a powerful administrative interface.
- Filament Admin Panel:
- Accessible via
/admin. - Provides CRUD (Create, Read, Update, Delete) operations for the following resources:
- AI Models (
app/Filament/Resources/AiModelResource.php): Manage AI models, their IDs, types, associated API providers, and specific parameters (JSON). - API Providers (
app/Filament/Resources/ApiProviderResource.php): Configure connections to external AI services (API URL, authentication tokens/credentials, plugin type). - Styles (
app/Filament/Resources/StyleResource.php): Define AI styles, including their title, prompt, description, preview image, parameters (JSON), and associated AI model. - Images (via direct database interaction and synchronization): While there's an
ImageResource, image management is largely automated through synchronization. - Users (
app/Filament/Resources/UserResource.php): Manage user accounts and assign roles. - Roles (
app/Filament/Resources/RoleResource.php): Define user roles and permissions. - Settings (
app/Filament/Resources/SettingResource.php): Manage application-wide settings.
- AI Models (
- Accessible via
3. Resources/Entities (Models)
The application's core data structures are represented by Eloquent models:
App\Models\User: Represents a user account.id(PK)nameemailpasswordrole_id(FK torolestable)two_factor_secret,two_factor_recovery_codes,two_factor_confirmed_at(for 2FA)settings(JSON)
App\Models\Image: Stores metadata for both original and styled images.id(PK)path(string, file path relative to storage disk)uuid(string, unique identifier for tracking)original_image_id(FK toimagestable, for styled images)style_id(FK tostylestable, for styled images)is_temp(boolean, true for temporary styled images)is_public(boolean, true for publicly visible images)comfyui_prompt_id(string, for tracking ComfyUI jobs)created_at,updated_at
App\Models\Style: Defines an AI style.id(PK)title(string)prompt(text, the base prompt for the AI model)description(text)preview_image(string, path to style preview image)parameters(JSON, additional parameters for the AI plugin, cast to array)ai_model_id(FK toai_modelstable)enabled(boolean)created_at,updated_at
App\Models\AiModel: Represents a specific AI model (e.g., Stable Diffusion v1.5).id(PK)name(string)model_id(string, identifier used by the AI service)model_type(string, e.g., "Stable Diffusion")enabled(boolean)parameters(JSON, additional parameters for the AI plugin, cast to array)created_at,updated_at
App\Models\ApiProvider: Configures connection details for an external AI service.id(PK)name(string, e.g., "ComfyUI API")api_url(string, base URL of the AI service)username(string, nullable)password(string, nullable)token(string, nullable)plugin(string, identifies the plugin to use, e.g., "comfyui", "runwareai")enabled(boolean)created_at,updated_at
App\Models\Role: Defines user roles for access control.id(PK)name(string, e.g., "admin", "user")created_at,updated_at
App\Models\Setting: Stores application-wide key-value settings.id(PK)key(string)value(text)created_at,updated_at
4. Database Structure (Schema)
Key tables and their relevant columns:
-
usersid:bigint unsigned auto_increment primary keyname:varchar(255)email:varchar(255) uniquepassword:varchar(255)role_id:bigint unsigned null(FK toroles.id)two_factor_secret:text nulltwo_factor_recovery_codes:text nulltwo_factor_confirmed_at:timestamp nullsettings:json nullcreated_at:timestamp nullupdated_at:timestamp null
-
imagesid:bigint unsigned auto_increment primary keypath:varchar(255)uuid:char(36) uniqueoriginal_image_id:bigint unsigned null(FK toimages.id)style_id:bigint unsigned null(FK tostyles.id)is_temp:tinyint(1) default 0is_public:tinyint(1) default 1comfyui_prompt_id:varchar(255) nullcreated_at:timestamp nullupdated_at:timestamp null
-
stylesid:bigint unsigned auto_increment primary keytitle:varchar(255)prompt:longtextdescription:longtextpreview_image:varchar(255)parameters:json nullai_model_id:bigint unsigned(FK toai_models.id)enabled:tinyint(1) default 1created_at:timestamp nullupdated_at:timestamp null
-
ai_modelsid:bigint unsigned auto_increment primary keyname:varchar(255)model_id:varchar(255)model_type:varchar(255) nullenabled:tinyint(1) default 1parameters:json nullcreated_at:timestamp nullupdated_at:timestamp null
-
api_providersid:bigint unsigned auto_increment primary keyname:varchar(255)api_url:varchar(255)username:varchar(255) nullpassword:varchar(255) nulltoken:varchar(255) nullplugin:varchar(255)enabled:tinyint(1) default 1created_at:timestamp nullupdated_at:timestamp null
-
roles-
id:bigint unsigned auto_increment primary key -
name:varchar(255) unique -
created_at:timestamp null -
updated_at:timestamp null -
api_provider_id:bigint unsigned(FK toapi_providers.id)
-
-
settingsid:bigint unsigned auto_increment primary keykey:varchar(255) uniquevalue:longtextcreated_at:timestamp nullupdated_at:timestamp null
5. User Interactions
5.1. Frontend User Interactions
- Image Upload: Users can upload images via a dedicated interface (not explicitly detailed in provided context, but implied by gallery functionality).
- Image Selection: Tapping on an image in the gallery opens a context menu.
- Context Menu Actions:
- "Drucken" (Print): Placeholder for printing functionality.
- "Stil ändern" (Change Style): Navigates to the style selection interface.
- "Schließen" (Close): Closes the context menu.
- Style Selection:
- Users browse a list of available styles.
- Selecting a style initiates the AI image transformation process.
- "Back" arrow: Returns to the image context menu.
- Gallery Refresh: The gallery automatically updates to show newly processed images (polling every 5 seconds).
- Authentication: Users can log in and out.
5.2. Backend (Admin Panel) User Interactions
- Resource Management: Full CRUD operations for AI Models, API Providers, Styles, Users, and Roles.
- Toggle Status: Enable/disable AI Models, API Providers, and Styles.
- Duplication: Duplicate existing AI Models and Styles to quickly create new ones.
- Settings Management: Update application-wide settings.
6. External System Interactions
6.1. AI Web Services
The application integrates with external AI services for image processing. The specific plugin used is determined by the plugin field in the ApiProvider model.
- ComfyUI (via
App\Api\Plugins\ComfyUi.php):- Image Upload: Sends image data (base64 encoded) to the ComfyUI server's
/upload/imageendpoint. - Prompt Queuing: Sends the constructed workflow JSON to the ComfyUI server's
/promptendpoint. - Result Fetching: Polls the ComfyUI server's
/history/{prompt_id}endpoint to check the status and retrieve the base64 encoded styled image.
- Image Upload: Sends image data (base64 encoded) to the ComfyUI server's
- RunwareAI (via
App\Api\Plugins\RunwareAi.php):- Image Upload: Sends image data (base64 encoded) to the RunwareAI API.
- Style Change Request: Sends a request with prompt, seed image UUID, model ID, and merged parameters to the RunwareAI API for image inference.
6.2. Authentication
- Laravel Sanctum: Used for API authentication, securing routes that require user login (e.g., keeping/deleting images, admin panel access).
7. Call Structure and Access Rights
7.1. API Routes (routes/api.php)
- Publicly Accessible Routes:
GET /api/images: Retrieves a list of images (public and temporary for unauthenticated users, all for authenticated users). Handled byImageController@index.GET /api/styles: Retrieves a list of available styles. Handled byStyleController@index.POST /api/images/style-change: Initiates an AI style change request. Handled byImageController@styleChangeRequest.GET /api/comfyui-url: Retrieves the ComfyUI API URL. Handled byImageController@getComfyUiUrl.GET /api/images/fetch-styled/{prompt_id}: Fetches the result of a styled image request. Handled byImageController@fetchStyledImage.
- Authenticated Routes (requires
auth:sanctummiddleware):GET /api/user: Retrieves authenticated user details.POST /api/admin/navigation-state: Stores admin navigation state. Handled byNavigationStateController@store.POST /api/images/keep: Marks a temporary styled image as permanent. Handled byImageController@keepImage.DELETE /api/images/{image}: Deletes an image. Handled byImageController@deleteImage.GET /api/images/status: Retrieves the status of an image (placeholder for future use). Handled byImageController@getStatus.
7.2. Web Routes (routes/web.php)
- Standard Laravel web routes for serving the Inertia.js frontend. The main application entry point is typically handled by a route that returns an Inertia response (e.g.,
Route::get('/', ...)).
7.3. Access Rights
- API Authentication: Laravel Sanctum is used to protect API routes. Users must be authenticated to access certain functionalities.
- Filament Admin Panel: Access to the
/adminpanel is controlled by Filament's built-in authentication and authorization system, typically based on user roles. - Image Visibility:
is_publicflag onImagemodel: Controls whether an image is visible to unauthenticated users.is_tempflag onImagemodel: Identifies temporary styled images. Unauthenticated users can see their own temporary images.
- Resource Status:
enabledflag onAiModel,ApiProvider, andStylemodels: Controls whether these resources are active and usable within the application.
8. Detailed Description of Key Logic/Flows
8.1. Image Styling Process
- User Action (Frontend): A user selects an image in the gallery and chooses a style from the
StyleSelectorcomponent. - Frontend Request: The
Home.vuecomponent sends anaxios.postrequest to/api/images/style-change, including theimage_idandstyle_id. - Backend (ImageController@styleChangeRequest):
- Retrieves the
ImageandStylemodels based on the provided IDs. - Retrieves the associated
AiModelandApiProviderfrom theStylemodel. - Loads the appropriate AI plugin (e.g.,
ComfyUi,RunwareAi) usingPluginLoader::getPlugin(). - Calls the
processImageStyleChange()method on the loaded plugin, passing theImageandStylemodels.
- Retrieves the
- AI Plugin (
ComfyUi.phporRunwareAi.php):- Image Upload: The plugin first uploads the original image to the external AI service.
- Parameter Merging:
- It retrieves
parametersfrom both theAiModeland theStylemodels. - These parameters (which are JSON objects) are deeply merged using
array_replace_recursive(). This ensures that specific parameters from the style can override or extend parameters defined at the model level.
- It retrieves
- Prompt Construction: The plugin constructs the final prompt/workflow for the AI service.
- For ComfyUI, it takes the merged parameters (workflow JSON) and performs string replacements for placeholders like
__PROMPT__(fromStyle->prompt),__FILENAME__(uploaded image filename), and__MODEL_ID__(fromAiModel->model_id). - Crucially, values for placeholders are JSON-encoded and then stripped of outer quotes to ensure safe injection into the JSON workflow, preventing syntax errors.
- For ComfyUI, it takes the merged parameters (workflow JSON) and performs string replacements for placeholders like
- API Call: The plugin sends the prepared request (e.g., prompt to ComfyUI, inference request to RunwareAI) to the external AI service.
- Response Handling: The plugin waits for a response from the AI service (e.g.,
prompt_idfrom ComfyUI, base64 image data from RunwareAI).
- Backend (ImageController@styleChangeRequest - continued):
- Receives the initial response from the plugin (e.g.,
prompt_id). - Updates the
Imagerecord with thecomfyui_prompt_idandstyle_idfor tracking. - Returns a JSON response to the frontend with the
prompt_idandimage_uuid.
- Receives the initial response from the plugin (e.g.,
- Frontend (Home.vue - Polling for Result):
- Upon receiving the
prompt_id, the frontend starts polling/api/images/fetch-styled/{prompt_id}.
- Upon receiving the
- Backend (ImageController@fetchStyledImage):
- Retrieves the
Imagerecord using thecomfyui_prompt_id. - Loads the relevant AI plugin.
- Calls a method on the plugin (e.g.,
waitForResultfor ComfyUI) to retrieve the final base64 encoded styled image data. - Decodes the base64 image, saves it to
public/storage/uploads(e.g.,styled_UUID.png). - Creates a new
Imagerecord in the database for the styled image, linking it to the original image and style, and settingis_temptotrue. - Returns a JSON response with the styled image's details.
- Retrieves the
- Frontend (Home.vue - Gallery Refresh):
- Upon successful fetching of the styled image, the frontend calls
fetchImages()to refresh the gallery, which now includes the newly created styled image.
- Upon successful fetching of the styled image, the frontend calls
8.2. Image Synchronization
- The
ImageController@indexmethod performs a synchronization between thepublic/storage/uploadsdirectory and theimagestable in the database. - It adds new image files found on disk to the database.
- It removes database entries for images that no longer exist on disk.
- This ensures the gallery always reflects the actual files in storage.
8.3. Parameter Merging Logic
- The
parametersfields inStyleandAiModelare stored as JSON in the database and automatically cast to PHP arrays by Eloquent. - In the AI plugins (
ComfyUi.php,RunwareAi.php), when constructing the AI service request:$modelParams = $style->aiModel->parameters ?? [];$styleParams = $style->parameters ?? [];$mergedParams = array_replace_recursive($modelParams, $styleParams);- This
array_replace_recursivefunction is crucial for deep merging, allowing style-specific parameters to override or extend model-level parameters.
- Placeholders (
__PROMPT__,__FILENAME__,__MODEL_ID__) within the merged JSON are replaced with actual values. These values are first JSON-encoded and then trimmed of their outer quotes to ensure they are safely inserted into the JSON structure without breaking it.
8.4. File Storage Configuration
- The application uses Laravel's filesystem configuration.
- The
publicdisk is configured inconfig/filesystems.phpto point directly topublic_path('storage'). - Images uploaded via Filament (e.g., style previews) are stored in
public/storage/style_previews. - The
public/storagedirectory is a symbolic link tostorage/app/public(though the configuration was adjusted to point directly topublic/storagefor thepublicdisk).
This detailed overview should provide a solid foundation for understanding and rebuilding the AI StyleGallery application.