LycheeOrg/Lychee
41.3
Weak · 19 September 2026
248.4k
lines of production code
PHP
with TypeScript
1
measurement over time
What this system is
This system is a self-hosted photo gallery application that manages the ingestion, organization, and presentation of large media libraries. It provides robust backend capabilities for importing files, processing images into various size variants, and performing AI-driven tasks like face recognition and NSFW detection. The platform supports complex album hierarchies, granular user permissions, and direct photo sales via a built-in webshop, all exposed through a modern API.
How it got here
2018–2022 — v8 architecture and dependency overhaul
79 changes.
The project underwent a comprehensive architectural rewrite, migrating the backend to Laravel 12 and the frontend to Vue 3 while replacing legacy model and controller structures with a modern, domain-driven design. This period established the foundation for Lychee v8 by introducing granular access controls, AI-powered face recognition, and a robust pipeline-based system for imports, diagnostics, and updates.
2023–2025 — API standardization and webshop integration
79 changes.
This period focused on standardizing the API layer by migrating resources to Spatie Laravel Data with TypeScript generation, while introducing a comprehensive pipe-based architecture for photo uploads and imports. Concurrently, the project implemented a new webshop feature for selling photos and albums, alongside significant backend enhancements including AI-driven NSFW moderation, face detection, and granular permission management.
2026 — API v3 performance and AI integration
22 changes.
This period focused on overhauling the V3 API to use a high-performance Struct-of-Arrays response format, significantly reducing memory usage and improving query speeds for albums and photos. Concurrently, the project expanded its feature set by introducing comprehensive AI-driven face detection and NSFW moderation capabilities, alongside robust bulk management tools for albums, photos, and administrative tasks.
Features
API request validation for NSFW detection features
This change introduces three new API request validation classes within the \app/Http/Requests/Nsfw\ directory to support the NSFW detection system. \BulkNsfwScanRequest\ handles admin-only bulk scanning requests with optional album and force parameters. \GetPhotoNsfwDetectionsRequest\ validates requests to retrieve NSFW detection data for a specific photo, enforcing photo access policies. \NsfwDetectionResultsRequest\ processes incoming results from an external classification service, authenticating via an API key header and validating complex detection data structures including labels, confidence scores, and bounding boxes.
app/Http/Requests/Nsfw · high confidence
API request validation for the new Renamer module
This change introduces the HTTP request validation layer for the Renamer feature, adding seven new request classes in app/Http/Requests/Renamer. These classes enforce authorization and input validation for creating, updating, and deleting rename rules, as well as for previewing, testing, and executing renames on photos and albums. The validation logic ensures that only users with upload or administrative privileges can manage rules, restricts rule modification to rule owners or admins, and validates specific attributes like rule patterns, replacement strings, and target scopes (photos vs. albums, current vs. descendants).
app/Http/Requests/Renamer · high confidence
Add timeline request validation and authorization
Added request classes for the new Timeline feature. GetTimelineRequest handles authorization for the main timeline page, checking the 'timeline\_page\_enabled' config and 'timeline\_photos\_public' setting for unauthenticated access. IdOrDatedTimelineRequest validates inputs for timeline photo queries, supporting date-based filtering with configurable granularity (via 'timeline\_photos\_granularity') and photo ID lookups, while also enforcing the same public/private access controls.
app/Http/Requests/Timeline · high confidence
Added Helpers facade for static access to utility methods
A new \Helpers\ facade has been introduced in the application, providing static access to the methods defined in \App\\Assets\\Helpers\. This allows developers to call utility functions such as \getTmpDir\, \getExtension\, \hasPermissions\, and \censor\ statically via \Helpers::method()\, simplifying the interface for common asset and system helper operations.
app/Facades · high confidence
Added LDAP authentication support and unified session/token guard
Users can now authenticate against an LDAP directory via the new LdapService, which handles user search, binding, and group membership queries. Additionally, the SessionOrTokenGuard ensures consistent authentication by allowing either session-based or token-based login on the same routes, while preventing conflicts if both are present simultaneously.
app/Services/Auth · high confidence
Added Laminas Text Table decorator interface
The application now includes the \DecoratorInterface\ from the Laminas Text component within its own contract namespace. This interface defines methods for retrieving specific ASCII characters used to render table borders (corners, lines, dividers), enabling the app to implement custom table decoration logic compatible with Laminas Text Table structures.
app/Contracts/Laminas · high confidence
Added PHPStan stubs for Safe GD image functions
Added stub files for the Safe library's GD image functions (such as imagecreatefromstring, imagejpeg, and imagepng) and the ImageException class. These stubs provide type information for static analysis, allowing PHPStan to correctly understand the return types and exceptions of these specific image manipulation functions while waiting for upstream support in the Safe library.
phpstan · high confidence
Added Vite development entry point with configuration diagnostics
A new \vite/index.html\ file has been introduced to serve as the entry point for the Vite local development environment. This HTML page includes a diagnostic overlay that displays when the application is misconfigured, guiding users to verify their \APP\_URL\, \TRUSTED\_PROXIES\, and reverse proxy header settings. It also embeds a comprehensive SVG sprite containing dozens of UI icons (such as navigation arrows, media controls, and status indicators) required by the frontend assets.
vite · high confidence
Added color extraction from pictures
Users can now extract dominant colors from images. This change introduces a new color extraction capability within the application, implemented via two distinct extractors (Farzai and League) that adhere to a common interface, allowing the system to derive a palette of colors from uploaded picture files.
app/Image/ColourExtractor · high confidence
Added data transfer objects for NSFW detection results
Introduced new DTOs in the \app/DTO/Nsfw\ namespace to structure NSFW moderation data. \NsfwBboxData\ defines bounding box coordinates, \NsfwDetectionItemData\ represents individual detection items with labels and confidence scores, and \NsfwDetectionResultsData\ aggregates these into categorized lists (block, review, sensitive) along with status and error information, enabling the application to process and expose NSFW detection outcomes.
app/DTO/Nsfw · high confidence
Added shop-specific exception classes for purchase and basket operations
The application now includes dedicated exception classes for the shop module, allowing for more precise error handling during e-commerce interactions. These new exceptions cover scenarios such as failed basket deletions, invalid purchase options, non-pending order modifications, photos that are not purchasable, and missing payment provider configurations. This change improves the clarity of error responses for users and developers when specific shop-related operations fail.
app/Exceptions/Shop · high confidence
Admin bulk editing for albums
Administrators can now apply metadata and visibility changes to multiple albums at once. This new action processes updates in three groups: base album properties (such as description, copyright, and photo layout), album-specific settings (like license and sorting), and visibility controls (including public status, link requirements, and access grants), ensuring that only specified fields are modified while leaving others unchanged.
app/Actions/Admin · high confidence
Admin-only webhook configuration and payload construction
Administrators can now manage webhook configurations (create, read, update, delete, and list) via new API request validation classes that enforce feature flags and admin permissions. Additionally, a new service builds webhook payloads, allowing admins to control which photo metadata (ID, album ID, title) and specific size variants are included in outgoing webhook events.
app/Http/Requests/Webhook, app/Services/Webhook · high confidence
Arabic localization added for v8 interface and admin features
Added comprehensive Arabic translations for the v8 front-end and administrative pages, covering the admin dashboard, bulk album editing, contact form, design system, diagnostics, duplicate finder, fix-tree maintenance, flow, gallery views, server import, jobs, landing page configuration, and various dialogs. This enables full Arabic language support for the updated user interface and management tools.
lang · high confidence
Automated photo-added notifications and expanded command loading
Users will now receive in-app notifications when new photos are added, driven by a new \lychee:photos\_added\_notification\ Artisan command scheduled to run weekly. Additionally, the application's console command structure has been reorganized to explicitly load commands from new subdirectories (\Laravel\, \Legacy\, \UserManagment\, and \ImageProcessing\), making these specific management and processing tools available via the CLI.
app/Console · high confidence
Backend API for contact form submissions and message management
This change introduces the backend infrastructure for the contact form feature, adding a new ContactController and associated request validation classes. Administrators can now manage contact inquiries via API endpoints that allow listing messages with search and read-status filtering, marking messages as read or unread, and deleting specific messages. Public visitors can submit contact messages through a new store endpoint, which supports optional security question validation and privacy policy consent checks based on configuration.
app/Http/Controllers/Contact, app/Http/Requests/Contact · high confidence
Backend actions for album sharing and permission propagation
This change introduces the backend logic for managing album sharing permissions. The new \Share\ action handles the creation of access permissions for specific albums, users, and user groups, storing grants for full photo access, download, upload, edit, and delete. The new \Propagate\ action provides two modes for managing permissions across nested albums: \update\ applies the current album's permissions to all descendants (creating or updating existing entries), while \overwrite\ clears all existing descendant permissions and replaces them with the current album's settings. Both propagation methods operate within database transactions to ensure data integrity.
app/Actions/Sharing · high confidence
Batch rename capability for albums and photos
Users can now preview and apply bulk renaming rules to albums and photos. New action classes (PreviewAlbums, PreviewPhotos, RenameAlbums, RenamePhotos) allow selecting specific items or scoping to a parent album and its descendants, processing changes in chunks to handle large libraries efficiently. The rename operation updates titles and re-splits them into base and index components using the configured renamer rules.
app/Actions/Renamer · high confidence
Database optimization actions for MySQL, PostgreSQL, and SQLite
Users can now explicitly optimize and analyze database tables through new action classes (OptimizeDb, OptimizeTables) that support MySQL, PostgreSQL, and SQLite. These actions execute driver-specific commands (OPTIMIZE TABLE, VACUUM, ANALYZE) to improve database performance and maintain table statistics.
app/Actions/Db · high confidence
Expanded diagnostics with new integrity, security, and service health checks
The diagnostics system now includes a comprehensive suite of new checks to help administrators verify their installation. These include verifying the existence of an admin user, checking database integrity (such as photos missing originals or size variants with missing file sizes), and validating configuration sanity. Security and access checks have been added to detect misconfigured APP\_URL settings that could break WebAuthn or image display, ensure at least one authentication method is active, and warn about insecure iframe embedding configurations. The diagnostics also now verify the health and configuration of external AI Vision services (face recognition and NSFW detection), local reverse geo-decoding services, and the Keygen API license token. Additionally, it checks for correct file permissions on storage directories, validates PHP environment settings (like upload limits and xdebug), and computes a file integrity hash of the installation.
app/Actions/Diagnostics/Pipes/Checks · high confidence
Improved OpenAPI schema generation for Laravel Data classes
The application now includes a custom schema extension (\DataToResponse\) for the Scramble library that automatically generates accurate OpenAPI documentation for \Spatie\\LaravelData\\Data\ objects. This change ensures that public properties within these data classes are correctly reflected in the API documentation, supporting complex type mappings such as unions, built-in types, and collections, thereby providing users with more precise and reliable API reference materials.
app/Http/Resources/OpenApi · high confidence
Initial public web root and installer assets
The public directory now contains the standard Laravel entry point (index.php) and a complete set of static assets for the application's installer, including Font Awesome 4.7.0 fonts and styles. It also introduces a new SVG logo, placeholder images for empty states, and a robots.txt file that restricts search engine access to sensitive directories like data and uploads while allowing access to public image uploads. Additionally, a storage symlink is established to link public uploads to the application's storage directory, and empty index.html files are added to prevent directory listing in upload folders.
public · high confidence
Introduce Webshop backend for purchasing photos and albums
This change adds the backend controllers for a new webshop feature, enabling users to browse purchasable items, manage a shopping basket, and complete payments. The new BasketController allows adding individual photos, entire albums, or specific print/pixel-size items to a basket, as well as retrieving or clearing the basket. The CatalogController exposes purchasable options for albums and their sub-albums, while the CatalogueSizesController provides active print and pixel size configurations with pricing. The CheckoutController handles the payment lifecycle, including session creation, processing payments via external providers (with redirect support), and finalizing orders upon return. Finally, the OrderController provides endpoints for listing orders, marking them as paid or delivered, and managing associated cookies.
app/Http/Controllers/Shop · high confidence
Introduce backend webshop services for photo sales and PayPal checkout
This change adds the core backend logic for the Lychee webshop, introducing services to manage shopping baskets, order lifecycles, and purchasable item pricing. The new \BasketService\ and \OrderService\ handle creating pending orders, adding photos or albums with specific size variants and license types, and managing order status transitions. The \PurchasableService\ enables administrators to define pricing for individual photos or entire albums, including hierarchical pricing across sub-albums. Additionally, a \CheckoutService\ and a custom \PaypalGateway\ are introduced to process payments via the PayPal Server SDK, supporting a two-step flow of order creation and payment capture.
app/Actions/Shop · high confidence
Introduce comprehensive DTO layer for album, import, and admin operations
The application now uses a dedicated set of Data Transfer Objects in the \app/DTO\ directory to structure data for bulk album editing, import workflows, and administrative statistics. This includes \BulkAlbumPatchData\ for handling partial updates to album metadata and visibility, \ImportDTO\ and \ImportMode\ to manage file import configurations and job execution, and \AdminStatsOverview\ to aggregate system metrics like photo counts and storage usage. Additional DTOs such as \EffectiveAccessPermission\ and \LdapConfiguration\ standardize how user permissions and LDAP settings are processed, ensuring consistent data handling across the backend.
app/DTO · high confidence
Introduce duplicate finder resource models
Added new data resource classes for the duplicate finder feature: \Duplicate\ exposes photo and album details along with a generated URL for each duplicate item, while \DuplicateCount\ provides aggregate statistics on pure duplicates, title duplicates, and duplicates within albums.
app/Http/Resources/Models/Duplicates · high confidence
Introduce standalone photo upload pipeline
A new standalone photo upload pipeline has been added to handle the end-to-end processing of uploaded photos. This pipeline introduces specific behaviors for users: user-supplied titles and descriptions are now applied at upload time and take precedence over automatic renaming rules; watermarks can be explicitly disabled during the upload process; and AI-powered features, including NSFW moderation and facial recognition, are automatically triggered upon upload based on configuration and user trust levels. Additionally, the pipeline manages the creation of size variants (including RAW support), handles Google Live Photos, and ensures file integrity through checksums.
app/Actions/Photo/Pipes/Standalone · high confidence
Introduce structured request validation for the Webshop basket and catalog
This change adds a new set of HTTP request validation classes for the Webshop backend, specifically within the \app/Http/Requests/Basket\ and \app/Http/Requests/Catalog\ directories. It introduces dedicated request handlers for adding albums, photos, print items, and pixel items to the basket, as well as for deleting basket items and retrieving the current basket state. These classes enforce strict validation rules for purchase parameters (such as size variants, license types, and pixel sizes) and implement authorization logic to ensure users can only modify their own baskets or access albums they are permitted to view. Additionally, it includes request classes for fetching catalog data and available catalogue sizes, establishing a robust input validation layer for the new webshop features.
app/Http/Requests/Basket · high confidence
Introduces managed album-listing cache with centralized key generation and tag-based eviction
The application now includes a new managed caching layer for album, tag, and person listings. A new \CacheKeyProvider\ centralizes the generation of cache keys and tags, ensuring consistent identification for cached data such as album children, flow descriptions, and various listing scopes (tag, person, pinned, and v3 API listings). The \ManagedCacheService\ provides a generic memoization mechanism that supports tag-based eviction, allowing specific cached entries to be invalidated when underlying data changes (e.g., when an album's description is updated or when album membership changes). This service respects both global feature flags and specific configuration settings, falling back to direct computation if caching is disabled or encounters errors, thereby improving performance for album listing queries while maintaining data consistency through precise invalidation.
app/Services/Cache · high confidence
Introduces new image processing and file abstraction contracts
This change adds a suite of new interfaces in the \app/Contracts/Image\ and \app/Contracts/Exceptions\ directories to support upcoming image handling features. Key additions include \ImageHandlerInterface\ for loading, saving, scaling, cropping, and rotating images; \ColourPaletteExtractorInterface\ to extract dominant colors from images; \BinaryBlob\ and \MediaFile\ interfaces to unify stream-based file operations across different storage backends; and \StreamStats\ to track stream statistics. It also defines exception contracts (\LycheeException\, \ExternalLycheeException\, \InternalLycheeException\) and an \HttpExceptionHandler\ interface for structured error handling.
app/Contracts/Image · high confidence
Introduces user-group sharing support
This change adds the backend request-handling layer for user-group sharing. In the \app/Http/Requests/Traits\ directory, it introduces a comprehensive set of traits (such as \HasUserGroupTrait\, \HasUserGroupIdsTrait\, and \HasRoleTrait\) to standardize how user groups, associated user IDs, and roles are validated and accessed within API requests. It also adds specific request classes under \app/Http/Requests/UserGroup\ (including \CreateUserGroupRequest\, \UpdateUserGroupRequest\, \ManageUserGroupRequest\, etc.) that enforce authorization policies and process the validated data for managing these groups.
app/Http/Requests/Traits · high confidence
Introduction of ImportPipe interface for import processing
A new ImportPipe interface has been added to define the contract for photo creation pipes within the import workflow. This interface specifies a handle method that accepts an ImportDTO state and a closure for the next step in the pipeline, enabling a structured, chainable approach to processing imports.
app/Contracts/Import · high confidence
Introduction of live metrics tracking and cleanup
The application now tracks user interactions with photos and albums in real-time. A new \LiveMetrics\ model and associated action classes (\GetMetrics\ and \CleanupMetrics\) have been added to record and retrieve these events, while automatically purging records older than the configured retention period to manage storage.
app/Actions/Metrics · high confidence
New AI Vision face detection and person management API
This change introduces a comprehensive set of new API endpoints for AI-driven face detection, clustering, and person management. Users can now trigger and receive results for face scans (including bulk scans), manage face clusters (assign, dismiss, uncluster), and perform full CRUD operations on Person records (create, update, delete, merge, claim). The controllers also expose endpoints for NSFW detection configuration and results, as well as retrieving face overlays for photos and listing photos associated with specific persons or albums, enforcing appropriate access controls throughout.
app/Http/Controllers/AiVision · high confidence
New AI-powered image moderation and recognition services
This update introduces backend services for automated image analysis. The new NsfwActionService and NsfwDetectionService integrate with an external NSFW classification API to automatically detect sensitive content, applying configurable actions such as blocking, reviewing, or marking albums based on user trust levels. Additionally, the new FaceDetectionService and FacialRecognitionService provide the infrastructure for batch face scanning and matching against stored embeddings via an external AI Vision API. The FileExtensionService has also been updated to recognize and support AVIF, HEIC, and HEIF image formats, as well as a broader set of raw camera file extensions for conversion.
app/Services/Image · high confidence
New API request validation for face recognition and maintenance operations
This change introduces a comprehensive set of new HTTP request validation classes in the \app/Http/Requests/Face\ directory to support the new face recognition feature. These classes define the input schemas, authorization gates, and business logic for various face-related API endpoints, including assigning faces to photos (\AssignFaceRequest\), batch operations on faces (\BatchAssignFacesRequest\, \BatchDismissFacesRequest\, \BatchFaceRequest\), bulk scanning (\BulkScanRequest\, \ScanPhotosRequest\), and managing face clusters (\ClusterAssignRequest\, \ClusterDismissRequest\, \ClusterFacesRequest\, \UnclusterFacesRequest\). It also adds request handlers for receiving results from the external AI vision service (\FaceDetectionResultsRequest\, \ClusterResultsRequest\) and for face maintenance tasks like dismissing faces (\ToggleDismissedRequest\, \DestroyDismissedFacesRequest\) and viewing face data (\GetPhotoFacesRequest\, \FaceMaintenanceIndexRequest\).
app/Http/Requests/Face · high confidence
New API resource classes for album protection, timeline, and photo data
This change introduces a set of new data-transfer objects in the \app/Http/Resources/Models/Utils\ directory to structure API responses. \AlbumProtectionPolicy\ exposes album security attributes (public access, password requirements, upload/download permissions) to the frontend. \PreComputedPhotoData\ and \PreformattedPhotoData\ handle photo metadata, including conditional exposure of EXIF data and GPS coordinates based on user authentication and configuration settings. \TimelineData\ provides formatted date strings for photos and albums to support timeline views, including parsing dates from album titles. \PreFormattedAlbumData\ formats album details like titles, descriptions, and date ranges. Other utility classes include \HeaderFocusData\ for header image positioning, \PersonNameResource\ for person data, and \UserToken\ for authentication tokens. All classes are annotated for TypeScript generation.
app/Http/Resources/Models/Utils · high confidence
New API resources for bulk album editing and server import
Added new API resource classes in the Admin namespace to support the bulk album edit feature and the new server import capability. BulkAlbumResource and PaginatedBulkAlbumResource expose detailed album metadata (including sorting, layout, and visibility settings) and tree structure data (\_lft/\_rgt) to enable efficient client-side bulk operations. ImportFromServerResource and ImportFromServerOptionsResource provide the data structures required for the Web UI to configure and execute directory imports from the server, including options like symlink usage and duplicate handling.
app/Http/Resources/Admin · high confidence
New Album maintenance model for tree repair
A new Album model class has been added to the Admin Maintenance namespace to facilitate the repair of the album tree structure. This dedicated model implements the Nestedset Node interface and trait, allowing the system to manage album hierarchy relationships without interfering with standard application logic.
app/Http/Controllers/Admin/Maintenance/Model · high confidence
New CLI commands for image processing and storage migration
This change introduces a suite of new Artisan commands in the \app/Console/Commands/ImageProcessing\ directory to handle background media tasks. Users can now run \lychee:decode\_GPS\_locations\ to reverse-geocode photos, \lychee:exif\_lens\ to populate missing EXIF metadata, \lychee:extract\_colour\_palette\ to generate color palettes, and \lychee:generate\_thumbs\ to create missing image variants. Additionally, \lychee:s3\_migrate\ and \lychee:track\_s3\_migrate\ allow migrating existing local photos and tracks to an S3 bucket, while \lychee:variant\_filesize\ and \lychee:video\_data\ help correct missing file sizes and video metadata. The \lychee:takedate\ command is also provided to update missing creation dates from EXIF data.
app/Console/Commands/ImageProcessing · high confidence
New Flow API resource layer for album listings and configuration
The application introduces a new set of API resources in the \app/Http/Resources/Flow\ directory to structure data for the public photo flow feature. \FlowResource\ and \FlowItemResource\ now handle the serialization of paginated album lists, including photo collections, cover images, statistics, and markdown-converted descriptions with caching. \InitResource\ exposes frontend configuration flags (such as carousel, header, and NSFW blur settings) derived from system configs and user support status, enabling the client to render the flow view correctly.
app/Http/Resources/Flow · high confidence
New WebAuthn credential management request validators
Added three new form request classes in the WebAuthn namespace to handle credential operations: DeleteCredentialRequest for removing credentials, EditCredentialRequest for updating credential aliases with validation rules, and ListCredentialsRequest for listing credentials. These validators enforce authorization checks using the UserPolicy and Gate, ensuring only authenticated users with edit permissions can manage WebAuthn credentials.
app/Http/Requests/WebAuthn · high confidence
New admin maintenance tools for album stats, face recognition, and system health
A comprehensive suite of new maintenance controllers has been added to the admin panel, providing administrators with direct UI access to various backend repair and optimization tasks. Album management now includes tools to backfill missing size statistics (BackfillAlbumSizes), recompute precomputed fields like date ranges and cover IDs (FulfillPreCompute), and generate missing size variants (GenSizeVariants). Face recognition capabilities are expanded with controllers to bulk-scan photos for new faces (BulkScanFaces), reset stuck or failed scan statuses (ResetFaceScanStatus), trigger AI clustering (RunFaceClustering), and synchronize or purge orphaned embeddings (SyncFaceEmbeddings, PurgeOrphanFaceEmbeddings). System health and integrity are improved with tools to fix broken album trees (FixTree, FullTree), clear stuck jobs (FixJobs), flush caches (FlushCache), and clean up orphaned files (Cleaning). Additional features include a duplicate photo finder (DuplicateFinder), database optimization (Optimize), and webshop order fulfillment management (FulfillOrders, FlushOldOrders).
app/Http/Controllers/Admin/Maintenance · high confidence
New admin panel controllers for bulk management, shop, and system configuration
The admin area now includes dedicated controllers to manage bulk album edits, import from server, job history, landing page customization, NSFW moderation, shop settings (print/pixel sizes and purchasable items), security advisories, and system updates. Administrators can now perform bulk operations on albums, configure the landing page, moderate flagged content, manage shop-related configurations, and view system diagnostics and update status directly from the admin interface.
app/Http/Controllers/Admin · high confidence
New and updated maintenance console commands
The \app/Console/Commands\ area now includes a comprehensive suite of new and refactored Artisan commands for system administration. Administrators can now run \lychee:diagnostics\ to view system, configuration, and error checks (with a \--skip\ option to ignore specific checks), \lychee:fix-permissions\ to correct POSIX file permissions (with a \--dry-run\ mode), and \lychee:fix-tree\ to repair nested set model errors in the album hierarchy. The \lychee:ghostbuster\ command has been updated to support S3 storage disks and offers granular control over removing dead symlinks and zombie photos. Bulk data maintenance is handled by \lychee:recompute-album-sizes\, \lychee:recompute-album-stats\, and the combined \lychee:recompute-buckets\ command, all of which support bulk backfilling and dry-run previews. Additionally, new commands \lychee:scan-faces\ and \lychee:rescan-failed-faces\ manage AI face detection jobs, \lychee:photos\_added\_notification\ handles email notifications for new uploads, and \lychee:webhook-test\ allows testing webhook configurations. The \lychee:sync\ command remains the primary tool for importing files and directories.
app/Console/Commands · high confidence
New backend actions for map bucket and photo queries
Added three new classes in app/Actions/Map to power the map API endpoints: QueryMapBuckets computes aggregated grid-cell counts and centroids for map clusters; QueryMapPhotos fetches individual photo details within a viewport, capped at 500 rows to prevent performance issues; and ResolvesMapPhotoSource provides shared logic for resolving photo queries across different album scopes and applying bounding box filters. These changes implement the backend logic for map data retrieval, supporting both aggregated bucket views and detailed photo listings.
app/Actions/Map · high confidence
New backend services for admin stats, timeline bucketing, security advisories, and secure image links
This change introduces a suite of new service classes in app/Services that power several backend capabilities. AdminStatsService provides a cached overview of system statistics (photos, albums, users, storage, jobs) for the admin panel. AlbumBucketComputer and PhotoBucketComputer centralize the logic for computing timeline bucket IDs based on sorting columns and granularity, supporting the reworked timeline and album sorting. SecurityAdvisoriesService, VersionRangeChecker, and UrlValidation introduce automated security advisory checking against GitHub data and stricter URL import validation (including DNS resolution and private IP blocking) to prevent SSRF. MoneyService adds currency handling for the new Webshop feature. PersonAlbumMatcher refines the query logic for person albums, and TitleSplitter enables natural sorting of titles at the database layer. TemporaryLinkSigner and UrlGenerator implement secure, time-limited image link generation with HMAC-based signing.
app/Services · high confidence
New background jobs for NSFW scanning, face detection, and album sensitivity
This change introduces several new queued jobs in the app/Jobs directory to handle asynchronous processing. DispatchNsfwScanJob and ApplyNsfwAlbumSensitivityJob enable NSFW moderation by scanning photos and marking albums as sensitive. DispatchFaceScanJob and DeleteFaceEmbeddingsJob integrate with an external AI Vision service for face detection and cleanup. Additionally, CheckTreeState provides a cached diagnostic for album tree integrity, while CleanupOrphanedPersonAlbumsJob automatically removes person albums that no longer contain any associated persons.
app/Jobs · high confidence
New configuration files for development and security features
This change introduces a suite of new configuration files that enable and tune several application features. It adds \config/clockwork.php\ and \config/debugbar.php\ to provide detailed debugging and profiling capabilities for developers. Security and operational controls are introduced via \config/honeypot.php\ (to detect bots), \config/features.php\ (to toggle features like S3 storage, LDAP authentication, and webhooks), and \config/markdown.php\ (to enforce stricter, safer Markdown parsing). Additionally, it includes \config/cors.php\ for API cross-origin settings, \config/data.php\ for data object handling, \config/feed.php\ for RSS/Atom feeds, \config/image-optimizer.php\ for media processing, \config/ldap.php\ for directory service connections, \config/log-viewer.php\ for log management, and \config/octane.php\ for high-performance server configuration.
config · high confidence
New console commands for creating and updating users
Added \lychee:create\_user\ and \lychee:update\_user\ artisan commands to manage user accounts via the command line. The create command allows administrators to provision new users with specific permissions (upload, edit settings, administer) and automatically grants admin rights if no other users exist. The update command enables changing a user's password by username.
app/Console/Commands/UserManagment · high confidence
New developer tooling and automation scripts
The scripts directory now includes several new utilities to improve the development workflow. A new Rector rule (VariableCasingRector) automatically converts variable names to camelCase. A translation validation script (check\_translations.php) ensures consistency across language files. Git hooks have been added: a pre-commit hook runs php-cs-fixer and Prettier to enforce code style, and a post-merge hook automatically runs composer install, npm ci, and database migrations (unless disabled via .NO\_AUTO\_COMPOSER\_MIGRATE). Additional scripts include gen\_release.php for generating version bump migrations, generate-js-types.sh for creating Vue auto-import types, install\_files.php for initial setup, and codex-commit-review.sh for suggesting conventional commit messages.
scripts · high confidence
New development and security configuration files added
Added \.dockerignore\ to exclude development artifacts, dependencies, and local storage from Docker builds, \.editorconfig\ to standardize indentation and line endings across editors, \.gitmodules\ to register the \Lychee-front\ frontend repository as a git submodule, \.php-cs-fixer.php\ to enforce PHP code style rules, \.prettierrc.json\ for JavaScript/TypeScript formatting, \.trivyignore\ to suppress known CVEs in the Frankenphp base image, and \AGENTS.md\ to define AI-assisted development workflows and quality gates.
(repo-wide) · high confidence
New email notification for added photos
Users will now receive an email notification when new photos are added to their library. This change introduces the PhotosAdded mail class, which formats and sends a markdown-based email containing the site title and details of the newly added photos.
app/Mail · high confidence
New embed resources for external galleries
Added new data resources (EmbedAlbumInfo, EmbedAlbumResource, EmbedPhotoResource, EmbedStreamResource) to support embedding public album and photo data on external websites. These resources provide minimal, publicly visible information including album details, photo metadata, size variants, and EXIF data, optimized for JavaScript-based embeds.
app/Http/Resources/Embed · high confidence
New event classes for album and photo metrics
Added new event classes in the \app/Events/Metrics\ directory to track specific user interactions with albums and photos. These include \AlbumDownload\, \AlbumShared\, and \AlbumVisit\ for album-level metrics, as well as \PhotoDownload\, \PhotoFavourite\, \PhotoShared\, and \PhotoVisit\ for photo-level metrics. These events extend base classes (\BaseAlbumMetricsEvent\ and \BasePhotoMetricsEvent\) to standardize how actions like downloads, shares, visits, and favorites are recorded and converted into database entries.
app/Events/Metrics · high confidence
New event-driven listeners for cache invalidation, statistics, and webhooks
This change introduces a suite of new event listeners in the app/Listeners directory to handle background tasks and system events. Cache management is improved with dedicated invalidators for album, photo, map, and user listings (ManagedCache\*Invalidator) to ensure data consistency, alongside a new CacheListener for optional event logging. Album statistics and thumbnail recomputation are now triggered automatically via listeners on photo and album mutations. Additionally, the system now supports configurable webhooks via WebhookListener, tracks long-running SQL queries with LogQueryTimeout, processes webshop order fulfillment through OrderCompletedListener, and handles license key rotation on admin login.
app/Listeners · high confidence
New external request handling for security advisories and update checks
The application now includes a dedicated HTTP request layer in app/Metadata/Json to fetch external data, introducing classes for GitHub Security Advisories, change logs, Git commits, tags, and general update checks. These new request handlers (AdvisoriesRequest, ChangeLogsRequest, CommitsRequest, TagsRequest, UpdateRequest) extend a shared base that manages caching, error logging, and specific HTTP headers (such as the GitHub JSON API accept header), enabling the system to retrieve security and version metadata from remote sources.
app/Metadata/Json · high confidence
New image processing infrastructure and watermarking support
This change introduces a new image processing architecture within the app/Image directory, adding several new classes to handle image generation and manipulation. Key additions include the Watermarker class, which enables applying configurable watermarks to images based on user authentication status and specific configuration settings (such as position, opacity, and scaling). The PlaceholderEncoder class handles the creation of low-quality image placeholders by compressing and encoding images to base64 for database storage. Additionally, the SizeVariantDefaultFactory and SizeVariantDimensionHelpers classes manage the creation and dimension logic for various image size variants (thumbnails, small, medium, etc.), while StreamStat and StreamStatFilter provide on-the-fly stream statistics for file integrity checks. These components collectively replace or augment previous image handling logic, enabling more robust image variant generation and watermarking capabilities.
app/Image · high confidence
New input validation for shop management features
Added request validation classes for the Webshop backend, enabling users to manage purchasable items, print sizes, and pixel sizes. These new files enforce authorization checks (ensuring only the owner can modify settings) and validate input data for creating, updating, and deleting purchasable albums and photos, as well as managing print and pixel size configurations.
app/Http/Requests/ShopManagement · high confidence
New maintenance request validation classes
Added a new set of request validation classes in the Maintenance namespace to handle specific backend maintenance operations. These include CleaningRequest for filesystem cleaning, CreateThumbsRequest for generating image thumbnails, FullTreeUpdateRequest for album tree structure updates, MigrateRequest for handling user authentication during system migration, RegisterRequest for license key registration, SearchDuplicateRequest for finding duplicate images, and empty base requests for Maintenance and Update operations. All classes enforce appropriate authorization checks using the SettingsPolicy.
app/Http/Requests/Maintenance · high confidence
New metadata management services for disk usage, extraction, geocoding, and writing
The app/Metadata area now includes four new service classes: DiskUsage calculates storage consumption for the installation and upload folders; Extractor collects normalized EXIF and video metadata using a prioritized reader chain (FFprobe, Exiftool, Imagick, or native PHP fallback) and supports XMP sidecar files; Geodecoder converts GPS coordinates into human-readable location names via Nominatim with optional local endpoint support and rate limiting; and Writer embeds title, description, tags, and ratings back into image files using exiftool. These services provide the backend infrastructure for storage diagnostics, comprehensive media metadata extraction, reverse geocoding, and metadata persistence.
app/Metadata · high confidence
New multi-step web-based installation wizard
The application now includes a dedicated web-based installation interface that guides users through a six-step setup process: Welcome, System Requirements validation, File Permissions check, Environment (.env) configuration, Database Migration and key generation, and final Admin User creation. This replaces previous installation methods with a structured, step-by-step wizard that validates PHP versions, extensions, and directory permissions before allowing the user to configure the environment and create the initial administrator account.
app/Http/Controllers/Install · high confidence
New order management request validators
Added new request validation classes for order operations: GetOrderRequest for retrieving a single order with authorization checks, ListOrderRequest for listing orders with an option to include pending orders, MarkAsDeliveredOrderRequest for marking orders as delivered with item validation, and MarkAsPaidOrderRequest for marking offline orders as paid. These validators enforce proper authorization and data validation for order-related API endpoints.
app/Http/Requests/Order · high confidence
New request validation classes for live and photo metrics
Added MetricsRequest and PhotoMetricsRequest classes to handle input validation and authorization for metrics endpoints. MetricsRequest enforces the CAN\_SEE\_LIVE policy check for live metrics access, while PhotoMetricsRequest validates required photo IDs, visitor ID, and source ID for photo-specific metrics collection without requiring explicit authorization.
app/Http/Requests/Metrics · high confidence
New request validation classes for statistics endpoints
Added four new Laravel request classes (CountsRequest, SpacePerAlbumRequest, SpacePerUserRequest, SpaceSizeVariantRequest) in the app/Http/Requests/Statistics directory to handle input validation and authorization for statistics features. These classes enforce specific rules for count types, album IDs, and user ownership, ensuring that non-admin users can only access statistics relevant to their own accounts while admins retain full access.
app/Http/Requests/Statistics · high confidence
New request validation classes for user management operations
This change introduces four new request validation classes in the UserManagement namespace: AddUserRequest, DeleteUserRequest, ManagmentListUsersRequest, and SetUserSettingsRequest. These classes centralize authorization checks via the UserPolicy and define validation rules for creating, deleting, listing, and updating user accounts. Specifically, AddUserRequest and SetUserSettingsRequest handle user attributes such as username, password, upload permissions, administrative rights, upload trust levels, quotas, and notes, ensuring that only authorized administrators can perform these actions.
app/Http/Requests/UserManagement · high confidence
New statistics actions for upload/taken counts and storage space usage
Added new action classes in app/Actions/Statistics to power the statistics dashboard. Counts.php provides methods to retrieve the number of photos uploaded or taken per day over a configurable time range, as well as the earliest creation and capture dates for a user. Spaces.php calculates storage usage by leveraging a pre-computed album\_size\_statistics table for albums and querying size\_variants directly for unalbummed photos, returning total space per user and a breakdown of space usage by size variant type (e.g., thumb, original, raw).
app/Actions/Statistics · high confidence
New structured search token strategies for albums and photos
The search interface now supports a comprehensive set of structured query tokens for both albums and photos, replacing or supplementing previous search logic. For albums, users can filter by date (\date:\), text fields like title and description (\title:\, \description:\), and album tags (\tag:\), with support for prefix matching (e.g., \tag:vac\*\) and plain-text fallbacks. For photos, the new strategies enable filtering by color (\color:\/\colour:\) using configurable distance metrics, date (\date:\), specific fields (\make:\, etc.), plain text across title, description, location, model, and tags, rating (\rating:\ with sub-modifiers like \avg:\ and \own:\), aspect ratio (\ratio:\ with named buckets like \landscape\/\portrait\/\square\), tags (\tag:\), and file type (\type:\). All strategies use parameterized queries with proper escaping of LIKE wildcards to ensure security and correctness.
app/Actions/Search/Strategies · high confidence
New tree-based directory import and individual file import actions
The import system now includes two new action classes: \Exec\ and \FromUrl\. \Exec\ introduces a pipeline-based approach for importing directories, automatically creating a tree of albums based on the folder structure and handling missing photos/albums via configurable modes. \FromUrl\ provides a dedicated handler for importing photos from a list of URLs, including extension validation and trust-level checks before downloading. These changes replace or supplement previous ad-hoc import logic with a more structured, job-based workflow.
app/Actions/Import · high confidence
New typed statistics resources for album, user, and upload data
The application now exposes structured statistics data via new Laravel Data resources (Album, CountsData, DayCount, Sizes, UserSpace) that are automatically transformed into TypeScript types. Users will see more granular statistics, including per-album details (photos, descendants, size), daily upload counts with configurable thresholds, and user space usage, all delivered through a strongly-typed API contract.
app/Http/Resources/Statistics · high confidence
New utility classes and asset management strategies in app/Assets
This change introduces several new classes to the app/Assets directory to support internal application logic and asset handling. It adds a terminal table display utility (ArrayToTextTable), a feature flag manager (Features), and various helper functions for system checks and data formatting (Helpers). It also introduces a database boolean parser (DbBool) to correctly handle PostgreSQL boolean values, a command executor wrapper for testing, and new naming strategies for size variants and watermarks that use random suffixes and grouped directory structures.
app/Assets · high confidence
New v8 frontend entry point and album interaction composable
The resources directory now includes a new Vue 3 entry point (resources/js/app-v8.ts) that initializes the frontend using Nuxt UI and Pinia, distinct from the legacy v7 PrimeVue setup. Additionally, new composable modules have been added to resources/js/composables/album/ to handle album-specific interactions, including drag-and-select functionality, folder drop uploads, photo actions (highlighting, rotation, header setting), and album tree validation operations.
resources · high confidence
New view components for metadata, theming, and webshop
The application now uses dedicated view components to manage page metadata, dynamic CSS theming, and webshop visibility. The Meta component generates Open Graph and social sharing tags, including width and height attributes for images, and selects album cover images based on configuration. The Style component dynamically generates CSS color palettes from user-configurable accent colors using a palette generator. The Webshop component controls the display of webshop features based on supporter status and payment gateway configuration (Mollie, Stripe).
app/View · high confidence
Smart albums now support dynamic property access via MimicModel trait
A new \MimicModel\ trait has been added to the \app/SmartAlbums/Utils\ directory, enabling smart album classes to mimic the behavior of Eloquent models. This allows users to access album properties dynamically using standard attribute syntax (e.g., \$album-\>photos\), which automatically resolves to corresponding getter methods or existing properties, providing a more consistent and intuitive API for interacting with smart album data.
app/SmartAlbums/Utils · high confidence
Support for 'Remember Me' option on login
The login request validation now accepts an optional 'remember me' boolean field. When provided, this flag is processed and made available to the authentication logic, allowing users to request persistent sessions during login.
app/Http/Requests/Session · high confidence
Support for Live Photos via MOV container conversion
The application now supports Live Photos by introducing a new MOV format handler that re-packetizes video streams into the Quicktime container format. This ensures compatibility with the frontend's live photos kit, which requires Quicktime containers rather than the native MP4 format used by source files. Additionally, a new trait for abstract album properties has been added to standardize access to album metadata such as ID, title, thumbnail, and associated photos.
app/ModelFunctions · high confidence
Support for associating video files as live photo partners
Users can now upload video files to serve as live photo partners for images. This change introduces a new processing pipeline (GetVideoPath, PlaceVideo, UpdateLivePartner) that handles the storage and linking of these video assets, supporting both local filesystems and S3 storage, and allowing videos to be placed via copy, move, or symlink depending on the import method.
app/Actions/Photo/Pipes/VideoPartner · high confidence
WebAuthn authentication and credential management via Laragear/WebAuthn
The application now supports WebAuthn (passkeys) for both login and device registration, replacing the previous implementation with the Laragear/WebAuthn package. Users can now authenticate using supported security keys or biometric devices through the new WebAuthnLoginController, and manage their registered credentials (list, edit aliases, delete) via the WebAuthnManageController. The WebAuthnRegisterController handles the initial device attestation process. This change introduces a new authentication flow that requires WebAuthn to be explicitly enabled in the configuration.
app/Http/Controllers/WebAuthn · high confidence
Webshop API resource layer for catalog, checkout, and orders
The shop-facing API now exposes a comprehensive set of data structures to support the new webshop backend. Catalog browsing is enabled via CatalogResource, which aggregates purchasable albums, children, and photos, alongside CatalogueSizesResource for print and pixel size options. Checkout configuration is handled by CheckoutOptionResource and ConfigOptionResource, exposing currency, payment providers, and default pricing settings. The purchasing flow is supported by EditablePurchasableResource for item details and CheckoutResource for transaction results. Finally, order management is covered by OrderResource and OrderItemResource, which provide full order details, line items, and associated media thumbnails.
app/Http/Resources/Shop · high confidence
Removals
Removed default Laravel authentication controllers
The application has removed the default scaffolding for user authentication, specifically deleting the ForgotPasswordController, LoginController, RegisterController, and ResetPasswordController files. This change eliminates the built-in controllers that previously handled user login, registration, and password reset workflows via standard Laravel traits, indicating a shift away from the default authentication setup.
app/Http/Controllers/Auth · high confidence
Architecture
Centralized factory classes for albums, IDs, payments, and persons
The application now uses dedicated factory classes in app/Factories to manage the creation and retrieval of core entities. AlbumFactory handles the unified lookup of regular, tag, person, and smart albums (including star ratings, highlights, and timeline views) via a new SmartAlbumType enum. IdFactory generates URL-safe random identifiers for assets. OmnipayFactory manages payment gateway initialization and validation for the webshop feature. PersonFactory simplifies the retrieval or creation of person records for facial recognition. This refactoring centralizes object instantiation logic, improving consistency and maintainability across these domains.
app/Factories · high confidence
Introduces model contracts and interfaces for albums, size variants, and time handling
This change adds a new set of interface and abstract class definitions in the \app/Contracts/Models\ directory to standardize model behaviors. It defines \AbstractAlbum\ to specify the common interface for all album types (including virtual smart albums), \SizeVariantFactory\ and \AbstractSizeVariantNamingStrategy\ to manage the creation and naming of photo size variants, \HasRandomID\ for ID generation, and \HasUTCBasedTimes\ to enforce consistent UTC-based datetime conversion for database storage and retrieval.
app/Contracts/Models · high confidence
Introduces pipe interfaces for photo creation workflows
The \app/Contracts/PhotoCreate\ directory now defines a set of interfaces (e.g., \PhotoPipe\, \StandalonePipe\, \DuplicatePipe\, \VideoPartnerPipe\) that establish a standardized pipeline structure for handling photo creation. These contracts enforce a consistent flow for different creation modes—such as standalone uploads, duplicates, and video partners—ensuring that each step in the process adheres to a uniform interface for state management and chaining.
app/Contracts/PhotoCreate · high confidence
Refactored model architecture to use composite pattern and introduce granular access permissions
The model layer has been restructured to use a composite pattern for albums, where \Album\ and \TagAlbum\ hold a reference to a new \BaseAlbumImpl\ class to share logic without relying on Eloquent table inheritance. A new \AccessPermission\ model replaces the previous base album access table, allowing for granular, per-user and per-group permissions (including download, upload, edit, and delete rights) on albums. Additionally, new models have been introduced to support pre-computed album size statistics (\AlbumSizeStatistics\), user-specific smart album thumbnails (\AlbumUserThumb\), and facial recognition data (\Face\, \FaceSuggestion\).
app/Models · high confidence
Refactored model architecture with new extension traits and base classes
The model layer has been restructured to use a parent-child implementation pattern and new extension traits. A new \BaseAlbum\ abstract class and \ForwardsToParentImplementation\ trait manage the delegation of album properties and relationships to a \BaseAlbumImpl\ parent, ensuring consistent ID handling and timestamp management. New traits like \HasRandomIDAndLegacyTimeBasedID\ handle primary key generation, \CachesAlbumUserThumb\ optimizes thumbnail retrieval with a per-viewer cache, and \FiltersUploadValidation\ enforces visibility rules for unvalidated photos. Additionally, \SortingDecorator\ centralizes SQL-level ordering logic, and \ThrowsConsistentExceptions\ standardizes error handling across model operations.
app/Models/Extensions · high confidence
Refactored version detection into a modular metadata system
The version detection logic in the application has been restructured into a set of specialized classes under \app/Metadata/Versions\. \FileVersion\ now handles version information derived from the \version.md\ file and remote update checks, \GitHubVersion\ manages Git-based versioning (branch, commit ID, and release status) by interacting with Git metadata and remote APIs, and \InstalledVersion\ determines the database-stored version and identifies whether the installation is a release or a development environment. A new \Trimable\ trait supports commit ID formatting. This change replaces the previous monolithic or ad-hoc versioning code with a cleaner, interface-driven architecture that separates concerns between file-based, Git-based, and database-based version sources.
app/Metadata/Versions · high confidence
Removal of legacy application model and helper classes
The legacy \app/\ directory structure has been removed, deleting the \Album\, \Photo\, \User\, \Configs\, \Logs\, \Response\, \Validate\, and \Helpers\ classes. This eliminates the previous Eloquent-based data models, configuration management, logging utilities, and image processing helpers, indicating a significant architectural shift in how the application handles data and core logic.
app · high confidence
Specialized query builders for model collections
The application now uses dedicated query builder classes (e.g., AlbumBuilder, PhotoBuilder, TagAlbumBuilder) for its core models instead of relying on generic query interfaces. This change enables fine-grained control over query construction, such as adding virtual columns like \is\_recursive\_nsfw\ to albums or handling PostgreSQL-specific boolean fixes, and ensures that computed statistics are only included when actual models are hydrated.
app/Models/Builders · high confidence
Standardized HTTP request contracts and attribute constants
The application introduces a comprehensive set of PHP interfaces in the \app/Contracts/Http\ directory to standardize HTTP request handling. These contracts, such as \HasAlbum\, \HasPhoto\, and \HasUser\, enforce strict type definitions for request data, ensuring that endpoints consistently access specific resources like albums, photos, and user groups. Additionally, the \RequestAttribute\ class centralizes all request payload keys (e.g., \id\, \user\_id\, \title\, \tags\) into a single source of truth, reducing magic strings and improving maintainability across the codebase.
app/Contracts/Http · high confidence
Behavioural changes
API resources migrated to Spatie Laravel Data with TypeScript generation
The API response structures for models (including albums, photos, users, faces, and administrative stats) have been rewritten as strongly-typed Data objects using the Spatie Laravel Data package. This change standardizes the serialization of API payloads and automatically generates TypeScript type definitions for the frontend via the TypeScript Transformer, ensuring that client-side code stays in sync with backend data contracts.
app/Http/Resources/Models · high confidence
Add Unicode support for Laminas text table decorators
A new Unicode decorator class has been added to the Laminas metadata module to properly handle Unicode characters in text-based table rendering. This implementation ensures that box-drawing characters and other special symbols are correctly encoded and displayed, improving the visual integrity of text tables that rely on the Laminas text component.
app/Metadata/Laminas · high confidence
Added authorization checks for diagnostics and job logs, and introduced FrameData resource
This change introduces three new PHP classes to enforce access control and structure API responses. The new \DiagnosticsRequest\ class restricts access to the diagnostics page, ensuring only users with the \CAN\_SEE\_DIAGNOSTICS\ permission can view system information. Similarly, \ShowJobsRequest\ adds an authorization gate for the job logs endpoint, requiring the \CAN\_SEE\_LOGS\ permission. Additionally, \FrameData\ is added as a structured data resource for frame information, utilizing the Spatie Laravel Data package and TypeScript transformer for type safety.
app/Http/Requests/Diagnostics, app/Http/Requests/Jobs, app/Http/Resources/Frame · high confidence
Admin bulk album edit validation rules
The admin bulk album edit feature now enforces strict input validation for its API endpoints. Administrators can now list albums with pagination (supporting 100, 200, or 500 items per page), search for albums by ID, and perform bulk operations including deleting albums, patching metadata (such as description, copyright, license, sorting, and visibility settings), and transferring ownership. All operations require administrator privileges and validate that at least one field is provided for updates, ensuring data integrity during bulk management tasks.
app/Http/Requests/Admin/BulkAlbumEdit · high confidence
Admin setup validation during installation
The installation process now enforces strict validation for the initial admin account creation. A new request class validates that the username and password meet specific rules (including password confirmation) and ensures that an admin user has not already been set up, preventing duplicate admin creation during the installation flow.
app/Http/Requests/Install · high confidence
Admin-only access control for Security Advisories index endpoint
The Security Advisories index endpoint now enforces strict authorization, allowing only users with administrative privileges to retrieve advisory data. Unauthenticated requests will receive a 401 error, while authenticated non-admin users will receive a 403 Forbidden response, ensuring that sensitive security information is not exposed to regular users.
app/Http/Requests/Admin/SecurityAdvisories · high confidence
Admin-only authorization for moderation queue endpoints
The moderation queue endpoints (listing, retrieving a single photo, and bulk approving) are now restricted to administrators. New request validation classes enforce that only users with the may\_administrate flag can access these features, ensuring that non-admin users cannot view or modify the moderation queue.
app/Http/Requests/Moderation · high confidence
Album and photo-specific renaming rules
Users can now define and apply renaming rules separately for albums and photos. The system introduces dedicated \AlbumRenamer\ and \PhotoRenamer\ classes that filter the global set of user-defined rules based on whether they are targeting albums or photos, allowing for distinct naming conventions for each content type.
app/Metadata/Renamer · high confidence
Album listing and rights queries refactored for performance
The album listing and rights endpoints now use a new Struct-of-Arrays implementation to improve data retrieval speed. This change introduces dedicated action classes (BuildAlbumDataResource, QueryChildrenForAlbum, QueryChildrenForPerson, QueryChildrenForTag, QueryRightsForAlbum, and QueryRightsForMatchingAlbums) that construct optimized database queries and map results into flat arrays for the V3 API resources. The refactoring ensures that album children, tag albums, and person albums are fetched and processed more efficiently, reducing overhead in the API response generation.
app/Actions/Album/StructOfArrays · high confidence
Album management actions refactored to new domain-driven structure
The album management logic in app/Actions/Album has been completely rewritten into a set of dedicated action classes (such as Create, Delete, Move, Merge, and SetProtectionPolicy). This refactoring replaces the previous monolithic model-based approach with a more efficient, explicit workflow for handling album operations, including optimized bulk deletion, permission inheritance, and smart album creation. Additionally, a new Breadcrumb action has been introduced to provide hierarchical navigation paths for albums, and the archive download system has been updated to support chunked downloads and version-specific ZIP handling.
app/Actions/Album · high confidence
Authorization logic for Flow API endpoints
New request classes (FlowRequest, GetFlowListRequest) define access control for the Flow feature. Authenticated users can access Flow if the 'flow\_enabled' config is true; guests require both 'flow\_enabled' and 'flow\_public' to be true. Additionally, the GetFlowListRequest is gated by the 'features.struct-of-array' config flag, ensuring it only functions when that structural feature is enabled.
app/Http/Requests/Flow · high confidence
Centralized album and photo query logic with caching and filtering
The application now uses dedicated repository classes (AlbumRepository, PhotoRepository, ConfigManager) to handle data access, replacing previous inline query logic. Album queries are now paginated, support configurable sorting criteria, and utilize a managed cache service to improve performance for album listings and tag-based album searches. Photo queries for albums now support optional filtering by tags (with AND/OR logic) and person IDs, while ensuring non-admin users only see validated photos. Configuration values are now accessed through a centralized ConfigManager with type-safe getters and local caching.
app/Repositories · high confidence
Centralized authorization checks for album and photo editing
Authorization logic for modifying albums and photos has been extracted into dedicated traits within the \app/Http/Requests/Traits/Authorize\ directory. These new traits (such as \AuthorizeCanEditAlbumTrait\ and \AuthorizeCanEditPhotosTrait\) now explicitly enforce permissions using the \AlbumPolicy\ and \PhotoPolicy\ via Laravel's Gate facade, ensuring that users can only edit resources they have been granted permission to access.
app/Http/Requests/Traits/Authorize · high confidence
Complete backend rewrite with new controller architecture and security enhancements
The application has undergone a major backend refactoring, replacing the legacy controller structure with a modern, modular architecture. This change introduces new controllers for authentication (including LDAP support and OAuth integration), user profile management, and secure file serving with path traversal protection. It also adds dedicated controllers for managing renamer rules, statistics, tags, and RSS feeds, while removing the old Album and Albums controllers. Additionally, a new HoneyPotController has been added to help block automated scanning, and the landing page now uses a dedicated controller for its configuration.
app/Http/Controllers · high confidence
Comprehensive exception handling and reporting overhaul
The application now uses a dedicated \BaseLycheeException\ hierarchy to replace generic PHP exceptions, ensuring that all user-facing errors return precise HTTP status codes (such as 401, 403, 409, 412, 413, and 419) and clear, non-technical messages. This change introduces dozens of specific exception classes for scenarios like LDAP authentication failures, media conversion errors, and session expiration, while the new \Handler\ class enforces structured logging with configurable severity levels and ensures consistent JSON or HTML responses for API and web clients.
app/Exceptions · high confidence
Consistent error handling for database query operations
The application now uses a custom query builder (\FixedQueryBuilder\) and trait (\FixedQueryBuilderTrait\) to wrap core Eloquent methods like \where\, \select\, and \join\. This change ensures that internal errors during query construction are caught and re-thrown as specific \QueryBuilderException\ instances, providing more consistent and catchable error handling for users when database queries fail.
app/Eloquent · high confidence
Database migration scripts for legacy data import and configuration schema updates
This location contains the database migration files responsible for importing legacy Lychee v3 data (settings, albums, and photos) into the new schema, creating new tables for pages and symbolic links, and establishing the modern \configs\ table structure with categories and confidentiality levels. It also includes migrations that introduce new configuration options for features such as map providers, live photos, RSS feeds, and image processing tools like Exiftool and FFmpeg, alongside schema adjustments for photo metadata like location decoding and thumbnail handling.
database/migrations · high confidence
Diagnostics API resources migrated to Spatie Laravel Data
The diagnostic information endpoints now use a new set of resource classes (e.g., AlbumTree, ErrorLine, StatisticsCheckResource) built on the Spatie Laravel Data package. This change standardizes how diagnostic data is structured and serialized, ensuring consistent output for users checking system health, album tree integrity, and error logs.
app/Http/Resources/Diagnostics · high confidence
Diagnostics system refactored to use Laravel Pipelines
The diagnostics functionality has been restructured to use Laravel's Pipeline pattern, separating checks into distinct pipe classes for errors, configuration, system info, and disk space. This change introduces a more modular and extensible architecture for running diagnostic checks, allowing individual checks to be skipped or modified independently. The new structure includes specific checks for database integrity, configuration sanity, PHP version, opcache, and various service statuses, providing a more comprehensive and organized diagnostic report for users.
app/Actions/Diagnostics · high confidence
Efficient batch deletion of size variants with async file cleanup
The system now deletes multiple size variant records in a single database operation rather than one-by-one, significantly improving performance for bulk removals. Additionally, the action now supports S3 storage disks alongside local storage, ensuring that associated image files (including watermarked versions) are correctly identified and queued for asynchronous deletion via background jobs, regardless of where the media is stored.
app/Actions/SizeVariant · high confidence
Expanded diagnostics with detailed system, version, and Docker environment reporting
The diagnostics report now includes several new informational sections to help users troubleshoot their installation. It displays the specific Lychee edition (SE, Pro, or Signature) and version channel (Release, Tag, or Git), along with database version details. System information now explicitly shows the PHP integer size (32 vs 64-bit) and the number of database foreign keys. Additionally, it identifies the Docker environment type (LinuxServer.io, LycheeOrg, LycheeFrankenPHP, or custom) and lists available PHP extensions (Imagick and GD) with their versions.
app/Actions/Diagnostics/Pipes/Infos · high confidence
Extract OAuth logic into dedicated action class
The OAuth authentication and registration logic has been moved from the controller into a new \App\\Actions\\Oauth\\Oauth\ class. This refactoring centralizes the handling of OAuth providers, user creation on first attempt, and credential management into a dedicated service, improving code organization and separation of concerns within the application.
app/Actions/Oauth · high confidence
Frame access now requires explicit configuration and album selection
The Frame feature now enforces stricter access controls: users must have the 'mod\_frame\_enabled' configuration option turned on, and they must either provide a specific album ID or have a 'random\_album\_id' configured in the system settings. If these conditions are not met, access to the frame is denied with an unauthorized error, preventing accidental or unauthorized frame usage.
app/Http/Requests/Frame · high confidence
Improved bootstrap error handling and configuration initialization
The application now provides clearer, user-friendly error pages for critical bootstrap failures, such as missing Composer dependencies, disabled Apache mod\_rewrite, or incorrect file permissions on the storage and .env files, instead of showing generic PHP errors. Additionally, the bootstrap process now sets a specific User-Agent string for HTTP requests and configures file permissions (umask) to ensure proper group-writable access for cache files, while also supporting a configurable base path via the APP\_BASE\_PATH environment variable.
bootstrap · high confidence
Input validation for landing page configuration
Added request validation classes for managing landing page featured items and links. Administrators can now create, update, delete, and reorder featured items and links through the API, with built-in links protected from deletion and URL modification.
app/Http/Requests/LandingFeaturedItem, app/Http/Requests/LandingLink · high confidence
Introduces structured search token parsing and strategy interfaces
The search system now uses a dedicated \SearchToken\ data transfer object to represent individual parsed query components (such as modifiers like 'tag' or 'date', operators, and values) instead of raw strings. To support this, new contract interfaces (\AlbumSearchTokenStrategy\ and \PhotoSearchTokenStrategy\) have been added to define how these tokens are applied to database queries for albums and photos respectively. This change refactors the internal search logic to be more modular and type-safe, allowing distinct strategies to handle different search modifiers.
app/Contracts/Search, app/DTO/Search · high confidence
Introduction of version control and release detection interfaces
New contract interfaces have been added to the application's versioning system to standardize how version information and release status are accessed. The \HasIsRelease\ interface defines a method to determine if the current instance represents a release, while \HasVersion\ provides a getter for the stored version object. Additionally, \GitRemote\ specifies methods for fetching remote Git data, counting commits behind the current version, and retrieving head details, and \VersionControl\ outlines the core logic for hydrating remote data and checking if the installation is up to date.
app/Contracts/Versions · high confidence
Major application bootstrapping and service wiring overhaul
The application's service providers have been significantly refactored to support a modernized architecture. The AppServiceProvider now handles extensive service registration, including singletons for factories and versioning, request macros for verification and configuration, database query logging, Octane settings, and model observers. The AuthServiceProvider introduces a custom 'session-or-token' authentication guard and defines granular policies for users, photos, albums, tags, and AI vision features. The EventServiceProvider has been expanded to integrate multiple OAuth providers (Authelia, Authentik, Keycloak, etc.) via Socialite and registers numerous listeners for caching, metrics, license rotation, and webhooks. Additionally, the RouteServiceProvider now maps specific route files to distinct middleware groups (web-admin, api v2/v3, web-install) and implements rate limiting, while a new TypeScriptTransformerServiceProvider configures automatic TypeScript generation from PHP classes.
app/Providers · high confidence
Migrate album and photo configuration options to PHP enums
The application now uses strict PHP enums to define allowed values for album and photo display settings, replacing previous loose string or integer constants. This change enforces type safety for options such as album layouts (list, grid), photo layouts (square, justified, masonry, grid), aspect ratios, album decoration types and orientations, header sizes, title colors and positions, image overlay types, and thumbnail info. It also standardizes sorting columns, pagination modes, and landing page configuration options (layout, background mode, CTA position, featured items). For users, this ensures that only valid, pre-defined configuration choices are accepted, reducing the risk of invalid settings and improving consistency across the gallery's visual presentation and sorting behavior.
app/Enum · high confidence
Migrated collection API resources to Spatie Laravel Data
The API response structures for collections (including paginated albums, photos, persons, faces, webhooks, and the root album view) have been rewritten to use Spatie Laravel Data classes. This change standardizes how data is serialized to JSON, ensuring consistent typing and structure for the frontend, and introduces TypeScript type definitions for better client-side integration.
app/Http/Resources/Collections · high confidence
Migrated validation rules to Laravel 10 ValidationRule interface
The custom validation rules in app/Rules have been refactored to implement Laravel's modern ValidationRule interface, replacing the deprecated Rule interface used in previous versions. This change ensures compatibility with Laravel 10 and improves type safety across the application's input validation layer, including rules for album IDs, file uploads, configuration keys, and user authentication.
app/Rules · high confidence
New Docker entrypoint with strict environment validation and privilege dropping
The Docker entrypoint has been rewritten to enforce stricter security and configuration checks at startup. It now validates critical environment variables (such as APP\_KEY and database credentials), supports loading secrets from files via \_FILE suffixes, and checks for misconfigurations like mounted .env files. The entrypoint also drops privileges to the www-data user by default (using gosu or su-exec) and introduces a worker mode for horizontal scaling that waits for database migrations before starting queue workers.
docker · high confidence
New Editable API resource layer for albums, configuration, and uploads
The application introduces a new set of API resources in the \app/Http/Resources/Editable\ namespace to standardize how album metadata, system configuration, and upload details are serialized for the frontend. \EditableBaseAlbumResource\ now exposes a comprehensive set of album properties—including sorting criteria, layout options, timeline granularities, and specific attributes for tag and person albums—while conditionally exposing slugs only to supporter users. \EditableConfigResource\ provides a structured key-value representation for configuration data, and \UploadMetaResource\ enhances upload responses by including the expected ID, title, and description alongside file chunking details, enabling clients to handle metadata at upload time.
app/Http/Resources/Editable · high confidence
New Eloquent attribute casts for timezones, money, and read-only enforcement
The application introduces three new Eloquent casts in the \app/Casts\ directory to improve data handling and integrity. \DateTimeWithTimezoneCast\ ensures datetime attributes preserve their original timezone information and correctly compares instants across different database engines (fixing spurious dirty-state changes on PostgreSQL). \MoneyCast\ automatically converts between integer cent values in the database and \Money\ objects in PHP, supporting configurable default currencies. \MustNotSetCast\ prevents accidental modification of specific model attributes by throwing an exception if a set operation is attempted, optionally suggesting an alternative attribute to use instead.
app/Casts · high confidence
New Struct-of-Arrays API v3 endpoints for album listing and permissions
The Gallery controllers have been restructured to introduce a new API v3 interface that returns album data using a Struct-of-Arrays pattern. This includes new endpoints for the root album listing (\GET /Albums/root\), the flat album index (\GET /Albums\), and the bulk access permission list (\GET /Albums::accessPermissions\). The implementation replaces previous join-heavy queries with column-narrowed subqueries to prevent sensitive data leakage and improve performance, while adding support for caching, pagination, and scope-based filtering (own vs. shared) across root, pinned, tag, person, and smart album categories.
app/Http/Controllers/Gallery · high confidence
New backend actions for album listing, flow, and position data
The application introduces three new action classes in the Albums module to handle specific data retrieval tasks. The \Top\ action manages the retrieval of top-level albums (including smart, tag, person, and pinned albums) with integrated caching and ownership partitioning. The \Flow\ action constructs the query builder for the photo flow view, supporting configurable base albums, sub-album inclusion, and NSFW filtering. The \PositionData\ action retrieves photo location data for map views, optimizing performance by limiting size variant hydration. These changes refactor how album and photo metadata is fetched for the UI.
app/Actions/Albums · high confidence
New centralized authorization policies for albums, photos, and AI vision features
The application now uses a comprehensive set of Laravel Policy classes in app/Policies to manage access control. AlbumPolicy and PhotoPolicy enforce granular permissions for viewing, editing, downloading, and sharing, with PhotoPolicy inheriting album access rules and requiring photo validation for edits. AlbumQueryPolicy and PhotoQueryPolicy apply database-level filters for visibility, accessibility, and searchability, ensuring users only see data they are authorized to access. AiVisionPolicy introduces configurable face-permission modes (public, private, privacy-preserving, restricted) to control who can view, edit, claim, or merge AI-detected persons. MetricsPolicy restricts live metrics access based on configuration, while UserPolicy and UserGroupPolicy manage user profile edits and group administration. BasePolicy provides a global admin override, and SettingsPolicy restricts administrative settings to admins only.
app/Policies · high confidence
New contracts for diagnostic pipelines and external/JSON requests
The application introduces new interface contracts to standardize diagnostic processing and external data fetching. \DiagnosticPipe\ and \DiagnosticStringPipe\ define the contract for pipeline-based diagnostic handlers, allowing users to benefit from more structured and complete diagnostic reports. Additionally, \ExternalRequest\ and \JsonRequest\ interfaces abstract external HTTP interactions, providing consistent methods for clearing caches, retrieving age text, and fetching data (raw or decoded JSON) with optional caching support.
app/Contracts · high confidence
New domain events for album, photo, and user state changes
The application now dispatches a comprehensive set of domain events in the \app/Events\ namespace to signal state changes. These include \AlbumSaved\, \AlbumDeleted\, and \AlbumComputedDataUpdated\ to track album modifications and computed data updates; \PhotoAdded\, \PhotoDeleted\, \PhotoMoved\, \PhotoSaved\, and \PhotoBucketsRecomputed\ to handle photo lifecycle and listing cache invalidation; and \UserGroupMembershipChanged\ to track user permission updates. Additionally, specific cache-invalidation events like \AlbumListingCacheFlushRequested\ and \MapListingCacheFlushRequested\ are introduced to manage global cache coherence for album and map listings.
app/Events · high confidence
New embed request validation for filtering by author
A new \EmbededRequest\ class has been introduced to handle validation and authorization for embed endpoints. This change enables users to filter embedded albums and streams by author using the \data-author\ attribute (passed as a query parameter), supporting comma-separated usernames. It also enforces pagination limits (capped at 500), offset handling, and sort order validation, while ensuring that only public albums without password or link restrictions are accessible via embeds.
app/Http/Requests/Embed · high confidence
New image and video processing handler architecture
The application introduces a new, structured image processing system in the \app/Image/Handlers\ directory. This includes a \BaseImageHandler\ for shared logic like lossless optimization, and specific handlers for different engines: \GdHandler\ (using the GD library), \ImagickHandler\ (using ImageMagick), and \VideoHandler\ (using FFmpeg for video thumbnails). A dispatcher \ImageHandler\ automatically selects the best available engine (Imagick or GD) to load and manipulate images. Additionally, a \GoogleMotionPictureHandler\ is added to extract video streams from Google Motion Photos. This change replaces the previous ad-hoc image processing logic with a modular, extensible interface.
app/Image/Handlers · high confidence
New import pipeline with album/album deletion and job-based photo import
The import process in app/Actions/Import/Pipes has been restructured into a new pipe-based pipeline. BuildTree constructs a folder tree while skipping Lychee-reserved directories. CreateNonExistingAlbums creates or reuses albums (supporting optional title renaming) to match the folder structure. DeleteMissingAlbums and DeleteMissingPhotos can remove database records for albums or photos that no longer exist on disk, with dry-run support. ImportPhotos adds new images to albums, optionally skipping duplicates early, and queues ImportImageJob, RecomputeAlbumSizeJob, and RecomputeAlbumStatsJob for later processing. ExecuteBatch dispatches those queued jobs. PruneEmptyNodes removes empty folders and fails if the entire import path is empty. HasReporterTrait provides unified status reporting to CLI/web clients and test silencing.
app/Actions/Import/Pipes · high confidence
New install and update system with stricter PHP requirements
The application introduces a new pipeline-based architecture for checking and applying updates (ApplyUpdate, CheckUpdate) and validating server environments (RequirementsChecker, PermissionsChecker). This change raises the minimum supported PHP version to 8.2.0 (as defined in RequirementsChecker) and enforces specific folder permissions for storage and database directories. The update process now strictly follows a sequence of branch checking, git pulling, database migration, and composer dependency installation, replacing previous ad-hoc update mechanisms.
app/Actions/InstallUpdate · high confidence
New internal exception classes for zip extraction and model assumptions
The application now includes a set of new internal exception classes in the \app/Exceptions/Internal\ directory to improve error handling and debugging. Specifically, \ZipBombDetectedException\ and \ZipExtractionException\ have been added to distinguish between zip-bomb protection rejections and general extraction failures, while \FailedModelAssumptionException\ and \MissingModelAttributeException\ provide more specific signals for model-related logic errors. These changes support the new zip upload extraction feature and refine the internal error reporting mechanism.
app/Exceptions/Internal · high confidence
New middleware architecture and CSRF handling for API tokens
The application has replaced legacy middleware classes (AdminCheck, AlbumPWCheck, EncryptCookies, RedirectIfAuthenticated, TrustProxies) with a comprehensive set of new, purpose-built middleware components. This includes AcceptContentType and ContentType for strict request/response validation, FeatureEnabled for feature-flag gating, and status-checking middleware (InstallationStatus, MigrationStatus, AdminUserStatus) to control access based on system state. A key behavioral change is in VerifyCsrfToken, which now bypasses CSRF verification for requests carrying an API token header, while also excluding specific internal and public endpoints like zip downloads and session initialization. Additionally, new middleware handles album slug resolution, RSS feed metadata injection, locale setting, and CSP adjustments for development tools.
app/Http/Middleware · high confidence
New pipe-based update installer architecture
The application introduces a new modular pipeline system for handling installation and updates, located in app/Actions/InstallUpdate/Pipes. This change replaces previous implementation with a series of dedicated pipe classes (such as GitPull, ComposerCall, ArtisanKeyGenerate, and ArtisanMigrate) that execute specific update steps in sequence. Users will experience a more structured and potentially more reliable update process, with distinct stages for pulling code, managing dependencies, generating keys, and running database migrations, all coordinated through the new AbstractUpdateInstallerPipe base class.
app/Actions/InstallUpdate/Pipes · high confidence
New profile request validators for registration, OAuth, and shared album visibility
This change introduces a new set of Laravel request validation classes in the Profile namespace to handle specific user profile operations. The new \RegistrationRequest\ enforces username, email, and password rules for new user sign-ups, while \UpdateProfileRequest\ manages profile updates with conditional logic for basic authentication. Additionally, \ClearOauthRequest\ and \OauthListRequest\ provide structured validation for managing OAuth provider connections, and \UpdateSharedAlbumsVisibilityRequest\ allows users to configure the visibility of their shared albums using a specific enum. These validators centralize authorization checks and input validation for these profile-related features.
app/Http/Requests/Profile · high confidence
New request classes for managing settings configurations
The application introduces dedicated Laravel request validation classes for the Settings area: GetAllConfigsRequest retrieves all configuration values, SetConfigsRequest validates and processes bulk updates to editable configuration keys and values, and SetCSSSettingRequest and SetJSSettingRequest handle the validation and storage of custom CSS and JavaScript snippets. All operations require the user to pass the SettingsPolicy::CAN\_EDIT authorization gate.
app/Http/Requests/Settings · high confidence
New request validation classes for album listing and permission access
Added AlbumListV3Request and AlbumAccessPermissionListRequest to handle input validation and authorization for the v3 album API endpoints. AlbumListV3Request introduces admin-gated optional flags (with\_parent\_id, for\_bulk\_edit) that restrict access to administrators when enabled, while allowing open access for standard listing. AlbumAccessPermissionListRequest enforces that only users who own at least one album or are administrators can list album access permissions, aligning with the existing sharing list policy.
app/Http/Requests/Gallery · high confidence
New structured API resources for search initialization and results
The search functionality now exposes dedicated API resources (\InitResource\ and \ResultsResource\) that standardize how search configuration and results are returned to the client. \InitResource\ provides the minimum search length and current photo layout settings, while \ResultsResource\ delivers paginated collections of albums and photos, including metadata such as current page, total items, and per-page counts. This change introduces a consistent data structure for search endpoints, replacing previous ad-hoc response formats.
app/Http/Resources/Search · high confidence
New structured configuration resources for gallery, landing, and timeline views
The application now exposes a comprehensive set of new data resources in the \app/Http/Resources/GalleryConfigs\ directory (alongside \Root\ and \Timeline\ resources) to provide the frontend with structured configuration data. These resources—such as \InitConfig\, \LandingPageResource\, \AlbumConfig\, \UploadConfig\, and \NsfwConfigResource\—aggregate settings for features including the new landing page layouts, NSFW moderation, upload chunking, timeline granularity, and album display options. This change centralizes how configuration values are fetched and projected to the client, ensuring the UI receives consistent, typed data for these specific areas.
app/Http/Resources/GalleryConfigs · high confidence
New structured honeypot pipeline for detecting malicious access attempts
The application now uses a dedicated pipe-based architecture in app/Actions/HoneyPot to intercept and handle suspicious requests. This new system includes a base class for consistent error handling (preserving path information in logs) and specific handlers: it checks if the honeypot is enabled, blocks attempts to access .env files, and flags requests matching configured honeypot paths or cross-product patterns by returning a 418 (I'm a teapot) status instead of a standard 404. This provides more granular detection and better debugging information for security events.
app/Actions/HoneyPot · high confidence
New structured request classes for Map API endpoints
The Map API endpoints now use dedicated request validation classes (GetMapBucketsRequest, GetMapPhotosRequest, GetMapTracksRequest, and MapDataRequest) to handle input validation and authorization. These classes enforce specific rules for album access and viewport parameters, with GetMapTracksRequest requiring an album ID while others make it optional. Authorization checks are gated behind the 'features.struct-of-array' configuration flag for bucket, photo, and track endpoints, ensuring consistent access control across map-related API calls.
app/Http/Requests/Map · high confidence
New structured request validators for album API endpoints
The application introduces a comprehensive set of new HTTP request validation classes in the \app/Http/Requests/Album\ directory to handle album-related API operations. These new validators replace previous ad-hoc handling with structured classes for creating albums (\AddAlbumRequest\), managing smart albums (\AddPersonAlbumRequest\, \AddTagAlbumRequest\), retrieving album data and children (\GetAlbumRequest\, \GetAlbumChildrenRequest\, \GetAlbumPhotosRequest\), and performing administrative actions like merging, moving, or deleting albums (\MergeAlbumsRequest\, \MoveAlbumsRequest\, \DeleteAlbumsRequest\). This change standardizes input validation, authorization checks via policies, and data processing for the album management features.
app/Http/Requests/Album · high confidence
New structured rights resources for granular permission exposure
The application now exposes a comprehensive set of fine-grained permission flags to the frontend via new Laravel Data resources in the \app/Http/Resources/Rights\ directory. \AlbumRightsResource\ and \PhotoRightsResource\ provide detailed boolean capabilities (such as \can\_share\_with\_users\, \can\_make\_purchasable\, and AI-vision-specific actions like \can\_assign\_face\), while \ModulesRightsResource\ dynamically reports the availability of features like the map, flow, watermarker, and webshop based on configuration and user role. This structured approach ensures the UI accurately reflects the user's actual access rights across albums, photos, user management, and system modules.
app/Http/Resources/Rights · high confidence
New structured validation for album sharing operations
The sharing API now uses dedicated request classes (Add, Edit, Delete, List, ListAll, and Propagate) to validate inputs and enforce authorization. This ensures that only album owners or admins can manage shares, requires at least one user or group when adding permissions, and introduces a propagation feature that allows sharing settings to be overridden across albums.
app/Http/Requests/Sharing · high confidence
New validation and authorization logic for checkout operations
This change introduces five new request classes (CancelRequest, CreateSessionRequest, FinalizeRequest, OfflineRequest, ProcessRequest) within the app/Http/Requests/Checkout directory. These classes define the specific validation rules, authorization checks, and data preparation logic for various stages of the checkout process, such as creating payment sessions, finalizing transactions, handling offline payments, and processing payments. They ensure that only authorized users can perform these actions and that the incoming data meets the required format and constraints before being processed by the backend.
app/Http/Requests/Checkout · high confidence
New validation requests for admin import and stats features
Added new request validation classes in the admin area to support importing from server and managing admin statistics. Specifically, \ImportFromServerRequest\ validates the core import operation including directory paths, symlink options, and conflict checks, while \ImportFromServerBrowseRequest\ and \ImportFromServerOptionsRequest\ handle browsing and configuration options. \AdminStatsRequest\ and \AdminUpdateStatusRequest\ provide validation for admin statistics and status updates. All requests enforce appropriate authorization policies.
app/Http/Requests/Admin · high confidence
Photo management actions refactored to use a pipeline architecture with new duplicate and partner handling
The photo management actions in app/Actions/Photo have been completely rewritten to use a pipeline pattern for complex operations like creation, introducing dedicated pipes for handling duplicates, photo partners (Live Photos), and standalone uploads. This change adds robust duplicate detection and resolution logic, including metadata resyncing and skipping untrusted duplicates, while also supporting the creation and management of paired photo/video files. Additionally, the refactoring includes new classes for efficient photo deletion, moving/duplicating photos across albums with proper bucket ID computation, and a unified RAW-to-JPEG converter that preserves original files.
app/Actions/Photo · high confidence
RSS feed generation now produces one item per photo with proper enclosures and categories
The RSS feed action has been refactored to generate a single \<item\> for each photo rather than per-album, ensuring photos appear only once in the feed regardless of how many albums they belong to. Each item now includes an enclosure linking to the original image file, along with category tags derived from the most recent album the photo resides in. The feed respects user access permissions and NSFW settings, filtering out locked or sensitive albums for non-admin users, and orders items by creation date in reverse chronological order.
app/Actions/RSS · high confidence
Refactor user management into dedicated action classes
User management logic has been reorganized into a set of dedicated action classes within the \app/Actions/User\ directory. This change introduces specific handlers for creating users (\Create\), updating user details (\Save\), and managing API tokens (\TokenReset\, \TokenDisable\). It also adds support for LDAP integration via a new \ProvisionLdapUser\ action that automatically provisions and synchronizes local user attributes and admin status from LDAP groups, and a \Notify\ action that handles new photo email notifications. This refactoring centralizes user-related business logic, improving code maintainability and separating concerns from controllers.
app/Actions/User · high confidence
Refactored API request validation and authorization flow
The application's HTTP request handling has been restructured to ensure input validation occurs before authorization checks. A new \BaseApiRequest\ class overrides Laravel's default behavior to validate request data first, then check user permissions, preventing unnecessary database queries for unauthorized users. An \AbstractEmptyRequest\ base class was introduced to simplify request classes that require no validation rules or post-processing, such as the new \ListUsersRequest\ and \UsersRequest\ classes which now explicitly define their authorization logic using Laravel's Gate and Auth facades.
app/Http/Requests · high confidence
Refactored Eloquent relations for albums and photos
The \app/Relations\ directory has been restructured to use a new set of custom Eloquent relation classes (such as \BaseHasManyPhotos\, \HasAlbumThumb\, \HasManyChildAlbums\, and \HasManyPhotosByTag\). This change centralizes photo and album association logic, introducing stricter access control via \PhotoQueryPolicy\ and \AlbumQueryPolicy\, enforcing album-specific sorting through \SortingDecorator\, and supporting bidirectional relationships. For users, this results in more consistent and performant handling of album thumbnails, child albums, and smart albums (tag and person albums), while ensuring that visibility and sensitivity filters are applied correctly across all photo listings.
app/Relations · high confidence
Refactored album resource traits for header selection and timeline granularity
The album resource layer has been refactored into dedicated traits to improve how album headers are selected and timeline data is structured. The new \HasHeaderUrl\ trait introduces logic to determine the album cover image, respecting a new 'compact header' configuration and ensuring empty albums return no header. The \HasTimelineData\ trait centralizes the resolution of timeline granularity settings for both albums and photos, allowing them to fall back to default configuration values when not explicitly set. Additionally, \HasPrepPhotoCollection\ now handles the preparation of photo resources, including linking previous and next photo IDs for navigation.
app/Http/Resources/Traits · high confidence
Refactored installation and migration checks into dedicated middleware components
The installation status, database migration status, and admin user presence are now verified by new, specific middleware classes (IsInstalled, IsMigrated, HasAdminUser) that implement the MiddlewareCheck interface. This change improves robustness during installation and updates: IsInstalled now gracefully handles database connection failures (such as missing drivers or authentication errors) instead of crashing, and HasAdminUser correctly handles the scenario where the 'may\_administrate' column does not yet exist in the users table, ensuring the system can properly detect or create an admin user during the setup process.
app/Http/Middleware/Checks · high confidence
Refactored photo API request validation into dedicated classes
The photo-related API endpoints now use a set of dedicated request classes (e.g., \CopyPhotosRequest\, \EditPhotoRequest\, \UploadPhotoRequest\) to handle validation and authorization. This change centralizes the logic for validating photo IDs, album associations, and specific attributes like titles, descriptions, and watermarks, ensuring that only the necessary data is processed and that access policies are consistently enforced before the main controller logic runs.
app/Http/Requests/Photo · high confidence
Refactored photo initialization into a modular pipe system with improved RAW and metadata handling
The photo upload and import initialization process has been restructured into a series of dedicated pipes within the \app/Actions/Photo/Pipes/Init\ directory. This change introduces specific steps for validating supported media formats, detecting and converting RAW files to JPEG while preserving originals, finding duplicate photos via checksums, and linking live photo components. Metadata extraction now prioritizes the original RAW file over converted JPEGs to preserve EXIF data, and import modes can now selectively skip metadata loading. This modular approach replaces previous monolithic logic, making the upload flow more robust and easier to extend.
app/Actions/Photo/Pipes/Init · high confidence
Refactored photo upload data structures into dedicated DTOs
The photo upload process now uses specific Data Transfer Objects (StandaloneDTO, DuplicateDTO, VideoPartnerDTO, PhotoPartnerDTO, and InitDTO) to manage upload context. This change introduces support for user-supplied title and description overrides during upload, allows disabling watermarks per upload, and enables pre-allocating photo IDs to return expected IDs in the response before the upload job completes.
app/DTO/PhotoCreate · high confidence
Refactored photo upload pipeline into modular, shared processing steps
The photo upload workflow has been restructured into a series of dedicated pipe classes within the \app/Actions/Photo/Pipes/Shared\ directory. This change introduces specific, isolated steps for handling metadata hydration, color palette extraction, reverse-geocoding, S3 uploads, album notifications, and ownership validation. By breaking the monolithic upload logic into these composable components, the system now supports more granular control over the upload process, enabling features like asynchronous background jobs for geocoding and color extraction, while ensuring that photo metadata and statistics are correctly hydrated and persisted through a standardized pipeline.
app/Actions/Photo/Pipes/Shared · high confidence
Refactored remote version checking into a structured Git remote strategy
The remote version-checking logic has been restructured to use a dedicated abstract base class and specific implementations for fetching Git tags and commits. This change introduces \AbstractGitRemote\ along with \GitTags\ and \GitCommits\ classes, which standardize how the application retrieves remote HEAD information, commit SHAs, and age text. Users benefit from a more maintainable and consistent approach to version updates, ensuring that checks against GitHub tags and commit histories are handled through a unified interface.
app/Metadata/Versions/Remote · high confidence
Refactored routing architecture with new API and web route files
The application's routing has been reorganized into distinct, modular files to improve maintainability and support new features. The legacy \routes/web.php\ and \routes/api.php\ files have been removed and replaced with \routes/web\_v2.php\ (handling the main Vue-based frontend, OAuth, and health checks), \routes/api\_v2.php\ (the primary JSON API for gallery operations, sharing, and imports), \routes/api\_v3.php\ (a new greenfield API surface using Struct-of-Arrays for albums, photos, and maps), and \routes/api\_v2\_shop.php\ (dedicated routes for the webshop basket, checkout, and management). Additionally, \routes/web-admin-v2.php\ and \routes/web-install.php\ now handle administrative and installation-specific UI routes separately. This change also removes deprecated Laravel default routes (console, channels) and redirects old v1 API calls to an error view.
routes · high confidence
Refactored search engine with structured token parsing and strategy-based filtering
The search functionality in app/Actions/Search has been completely rewritten to use a structured token parser and a strategy pattern for filtering. Search queries are now parsed into typed tokens (e.g., tag, date, rating, color) by SearchTokenParser, which are then applied to queries via specific strategies in PhotoSearch and AlbumSearch. This allows for precise filtering on photo attributes (like make, lens, ISO, rating) and album attributes (title, description, date, tags), with proper handling of visibility, permissions, and sorting. The refactoring also introduces support for color name resolution via ColourNameMap and ensures that photo-only filters do not incorrectly match albums.
app/Actions/Search · high confidence
Refactored search request validation and sorting logic
The search functionality has been refactored to introduce structured request classes (GetSearchRequest, InitSearchRequest) that enforce stricter validation and support explicit sorting. Users can now specify sorting columns and orders for search results, with the system automatically mapping these to appropriate photo and album sorting criteria. The refactoring also improves security by ensuring proper authorization checks are applied to search operations, particularly when accessing albums.
app/Http/Requests/Search · high confidence
Refactored tag API resources to use structured data classes
The tag-related API endpoints now return structured data via new resource classes (PhotoTagResource, TagResource, TagWithPhotosAndAlbumsResource, and TagsResource) built on Spatie Laravel-Data. This change standardizes the JSON response format for tags, including photo and album associations, and introduces a can\_edit permission flag in the TagsResource to indicate whether the current user has permission to edit tags.
app/Http/Resources/Tags · high confidence
Replaced photo query logic with Struct-of-Arrays architecture for improved performance
The photo listing, bucketing, and details endpoints now use a new Struct-of-Arrays implementation that returns data as parallel arrays rather than hydrated Eloquent models. This change significantly reduces memory usage and improves response times for large albums and smart albums (such as the Timeline) by performing SQL-level grouping and filtering where possible, while deferring full model hydration only to the specific details tier where it is strictly necessary.
app/Actions/Photo/StructOfArrays · high confidence
Robust bulk deletion of albums and photos
The album and photo deletion workflows have been refactored to handle large-scale removals reliably. The new \AlbumsToBeDeletedDTO\ and \PhotosToBeDeletedDTO\ classes chunk database operations to prevent MySQL placeholder limits (Error 1390) when deleting many items at once. Album deletion now correctly manages nested-set tree gaps and foreign key constraints by deleting leaves before parents and temporarily disabling constraints within a transaction. Photo deletion ensures that cover and header references in other albums are cleared, triggers necessary cache flushes and events, and schedules background jobs for file and face embedding cleanup.
app/DTO/Delete · high confidence
Secure zip extraction with bomb and path-traversal protection
The application now uses a new SafeZipExtractor service to handle untrusted zip uploads, protecting against zip-bomb attacks and path-traversal (zip-slip) vulnerabilities. This service validates archive metadata before extraction, enforces strict limits on total uncompressed size, per-file size, entry count, and compression ratio, and ensures extracted files remain within the designated destination directory.
app/Services/Zip · high confidence
Smart albums now respect per-user ownership and configurable visibility overrides
The smart album system in app/SmartAlbums has been refactored to support user-specific filtering and granular visibility controls. By default, smart albums now respect the \enable\_smart\_album\_per\_owner\ configuration, meaning albums like 'My Best Pictures' or 'My Rated Pictures' only show photos rated by the current user, while others like 'Recent' or 'Highlighted' show photos the user has access to. Additionally, a new \SA\_override\_visibility\ setting allows administrators to bypass standard security filters for specific albums, making them fully public regardless of ownership. This change introduces new smart album types for user-specific ratings and refactors the base query logic to apply these filters consistently across all smart album implementations.
app/SmartAlbums · high confidence
Standalone migration models for database schema changes
The \database/migrations/TemporaryModels\ directory now contains self-contained model classes and helper scripts (such as \TitleSplitter\, \OptimizeTables\, and specific models for \photos\ and \albums\) that are frozen copies of application logic. These ensure that database migrations remain executable in the future without depending on the current application codebase, preventing breakage if the main models or services are refactored or removed.
database/migrations/TemporaryModels · high confidence
Structured exception handling for installation, migration, and environment errors
The application now uses dedicated exception handlers to manage setup and environment issues more gracefully. When the database is inaccessible, the encryption key is missing, or a migration is required, users are automatically redirected to the appropriate setup or migration screens instead of seeing raw error pages. Similarly, if the Vite manifest is missing, a clear instruction to run 'npm run dev' is displayed. This ensures a smoother onboarding experience and clearer feedback during configuration.
app/Exceptions/Handlers · high confidence
Support for ZipStream 2.1 and 3.1 via version-specific traits
The archive service now supports both ZipStream 2.1 and 3.1 by introducing \Zip21Trait\ and \Zip31Trait\. These traits allow the application to dynamically select the appropriate zip creation logic based on the installed \maennchen/zipstream-php\ version, ensuring compatibility across different dependency configurations while maintaining consistent archive generation behavior for users.
app/Services/Archives · high confidence
Tag management now supports albums and respects multi-user ownership
The tag system has been refactored to allow tags to be associated with albums in addition to photos. This change introduces per-user ownership checks for all tag operations: when a non-admin user deletes or merges tags, only the relationships belonging to their own photos and albums are affected, leaving other users' data intact. The tag listing now includes album counts, and retrieving tag details returns both accessible photos and albums, ensuring that users only see content they own or have permission to access.
app/Actions/Tag · high confidence
Unified file handling via new stream-based abstraction layer
The application introduces a new \App\\Image\\Files\ namespace containing a hierarchy of classes (\AbstractBinaryBlob\, \BaseMediaFile\, \FlysystemFile\, \NativeLocalFile\, \UploadedFile\, \DownloadedFile\, \InMemoryBuffer\, and temporary file variants) that standardize how media files are read, written, and moved. This change replaces direct filesystem operations with a unified stream-based API, enabling consistent handling of files across local storage, remote Flysystem disks, and in-memory buffers. Users benefit from improved reliability during file uploads, URL imports, and storage migrations, as the new layer avoids issues related to filesystem permissions, cross-mount-point moves, and temporary file management.
app/Image/Files · high confidence
Update DatabaseSeeder with license headers and modern PHP syntax
The database seeder now includes MIT license and copyright headers, uses the modern \void\ return type declaration, and switches the commented-out example from calling a specific seeder class to using the Laravel factory pattern (\User::factory(10)-\>create()\).
database/seeds · high confidence
Updated HTTP middleware stack and configuration for Laravel 10 compatibility
The application's HTTP kernel has been refactored to align with Laravel 10 standards, replacing the deprecated \routeMiddleware\ array with \middlewareAliases\ and updating global middleware classes (e.g., \CheckForMaintenanceMode\ to \PreventRequestsDuringMaintenance\). This change introduces several new middleware capabilities for users, including Content Security Policy (CSP) management via \SecureHeadersMiddleware\ and \DisableCSP\, stricter content type handling for API and web routes, and new access controls such as \login\_required\ and \unlock\_with\_password\. Additionally, performance monitoring is now available through a \Latency\ middleware in the API group, and legacy ID redirects are handled automatically.
app/Http · high confidence
V3 API resources adopt Struct-of-Arrays response format
The V3 API endpoints for albums, photos, maps, and flows now return data as parallel, index-aligned arrays (Struct-of-Arrays) instead of individual object records. This change applies to resources such as \AlbumListResource\, \PhotoRatioResource\, \MapBucketResource\, and \FlowListResource\, enabling clients to reconstruct lists and trees in a single pass without per-item overhead. The format includes specific fields for album hierarchy, photo metadata, map coordinates, and bulk-edit capabilities, with optional fields omitted entirely when not applicable.
app/Http/Resources/V3 · high confidence
Fixes
Add secure path request validation for image links
A new SecurePathRequest class has been introduced to validate access to secure image paths. This change ensures that requests for these paths are only authorized if either the 'secure\_image\_link\_enabled' or 'temporary\_image\_link\_enabled' configuration option is active, thereby preventing unauthorized access to potentially sensitive image URLs.
app/Http/Requests/SecurePath · high confidence
Structured exception handling for secure link validation
The application now uses specific exception classes within the \App\\Exceptions\\SecurePaths\ namespace to handle errors related to secure links. This includes distinct handling for invalid payloads, invalid signatures, expired signatures, incorrect paths, and path traversal attacks. Notably, path traversal attempts now trigger a specific HTTP 418 (I'm a teapot) response, which supports fail-to-ban honeypot mechanisms, while other validation errors return standard 403 or 404 responses.
app/Exceptions/SecurePaths · high confidence
Test coverage
Added comprehensive test coverage for AI Vision face recognition features; Comprehensive database model factories added for testing.
Dependencies
Major dependency overhaul: Laravel 12, Vue 3, Vite 8, and Tailwind CSS 4
The project has undergone a comprehensive dependency upgrade, migrating the backend from Laravel 5.6 to Laravel 12 (requiring PHP 8.4) and the frontend from Vue 2 to Vue 3. The build system has shifted from Laravel Mix/Webpack to Vite 8, and the styling framework has been upgraded to Tailwind CSS 4. This change also introduces new libraries for payment processing (Stripe, PayPal, Mollie), authentication (WebAuthn, various Socialite providers), and image handling, while removing older dependencies like Laravel Mix and Bootstrap.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 41.
Lenses
- Code Health 84
- Architecture 72
- Maturity 70
- Readiness 29
- Security 71
- Domain Modelling 55
- Accessibility 37
Changes since last survey
- 300 commits — 253 feature/other, 47 fixes
By area
- (root) — 105 commits
- resources/js — 80 commits
- app/Http — 23 commits
- .github/workflows — 20 commits
- docs/specs — 13 commits
- app/Actions — 11 commits
- database/migrations — 6 commits
- lang/ar — 5 commits
- lang/es — 4 commits
- lang/de — 3 commits
- app/Image — 2 commits
- app/Policies — 2 commits
- lang/fr — 2 commits
- tests/AssistedVision — 2 commits
- tests/Unit — 2 commits
- (repo) — 1 commit
- app/Console — 1 commit
- app/Enum — 1 commit
- app/Exceptions — 1 commit
- app/Jobs — 1 commit
Notable commits
- fix: (fix): do not display the warning-misconfiguration.blade.php (#4641)
- fix: AWS crash fix (#4668)
- fix: Add filtering & fix bug when deleting a person. (#4467)
- fix: Fix LinuxServer.io base path (though, they should fix their env) (#4589)
- fix: Fix Sqlite bug (#4516)
- fix: Fix access rights (#4580)
- fix: Fix broken UI on v8 (#4638)
- fix: Fix browser tab title getting stuck on a photo's filename (#4758)
- fix: Fix caching issue on tree global update (#4619)
- fix: Fix cves by updating dependencies (#4737)
- fix: Fix display in non-timeline mode (#4738)
- fix: Fix dock on smart album (#4741)
- fix: Fix download bypass on password protected albums (#4459)
- fix: Fix dummy validation when processing requests (#4507)
- fix: Fix folder multi processing (#4736)
- fix: Fix hidden albums leaking via "present in albums" list (#4387)
- fix: Fix inheritance issue on album creation (#4563)
- fix: Fix language (#4757)
- fix: Fix map display being broken (#4753)
- fix: Fix mb strings for our chinese users (#4415)
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
LycheeOrg/Lychee was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 21ca3a485e7b29fa90a3fd3d85727ddcc8ae9908 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.