# Performance optimisation — Stage 2 runtime report

Completed 2026-08-15. Stage 1 query and index improvements were preserved.

## 1. Laravel runtime bottlenecks fixed

- Removed routine global cache clears from settings, product, SEO, and link-update workflows.
- Removed per-request SEO table schema checks by caching table availability for one hour.
- Removed the per-boot informational log and full order-model log payload from the order mail provider.
- Removed a destructive public debug route that prevented route caching.

## 2. Cache strategy implemented

`App\Support\StorefrontCache` owns public, stable data keys:

- `settings:{key}` and `uploads:{id}`
- `navigation:category-menu`
- `catalog:selectable-categories`, `catalog:selectable-published-products`, `catalog:brands`, and `catalog:category:{id}:filters`
- `homepage:sections` and `homepage:section:{id}:products`
- `seo:canonicals` and `seo:redirects`

Navigation, selectable catalogue data, brands, category filters, and homepage definitions are cached for one hour. Homepage product collections remain at 15 minutes. Settings, uploads, and SEO maps are cached indefinitely only because they have explicit invalidation. Cart, checkout, authentication, and customer data are not cached.

## 3. Cache invalidation rules

- Settings and uploads invalidate their individual keys on save/delete.
- Menu, category, brand, product, and homepage-section changes invalidate only their related public catalogue/homepage keys.
- A product invalidates its own category-filter keys and only homepage sections containing that product.
- Category and brand changes invalidate homepage sections containing affected products.
- SEO canonical/redirect model changes invalidate their own maps.

Focused tests confirm settings invalidation leaves unrelated keys intact and a homepage-section change leaves other section-product caches intact.

## 4. Homepage optimisations

- Moved homepage section/product data loading out of Blade and into the Livewire component plus cache service.
- Removed the unused public search result/model collection from the homepage component.
- Reused cached section definitions and section-product collections without serialising them as public Livewire properties.

## 5. Helper and view refactors

- Moved `app/Helpers.php` into Composer production autoload and replaced runtime `env()` reads with configuration values.
- Replaced direct Blade database calls in the admin sidebar, category filters, and product edit form with controller/component/view-composer data.
- Product-edit attribute values are fetched in one grouped query rather than per-attribute queries.

## 6. Queue changes

- Customer order mail, contact mail, admin order mail, SMS, and sitemap refresh are queueable.
- Sitemap refresh now runs through a unique queued job instead of synchronously on normal model saves.
- Order writes remain inside their existing database transactions; notifications dispatch only after commit.
- `QUEUE_CONNECTION=sync` remains the safe current fallback. To use workers in production, set `QUEUE_CONNECTION=database` (or Redis where installed) and run:

```text
php artisan queue:work database --queue=default,sms --tries=3 --timeout=90
```

## 7. Session changes

No session model payloads or large session structures were found. The existing file-session driver remains compatible with shared hosting; cart/session data remains request scoped.

## 8. Logging changes

- Production `LOG_LEVEL` is now `warning`; the default logging fallback is also `warning`.
- Kept error/warning logs for delivery and checkout failures.
- Removed routine informational mail-provider logs and capped logged SMS error response bodies at 1,000 characters.

## 9. Composer changes

- Moved `livewire/livewire` from `require-dev` to `require`; it is required by storefront runtime routes.
- Updated only lock metadata; package versions did not change.
- `composer dump-autoload -o` and a `composer install --no-dev --optimize-autoloader --dry-run` both completed successfully. The no-dev simulation keeps Livewire and removes only development packages.
- No dependencies were removed. Composer still warns that `jenssegers/agent` has an unbounded version constraint and that legacy duplicate files are skipped by PSR-4; these were not changed in Stage 2.

## 10. Configuration changes

- Added configurable `QUEUE_AFTER_COMMIT` behavior and enabled it in this production environment.
- Added importer credentials to `config/services.php` and removed all runtime `env()` calls from application code.
- Fixed route-cache blockers by replacing the API closure with an invokable controller and removing the obsolete destructive debug route.

## 11. Principal files changed

- `app/Support/StorefrontCache.php`, `app/Providers/AppServiceProvider.php`, and `app/Jobs/RefreshSitemap.php`
- Homepage/category/header Livewire components and their Blade views
- Backend settings, SEO, media, product, home-section, and menu code
- Queueable mail classes, checkout/cart/contact flows, and the order mail provider
- `routes/web.php`, `routes/api.php`, Composer/config/environment files, and focused tests

## 12–13. Tests executed and results

- `php artisan optimize:clear`, `config:cache`, `route:cache`, and `view:cache` — all passed.
- `composer dump-autoload -o` — passed.
- `composer install --no-dev --optimize-autoloader --dry-run` — passed.
- `php artisan test` — 6 tests passed, 13 assertions.
- HTTP checks with production caches: homepage, shop, product, category, login, and cart returned 200.
- Authenticated kernel checks: `/admin`, `/admin/products`, `/admin/order`, `/admin/settings/system`, and product edit returned 200.

Checkout redirected to cart as expected because this local database has no cart/customer fixture. No orders or customer data were created for testing.

## 14. Deliberately postponed to Stage 3

- Browser-side asset, image, and JavaScript optimisation.
- Load/concurrency testing with production-like catalogue, customer, cart, and order data.
- Dependency version upgrades/security remediation (the targeted lock refresh exposed existing Laravel security-advisory blocks; no broad dependency update was performed).
- Review/removal of legacy duplicate PHP files and the unbounded `jenssegers/agent` constraint after a dedicated compatibility audit.
