Files
ai-stylegallery/PRP.md

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/images to 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 IntersectionObserver for 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.

3. Resources/Entities (Models)

The application's core data structures are represented by Eloquent models:

  • App\Models\User: Represents a user account.
    • id (PK)
    • name
    • email
    • password
    • role_id (FK to roles table)
    • 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 to images table, for styled images)
    • style_id (FK to styles table, 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 to ai_models table)
    • 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:

  • users

    • id: bigint unsigned auto_increment primary key
    • name: varchar(255)
    • email: varchar(255) unique
    • password: varchar(255)
    • role_id: bigint unsigned null (FK to roles.id)
    • two_factor_secret: text null
    • two_factor_recovery_codes: text null
    • two_factor_confirmed_at: timestamp null
    • settings: json null
    • created_at: timestamp null
    • updated_at: timestamp null
  • images

    • id: bigint unsigned auto_increment primary key
    • path: varchar(255)
    • uuid: char(36) unique
    • original_image_id: bigint unsigned null (FK to images.id)
    • style_id: bigint unsigned null (FK to styles.id)
    • is_temp: tinyint(1) default 0
    • is_public: tinyint(1) default 1
    • comfyui_prompt_id: varchar(255) null
    • created_at: timestamp null
    • updated_at: timestamp null
  • styles

    • id: bigint unsigned auto_increment primary key
    • title: varchar(255)
    • prompt: longtext
    • description: longtext
    • preview_image: varchar(255)
    • parameters: json null
    • ai_model_id: bigint unsigned (FK to ai_models.id)
    • enabled: tinyint(1) default 1
    • created_at: timestamp null
    • updated_at: timestamp null
  • ai_models

    • id: bigint unsigned auto_increment primary key
    • name: varchar(255)
    • model_id: varchar(255)
    • model_type: varchar(255) null
    • enabled: tinyint(1) default 1
    • parameters: json null
    • created_at: timestamp null
    • updated_at: timestamp null
  • api_providers

    • id: bigint unsigned auto_increment primary key
    • name: varchar(255)
    • api_url: varchar(255)
    • username: varchar(255) null
    • password: varchar(255) null
    • token: varchar(255) null
    • plugin: varchar(255)
    • enabled: tinyint(1) default 1
    • created_at: timestamp null
    • updated_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 to api_providers.id)

  • settings

    • id: bigint unsigned auto_increment primary key
    • key: varchar(255) unique
    • value: longtext
    • created_at: timestamp null
    • updated_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/image endpoint.
    • Prompt Queuing: Sends the constructed workflow JSON to the ComfyUI server's /prompt endpoint.
    • Result Fetching: Polls the ComfyUI server's /history/{prompt_id} endpoint to check the status and retrieve the base64 encoded styled image.
  • 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 by ImageController@index.
    • GET /api/styles: Retrieves a list of available styles. Handled by StyleController@index.
    • POST /api/images/style-change: Initiates an AI style change request. Handled by ImageController@styleChangeRequest.
    • GET /api/comfyui-url: Retrieves the ComfyUI API URL. Handled by ImageController@getComfyUiUrl.
    • GET /api/images/fetch-styled/{prompt_id}: Fetches the result of a styled image request. Handled by ImageController@fetchStyledImage.
  • Authenticated Routes (requires auth:sanctum middleware):
    • GET /api/user: Retrieves authenticated user details.
    • POST /api/admin/navigation-state: Stores admin navigation state. Handled by NavigationStateController@store.
    • POST /api/images/keep: Marks a temporary styled image as permanent. Handled by ImageController@keepImage.
    • DELETE /api/images/{image}: Deletes an image. Handled by ImageController@deleteImage.
    • GET /api/images/status: Retrieves the status of an image (placeholder for future use). Handled by ImageController@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 /admin panel is controlled by Filament's built-in authentication and authorization system, typically based on user roles.
  • Image Visibility:
    • is_public flag on Image model: Controls whether an image is visible to unauthenticated users.
    • is_temp flag on Image model: Identifies temporary styled images. Unauthenticated users can see their own temporary images.
  • Resource Status:
    • enabled flag on AiModel, ApiProvider, and Style models: Controls whether these resources are active and usable within the application.

8. Detailed Description of Key Logic/Flows

8.1. Image Styling Process

  1. User Action (Frontend): A user selects an image in the gallery and chooses a style from the StyleSelector component.
  2. Frontend Request: The Home.vue component sends an axios.post request to /api/images/style-change, including the image_id and style_id.
  3. Backend (ImageController@styleChangeRequest):
    • Retrieves the Image and Style models based on the provided IDs.
    • Retrieves the associated AiModel and ApiProvider from the Style model.
    • Loads the appropriate AI plugin (e.g., ComfyUi, RunwareAi) using PluginLoader::getPlugin().
    • Calls the processImageStyleChange() method on the loaded plugin, passing the Image and Style models.
  4. AI Plugin (ComfyUi.php or RunwareAi.php):
    • Image Upload: The plugin first uploads the original image to the external AI service.
    • Parameter Merging:
      • It retrieves parameters from both the AiModel and the Style models.
      • 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.
    • 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__ (from Style->prompt), __FILENAME__ (uploaded image filename), and __MODEL_ID__ (from AiModel->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.
    • 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_id from ComfyUI, base64 image data from RunwareAI).
  5. Backend (ImageController@styleChangeRequest - continued):
    • Receives the initial response from the plugin (e.g., prompt_id).
    • Updates the Image record with the comfyui_prompt_id and style_id for tracking.
    • Returns a JSON response to the frontend with the prompt_id and image_uuid.
  6. Frontend (Home.vue - Polling for Result):
    • Upon receiving the prompt_id, the frontend starts polling /api/images/fetch-styled/{prompt_id}.
  7. Backend (ImageController@fetchStyledImage):
    • Retrieves the Image record using the comfyui_prompt_id.
    • Loads the relevant AI plugin.
    • Calls a method on the plugin (e.g., waitForResult for 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 Image record in the database for the styled image, linking it to the original image and style, and setting is_temp to true.
    • Returns a JSON response with the styled image's details.
  8. 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.

8.2. Image Synchronization

  • The ImageController@index method performs a synchronization between the public/storage/uploads directory and the images table 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 parameters fields in Style and AiModel are 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_recursive function 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 public disk is configured in config/filesystems.php to point directly to public_path('storage').
  • Images uploaded via Filament (e.g., style previews) are stored in public/storage/style_previews.
  • The public/storage directory is a symbolic link to storage/app/public (though the configuration was adjusted to point directly to public/storage for the public disk).

This detailed overview should provide a solid foundation for understanding and rebuilding the AI StyleGallery application.