diff --git a/Work/Projects/.DS_Store b/Work/Projects/.DS_Store new file mode 100644 index 0000000..20373f8 Binary files /dev/null and b/Work/Projects/.DS_Store differ diff --git a/Work/Projects/Laravel-v12-Migration/UPDATE_LOG-contentmakers.md b/Work/Projects/Laravel-v12-Migration/UPDATE_LOG-contentmakers.md new file mode 100644 index 0000000..0339bd3 --- /dev/null +++ b/Work/Projects/Laravel-v12-Migration/UPDATE_LOG-contentmakers.md @@ -0,0 +1,538 @@ +# Update Log + +## Run Metadata + +- Date: 2026-02-10 +- Started: 2026-02-10 12:36:36 CET +- Branch: `upgrade/laravel12-filament5-full` +- Goal: Laravel 12 + full ecosystem upgrades (Composer and npm), including Filament v3 -> v4 -> v5, while skipping + ESLint major upgrades. + +## Preflight Snapshot + +### Environment + +- PHP: `8.4.17` +- Composer: `2.8.5` +- Node: `v20.19.6` +- npm: `11.6.4` + +### Composer Outdated (Direct) + +- Laravel major target available: `laravel/framework 11.46.1 -> 12.50.0`. +- Filament major target available: `filament/filament 3.3.45 -> 5.2.0`. +- Inertia Laravel major target available: `1.3.3 -> 2.0.19`. +- Ziggy major target available: `1.8.2 -> 2.6.0`. +- Multiple ecosystem majors available (Filament plugins, DOMPDF, Mollie, Pest stack, Symfony components, Resend). + +### Laravel 12 Blocker Check (`composer why-not laravel/framework ^12 -t`) + +- Hard blockers detected: + - `codezero/laravel-localized-routes:^4` (supports only Illuminate 10/11). + - `codezero/laravel-localizer:^3` (supports only Illuminate 10/11). + - `codezero/laravel-uri-translator:^2` (transitive, supports only Illuminate 10/11). + - `resend/resend-laravel:^0.14` (supports only Illuminate 10/11). + - `laravel-lang` current line (`lang:^12`, `common:^3`) anchored to publisher line that supports only Illuminate < + =11. + +### npm Outdated Snapshot + +- Major targets available: + - `@inertiajs/vue3 1.3.0 -> 2.3.13` + - `tailwindcss 3.4.18 -> 4.1.18` + - `laravel-vite-plugin 1.3.0 -> 2.1.0` + - `vite 6.4.1 -> 7.3.1` + - `@vitejs/plugin-vue 5.2.4 -> 6.0.4` + - `pinia 2.3.1 -> 3.0.4` + - `swiper 10.3.1 -> 12.1.0` + - `vue-i18n 10.0.8 -> 11.2.8` +- ESLint majors are available but intentionally skipped in this run. + +### Baseline Verification + +- `php artisan test --compact`: `14 passed`, no failures. +- Warnings: PHPUnit doc-comment metadata deprecations (will break in PHPUnit 12 timeframe). +- `npm run build`: build succeeds. +- Warning: `baseline-browser-mapping` database is older than two months. + +## Package Blockers + +- `codezero/laravel-localizer` removed per decision (no Laravel 12 support). +- `codezero/laravel-localized-routes` replaced by `opgginc/codezero-laravel-localized-routes` (Laravel 12 support). +- `resend/resend-laravel` must move to `^1.0`. +- `laravel-lang/lang` and `laravel-lang/common` must move to newer major lines compatible with Laravel 12. + +## Exceptions & Weirdness + +1. **Stale package/service manifests after Composer package changes** + - Symptom: runtime errors for removed/moved service providers (for example debugbar, old localizer, filament-upgrade + provider references). + - Failing commands: `php artisan ...` commands after `composer update --no-scripts`. + - Root cause: stale `bootstrap/cache/packages.php` and `bootstrap/cache/services.php`. + - Exact fix: delete both files and re-run `composer dump-autoload` / package discovery. + - Preventive rule: clear both manifest files after major package removals/replacements. + +2. **Localized route transition edge case (`Attribute [localized] does not exist`)** + - Symptom: route boot failure during transition from abandoned CodeZero packages to OPGG fork. + - Root cause: cached package manifests + package transition timing. + - Exact fix: same manifest clear as above, then rerun discovery. + +3. **Ziggy v2 client dependency gap** + - Symptom: Vite build failed with `Rollup failed to resolve import "qs-esm"` from + `vendor/tightenco/ziggy/src/js/Route.js`. + - Failing command: `npm run build`. + - Root cause: Ziggy v2 JS source now imports `qs-esm`, not present in project npm deps. + - Exact fix: `npm install qs-esm`. + - Preventive rule: after Ziggy major upgrades, run a full build immediately and verify vendor JS imports. + +4. **PHPUnit 12 test discovery change reduced executed test count (14 -> 3)** + - Symptom: only methods named `test_*` executed; legacy `/** @test */` methods were skipped. + - Failing command: `php artisan test --compact` (unexpected low count). + - Root cause: metadata annotation behavior changed in PHPUnit 12 line. + - Exact fix: migrate `/** @test */` methods to `#[Test]` attributes in affected class-based tests. + - Preventive rule: include a test-count sanity check after PHPUnit major upgrades. + +5. **Hidden regression surfaced after restoring full test discovery** + - Symptom: `Call to undefined function get_classes_in_namespace()` in sitemap generation test. + - Failing command: `php artisan test --compact`. + - Root cause: helper function no longer provided by dependencies after package upgrades. + - Exact fix: added local `get_classes_in_namespace()` implementation to `app/helpers.php`. + - Preventive rule: once discovery is fixed, rerun full suite and treat newly exposed failures as real upgrade + regressions. + +6. **Pint interaction with PHPUnit setup visibility** + - Symptom: `setUp()` visibility conflict (`must be public`) after formatting pass. + - Failing command: `php artisan test --compact`. + - Root cause: formatter rule normalized setup method visibility in a way that conflicted with this TestCase chain. + - Exact fix: remove no-op `setUp()` overrides from affected tests. + - Preventive rule: rerun tests after Pint in upgrade branches, not just before Pint. + +7. **npm package location warning due duplicate entries** + - Symptom: npm warned about removing duplicated packages from `dependencies` in favor of `devDependencies`. + - Root cause: same frontend build packages declared in both sections. + - Exact fix: npm normalized entries during install (kept in `devDependencies`). + - Preventive rule: avoid duplicating build-only packages across both dependency sections. + +8. **Build warning persisted (non-blocking)** + - Symptom: `[baseline-browser-mapping] ... over two months old` and generated empty chunks in Vite output. + - Impact: build still successful. + - Action: log-only. + +9. **Filament v5 codemod scope gap caused delayed runtime failures** + - Symptom: project appeared upgraded, but frontend routes later crashed with missing Filament classes in `cms/*` and + `commerce/*`. + - Root cause: initial codemod pass was executed for `app/` and `modules/` only, leaving other custom source roots + untouched. + - Exact fix: run a second migration pass over all custom roots and then verify class existence across repository + imports. + - Preventive rule: always enumerate all custom source roots before running Filament codemods (`app`, `modules`, + `cms`, `commerce`, `support`, etc.). + +10. **`vendor/bin/filament-v5` can print Rector cache deletion errors but still exit successfully** + +- Symptom: commands like `vendor/bin/filament-v5 cms` and `vendor/bin/filament-v5 commerce` reported + `Unable to delete ... rector_cached_files ... No such file or directory`, yet finished with success messaging. +- Impact: misleading signal that migration completed for target directory. +- Exact fix: do not trust command success text alone; run a post-codemod class-import existence scan and targeted + runtime smoke checks. +- Preventive rule: treat codemod output warnings as potential partial-failure even with zero exit code. + +11. **Filament v5 namespace migration gaps (schemas vs forms)** + +- Symptom: `Class "Filament\\Forms\\Components\\Fieldset" not found` on runtime page render. +- Root cause: layout/util classes moved to `Filament\\Schemas\\...` but legacy imports remained in + `cms/Filament/Form/*`. +- Exact fix: migrate imports: + - `Filament\\Forms\\Components\\Fieldset` -> `Filament\\Schemas\\Components\\Fieldset` + - `Filament\\Forms\\Components\\Grid` -> `Filament\\Schemas\\Components\\Grid` + - `Filament\\Forms\\Components\\Component` -> `Filament\\Schemas\\Components\\Component` + - `Filament\\Forms\\Get|Set` -> `Filament\\Schemas\\Components\\Utilities\\Get|Set` + - `Filament\\Forms\\Components\\Tabs\\Tab` -> `Filament\\Schemas\\Components\\Tabs\\Tab` + - `Filament\\Forms\\Components\\Section` -> `Filament\\Schemas\\Components\\Section` +- Preventive rule: after each major Filament upgrade, scan for old + `Filament\\Forms\\Components\\(Fieldset|Grid|Section|Tabs\\Tab)` and `Filament\\Forms\\Get|Set`. + +12. **Filament page actions namespace changed** + +- Symptom: commerce resource page classes still imported `Filament\\Pages\\Actions`. +- Root cause: missed codemod transformations in specific folders. +- Exact fix: replace with `use Filament\\Actions;` and keep `Actions\\*Action::make()` calls. +- Preventive rule: grep for `use Filament\\Pages\\Actions;` after v5 migration and replace all matches. + +13. **Resource/relation manager form signature drift** + +- Symptom: files still used `Filament\\Forms\\Form` type and `form(Form $form): Form` signatures. +- Root cause: partial codemod application in commerce resources. +- Exact fix: update to Filament v5 schema signature: + - Resources: `public static function form(Schema $schema): Schema` + - Relation managers: `public function form(Schema $schema): Schema` +- Preventive rule: grep for `use Filament\\Forms\\Form;` and remove all remaining occurrences. + +14. **`TextInput\\Mask` builder class no longer available in current Filament line** + +- Symptom: legacy closures typed as `Forms\\Components\\TextInput\\Mask` became invalid and future runtime failures were + likely. +- Root cause: legacy mask builder API from older Filament line. +- Exact fix: replaced with v5-safe numeric/step/prefix configuration instead of removed mask-builder typehints. +- Preventive rule: grep for `TextInput\\Mask` and rewrite masks using current v5 text input API. + +15. **Running the official Filament upgrade utility can generate a large public-asset diff** + +- Symptom: `php artisan filament:upgrade --no-interaction` republished many files under `public/js/filament/*`, + `public/css/filament/*`, and `public/fonts/filament/*`, then cleared config/route/view caches. +- Impact: noisy git diff and potential overwrite risk for locally customized published Filament assets. +- Exact fix: run this command intentionally once per upgrade pass, then review/commit asset churn separately and rerun + verification (`pint`, tests, build). +- Preventive rule: announce this side effect before execution and avoid running it repeatedly without need. + +16. **`route:list` can throw due controller-constructor abort guards** + +- Symptom: `php artisan route:list --path=admin` failed with + `Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException` originating from + `App\\Http\\Controllers\\Public\\VacancyController::__construct()` line 16. +- Root cause: constructor contains `abort_unless(..., 404)` and the route-list command instantiates controllers during + route metadata collection. +- Exact fix: use `php artisan about` + tests/build for upgrade smoke checks when this occurs. Long-term refactor: move + hard feature gates out of constructors into middleware/action-level guards. +- Preventive rule: avoid hard `abort_*` calls in controller constructors. + +17. **npm dependency graph got stuck during ESLint major migration** + +- Symptom: repeated `npm install` attempts failed with `ERESOLVE could not resolve` while moving `eslint-plugin-vue` to + `^10` and `vue-eslint-parser` to `^10`. +- Root cause: stale lock/tree state from earlier duplicated dependency declarations caused resolver deadlock. +- Exact fix: regenerate the npm install tree cleanly (fresh `node_modules` and lock regeneration), then install the + target dependency set. +- Preventive rule: when npm repeatedly fails with the same peer conflict after package.json corrections, do a clean + dependency graph rebuild instead of retry loops. + +18. **`eslint-plugin-vue` v10 required ESLint flat config migration** + +- Symptom: linting failed with legacy config errors (`plugin:vue/vue3-recommended` not found / invalid config shape with + `default` key). +- Root cause: newer Vue ESLint plugin line expects modern flat-config flow; legacy `.eslintrc` extends become + incompatible. +- Exact fix: add `eslint.config.cjs` and migrate rules/plugins there; keep eslint on v9. +- Preventive rule: treat ESLint plugin major upgrades as config-schema migrations, not package-only updates. + +19. **Tailwind v4 upgrader refuses dirty git state by default** + +- Symptom: `npx @tailwindcss/upgrade` aborted with “Git directory is not clean”. +- Exact fix: run with `--force` on controlled upgrade branches. + +20. **Tailwind upgrader scanned backup directories and failed config linking** + +- Symptom: upgrader reported it could not determine config for CSS files in `node_modules.bak` and + `resources/css/app.css`. +- Root cause: backup dependency folder was inside repository tree and stylesheet had no explicit config link. +- Exact fix: move backup folder outside repo and run upgrader with `-c tailwind.config.js`. + +21. **Tailwind upgrader failed to load custom config due legacy helper signature** + +- Symptom: `Cannot destructure property 'negative' of 'undefined'`. +- Root cause: custom `inset: (theme, { negative }) => ...` pattern from older Tailwind config API. +- Exact fix: replace with explicit negative-spacing generation helper that only depends on `theme('spacing')`. + +22. **Tailwind template migration failed on `@apply` of custom class** + +- Symptom: `Cannot apply unknown utility class 'pl-container'`. +- Root cause: `@apply` referenced custom class aliases instead of raw utilities in `resources/css/utility.css`. +- Exact fix: expand `.container` rule to raw utility set (`pl-8 lg:pl-32 pr-8 lg:pr-32`) and rerun upgrader. + +23. **Tailwind v4 PostCSS plugin package split** + +- Symptom: Vite build failed with “trying to use `tailwindcss` directly as a PostCSS plugin”. +- Root cause: Tailwind v4 moved PostCSS integration to `@tailwindcss/postcss`. +- Exact fix: install `@tailwindcss/postcss` and update `postcss.config.js` plugin key. + +24. **`eslint-plugin-tailwindcss` is not Tailwind v4 compatible** + +- Symptom: linting failed with `ERR_PACKAGE_PATH_NOT_EXPORTED` for `tailwindcss/resolveConfig`. +- Root cause: current plugin line peers against Tailwind `^3.4.0` only. +- Exact fix: remove `eslint-plugin-tailwindcss` integration from active lint config during Tailwind v4 migration. + +25. **Clean npm install exposed missing direct dependency (`lodash`)** + +- Symptom: Vite build failed resolving `lodash` imported by `resources/js/utilities.js`. +- Root cause: package was previously present transitively in old lock state but not declared directly. +- Exact fix: add `lodash` as direct dependency. +- Preventive rule: after lock regeneration, treat unresolved imports as missing direct dependency declarations and fix + explicitly. + +26. **Filament schema traversal can access uninitialized component container** + +- Symptom: runtime crash + `Typed property Filament\\Schemas\\Components\\Component::$container must not be accessed before initialization` while + resolving block schema metadata. +- Root cause: direct child-component traversal (`getChildComponents()`/`getName()`) can touch component internals before + Livewire/Filament container initialization. +- Exact fix: in `cms/Filament/Blocks/Block.php`, resolve protected `childComponents` via reflection, treat closure child + schemas as empty in non-Livewire context, and guard `getName()` with `Throwable` fallback to recursive traversal. +- Preventive rule: when extracting schema metadata outside a mounted form lifecycle, avoid direct `getChildComponents()` + assumptions and handle closure-based schema definitions safely. + +## Command Transcript (Key Commands) + +1. `COMPOSER_CACHE_DIR=/tmp/composer-cache composer outdated --direct --format=json` +2. `composer why-not laravel/framework ^12 -t` +3. Multiple Composer major updates (Laravel/Filament ecosystem, plugin replacements, package removals) +4. `npm outdated --json` +5. `npm update` +6. + +`npm install @inertiajs/vue3@^2 @vitejs/plugin-vue@^6 laravel-vite-plugin@^2 vite@^7 @vueuse/core@^14 swiper@^12 vue-i18n@^11 pinia@^3 imagetools-core@^9 vite-imagetools@^9 @formkit/auto-animate@^0.9 @gtm-support/vue-gtm@^3` + +7. `npm install uuid@^13` +8. `npm install qs-esm` +9. `php artisan test --compact` +10. `vendor/bin/pint --dirty` +11. `npm run build` +12. `vendor/bin/filament-v5 cms` +13. `vendor/bin/filament-v5 commerce` +14. `vendor/bin/filament-v5 support` +15. Repository-wide Filament import existence scan against Composer autoload +16. `php artisan tinker --execute="Cms\\Filament\\Form\\Fieldset\\ImageForBlock::make('image'); echo 'ok';"` +17. `php artisan filament:upgrade --no-interaction` +18. `vendor/bin/pint --dirty` +19. `php artisan test --compact` +20. `npm run build` +21. `composer outdated --direct --format=json` +22. `npm outdated --json` +23. `php artisan route:list --path=admin` (fails due constructor abort; see exception #16) +24. `php artisan about` +25. + +`npm pkg delete dependencies.@typescript-eslint/eslint-plugin dependencies.eslint-plugin-unused-imports dependencies.eslint-plugin-vue` + +26. npm dependency graph regeneration for ESLint package upgrades +27. Added flat ESLint config (`eslint.config.cjs`) and migrated rules from `.eslintrc.json` +28. `npx @tailwindcss/upgrade --force -c tailwind.config.js` +29. `npm install -D @tailwindcss/postcss` +30. `npm install lodash` +31. Verification reruns: `npx eslint ...`, `npm run build`, `php artisan test --compact`, + `composer outdated --direct --format=json`, `npm outdated --json` +32. `php artisan test tests/Feature/Cms/Blocks/BlockSchemaTest.php --compact` +33. Added regression coverage in `tests/Feature/Cms/Blocks/BlockSchemaTest.php` + +## npm Final State + +### Upgraded majors completed in this pass + +- `@inertiajs/vue3` -> `^2.3.13` +- `@vitejs/plugin-vue` -> `^6.0.4` +- `laravel-vite-plugin` -> `^2.1.0` +- `vite` -> `^7.3.1` +- `@vueuse/core` -> `^14.2.1` +- `pinia` -> `^3.0.4` +- `swiper` -> `^12.1.0` +- `vue-i18n` -> `^11.2.8` +- `imagetools-core` -> `^9.1.0` +- `vite-imagetools` -> `^9.0.2` +- `@formkit/auto-animate` -> `^0.9.0` +- `@gtm-support/vue-gtm` -> `^3.1.0` +- `uuid` -> `^13.0.0` +- `qs-esm` added for Ziggy v2 compatibility +- `tailwindcss` -> `^4.1.18` +- `@tailwindcss/postcss` added for Tailwind v4 PostCSS integration +- `@typescript-eslint/eslint-plugin` -> `^8.55.0` +- `@typescript-eslint/parser` -> `^8.55.0` +- `eslint-plugin-unused-imports` -> `^4.4.1` +- `eslint-plugin-vue` -> `^10.7.0` +- ESLint migrated to flat config with `eslint` `^9.39.2` +- `lodash` added as explicit direct dependency + +### Remaining npm outdated entries + +- `eslint` `9.39.2 -> 10.0.0` (left intentionally due current `@typescript-eslint` v8 peer range support targeting + eslint 8/9) + +## Post-Upgrade Verification + +- `composer outdated --direct --format=json`: no direct outdated packages (`"installed": []`). +- `php artisan test --compact`: `16 passed (28 assertions)` (includes new block schema regression coverage). +- `npm run build`: successful client + SSR build on Vite 7. +- `vendor/bin/pint --dirty`: passes after fixups. +- `php artisan filament:upgrade --no-interaction`: succeeds and republishes Filament assets/caches. +- `php artisan route:list --path=admin`: fails because a constructor-level abort is triggered (documented in exception + #16). +- `npx eslint resources/js/app.js resources/js/ssr.js`: passes with flat ESLint config. + +## Historical Lessons (From Earlier Upgrade Logs) + +- Source consulted: `UPGRADE-LOG-CLEANSHOPPING.md`. +- Stale `bootstrap/cache/packages.php` and `bootstrap/cache/services.php` can retain removed service providers after + package changes. +- Filament major upgrades can require running upgrade tooling for custom roots (`app/` and `modules/`). +- Filament upgrade scripts may miss manual fixes; always run targeted grep and tests after codemods. +- Tailwind major migrations can fail with advanced config/plugin patterns; run as a dedicated pass. +- Filament codemod success output is not sufficient validation: cross-check every custom code root and run class-import + existence scans. + +## Reusable Rules + +- Keep this file as the canonical `UPDATE_LOG` for each future upgrade pass. +- For each exception, always record: + - Symptom + - Failing command + - Root cause + - Exact fix + - Preventive rule + +## Pending TODOs + +1. **Migrate remaining PHPUnit-style tests to idiomatic Pest tests** + - Reference guide: `https://pestphp.com/docs/migrating-from-phpunit-guide` + - Scope: convert class-based PHPUnit style tests (`tests/Feature/*`, `tests/Unit/*`) to Pest `it()` style where + practical. + - Keep/validate safety guard before every migration test run: `tests/TestCase.php` must enforce in-memory sqlite ( + `database.default=sqlite` and `database.connections.sqlite.database=:memory:`) to prevent accidental writes to + non-test databases. + +## Session Notes — 2026-02-10 (Browser Testing Bootstrap) + +1. **Composer dev-package install can rerun Filament upgrade hooks** + - Symptom: installing browser-test dependencies triggered `php artisan filament:upgrade` via Composer scripts, + republishing Filament assets and clearing caches. + - Failing command: `composer require pestphp/pest-plugin-browser --dev --no-interaction`. + - Root cause: project-level `post-update-cmd` in `composer.json` always runs `@php artisan filament:upgrade`. + - Exact fix: treat as expected side effect and avoid repeated Composer writes when not needed. + - Preventive rule: on upgrade branches, assume Composer package changes may create large Filament asset diffs. + +2. **Pest browser tests need Playwright runtime setup in addition to npm package install** + - Symptom: browser tests can fail on clean machines if Playwright browser binaries are not installed. + - Failing command: `./vendor/bin/pest tests/Browser/...` before Playwright install. + - Root cause: installing `playwright` npm package does not guarantee browser binaries are present. + - Exact fix: run `npx playwright install` (or `npx playwright install chromium`) after dependency install. + - Preventive rule: include Playwright browser install in local + CI bootstrap for browser test suites. + +3. **Pest v4 browser tests conflict with `public setUp()` in custom TestCase** + - Symptom: fatal error + `Access level to Pest\Concerns\Testable::setUp() must be public (as in class Tests\TestCase)`. + - Failing command: `./vendor/bin/pest tests/Browser/PageBrowserTest.php`. + - Root cause: `tests/TestCase.php` used `public function setUp()`, which conflicts with Pest's trait method + visibility expectations. + - Exact fix: change `tests/TestCase.php` `setUp()` visibility to `protected`. + - Preventive rule: keep custom `setUp()` visibility aligned with Laravel/PHPUnit defaults (`protected`) for Pest + compatibility. + +4. **Browser title assertions can be empty on Inertia pages during early render** + - Symptom: browser test failed with `Expected page title ... but found ''` on a valid Inertia route. + - Failing command: `./vendor/bin/pest tests/Browser/PageBrowserTest.php`. + - Root cause: in this stack, `` can be empty at initial render timing while the page payload is already + present. + - Exact fix: assert against rendered source payload (`assertSourceHas(...)`) plus smoke assertions instead of strict + immediate title assertion. + - Preventive rule: for Inertia browser tests, prefer stable assertions (`assertSourceHas`, `assertSee`, + `assertNoSmoke`) over immediate `<title>` checks unless waiting for a client-side update. + +5. **Block settings detection can still trigger uninitialized Filament container access** + - Symptom: browser request crashed with + `Typed property Filament\\Schemas\\Components\\Component::$container must not be accessed before initialization`. + - Failing path: `Cms\\Filament\\Blocks\\Block::hasSettings()` calling `getSettings()->getChildComponents()` during + content arraying. + - Root cause: `hasSettings()` used a direct child-component accessor that requires a mounted container, even in + non-Livewire rendering. + - Exact fix: change `hasSettings()` to use the safe `getSchemaChildComponents()` resolver and treat closure schemas + as non-resolvable (`false`) in this context. + - Preventive rule: in backend-only schema introspection, avoid direct `getChildComponents()` calls and rely on + guarded reflection/fallback accessors. + +6. **Pest browser `assertSee()` can fail on non-SSR Inertia pages** + - Symptom: browser test did not find seeded text as visible DOM text even though the route and payload were correct. + - Failing assertion: `assertSee('Browser Seed Content')`. + - Root cause: this page flow is client-rendered Inertia; text is present in response payload/source before + hydration, not necessarily as immediate visible server-rendered DOM. + - Exact fix: use `assertSourceHas(...)` for payload-level assertions plus route/smoke assertions. + - Preventive rule: for non-SSR Inertia browser tests, prefer `assertSourceHas` over immediate `assertSee` unless + explicitly waiting for frontend hydration. + +## Session Notes — 2026-02-10 (Remaining Update Pass) + +1. **Final direct Composer updates are complete** + - Action: upgraded remaining direct outdated packages (`filament/filament`, + `filament/spatie-laravel-media-library-plugin`, `filament/spatie-laravel-settings-plugin`, `filament/upgrade`) + from `5.2.0` to `5.2.1`. + - Verification: `composer outdated --direct --format=json` now returns `"installed": []`. + +2. **Composer update still triggers Filament asset republish side effects** + - Symptom: `composer update ...` executed `post-update-cmd` and reran `php artisan filament:upgrade`, republishing + `public/js/filament/*`, `public/css/filament/*`, and font assets. + - Impact: expected large public asset churn in git diff. + - Preventive rule: keep Filament public-asset changes grouped and reviewed separately when running Composer updates. + +3. **npm is fully up to date except ESLint major** + - Action: ran `npm update` and refreshed lockfile. + - Result: only `eslint` remains in `npm outdated` (`9.39.2 -> 10.0.0`). + - Decision: keep on ESLint 9 for this pass to avoid forced major migration risk while finishing framework/package + updates. + +4. **Build + tests remain green after patch pass** + - `npm run build`: successful (client + SSR). + - `php artisan test --compact`: `16 passed (28 assertions)`. + - `./vendor/bin/pest tests/Browser/PageBrowserTest.php`: passes. + - `php artisan test tests/Feature/Cms/Blocks/BlockSchemaTest.php --compact`: passes. + - `vendor/bin/pint --dirty`: passes. + +5. **Tailwind v4 can silently reintroduce core `.container` and override custom layout containers** + - Symptom: major frontend layout degradation after upgrade (page spacing/width looked "missing CSS" across many + pages). + - Root cause: Tailwind v4 no longer supports `corePlugins.container = false` from JS config in active CSS-first + mode; the core `.container` utility was generated and overrode project custom `.container`. + - Exact fix: in `resources/css/app.css`, add `@source not inline('container');` (and + `@source not inline('container!');`) to prevent Tailwind from generating the core container utility, keeping the + custom `.container` from `resources/css/utility.css` as the only definition. + - Verification: built CSS now contains only the custom `.container` rule (`grep -o '\\.container{' ... | wc -l` = + `2` from base + media rule), browser + schema tests pass. + - Preventive rule: after Tailwind major upgrades, always diff/check compiled `.container` output when projects + define their own container class name. + +6. **Tailwind v4 does not require `tailwind.config.js`, but compatibility file can remain accidentally** + - Symptom: repository still had `tailwind.config.js` after migration, creating ambiguity about active config source. + - Root cause: Tailwind v4 uses CSS-first config; JS config is compatibility-only and not auto-loaded unless + `@config` is explicitly used. + - Exact fix: remove unused `tailwind.config.js` when fully migrated to CSS directives and no tooling references + remain. + - Preventive rule: after v4 migration, run a repo-wide search for `@config` and `tailwind.config.js` references; if + none exist, remove stale config files to avoid future confusion. + +## Tailwind Upgrade Workflow Directive (Authoritative) + +1. **Always run the Tailwind upgrade utility first** + - Required default path: use the official updater before doing manual migrations. + +2. **If the upgrade utility errors, resolve blockers and rerun the utility** + - Do not switch to a manual full migration as first fallback. + - Iterate: fix error -> rerun updater -> repeat until updater succeeds. + +3. **If custom classes block the updater, temporarily comment them out** + - Typical case: custom utility/class patterns causing updater parse/apply failures. + - Workflow: comment problematic custom classes -> run updater -> reapply custom classes after successful upgrade. + +4. **Manual edits are only for unblocking/reapplying around the updater** + - Manual work should support the upgrader workflow, not replace it. + +5. **Unpack all custom classes before running Tailwind upgrades** + - Rule: do not keep "custom class inside custom class" patterns (for example, a custom class that `@apply`s another + custom class). + - Required approach: expand nested custom-class usage to raw utility classes first, then run the upgrader. + - After upgrade: keep this flattened structure; avoid reintroducing custom-class-in-custom-class composition. + - Verification snapshot (2026-02-10): repository-wide `@apply` scan found only raw utility usage in + `resources/css/app.css`; no custom-class tokens were referenced inside other custom classes. + +6. **Blade-injected runtime colors require `@theme inline` in Tailwind v4** + - Symptom: color utilities tied to runtime CSS variables from `resources/views/app.blade.php` behaved inconsistently + after migration. + - Root cause: theme tokens in `resources/css/app.css` referenced runtime vars (`var(--primary-color)` etc.) using + plain `@theme` instead of v4's recommended `@theme inline` for variable references. + - Exact fix: switch to `@theme inline` for color tokens and ensure every referenced token exists. + - Verification snapshot (2026-02-10): compiled CSS now emits `.bg-primary{background-color:var(--primary-color)}` + and `.from-primary-medium{...var(--primary-color)...}`. + - Preventive rule: when colors are injected at runtime (Blade/style attributes), define Tailwind color tokens with + `@theme inline`. + +7. **Missing theme token prevents utility generation (`from-primary-medium`)** + - Symptom: `from-primary-medium` class in `resources/js/Components/Header.vue` had no compiled CSS. + - Root cause: no `--color-primary-medium` token existed in the Tailwind theme namespace. + - Exact fix: add `--color-primary-medium` mapping in the `@theme inline` block (`resources/css/app.css`). + - Preventive rule: after migration, grep for custom color utility names and verify each has a corresponding + `--color-*` theme variable. diff --git a/Work/Projects/Laravel-v12-Migration/UPGRADE-LOG-CLEANSHOPPING.md b/Work/Projects/Laravel-v12-Migration/UPGRADE-LOG-CLEANSHOPPING.md new file mode 100644 index 0000000..1d1a556 --- /dev/null +++ b/Work/Projects/Laravel-v12-Migration/UPGRADE-LOG-CLEANSHOPPING.md @@ -0,0 +1,406 @@ +# Upgrade Log: Laravel 11 → 12 + Ecosystem + +## Prompt + +Hi, we are going to update to the next version of Laravel And updates everything that goes along with it. so please run +`composer outdated`. Gather all the resources you need to do the updates and then make plan. What I also want you to do +is keep all the exceptions, all the errors, everything that's out of the ordinary in a markdown file. Keep track of +that. Because we are going to do this a lot more times and I want to make a list of exceptions and weird things. So we +don't have to reinvent the wheel every time. There is a UPDATE_LOG containing the progress and some errors found during +previous updates, Consult this when needed and update and add to it when needed. + +There are upgrade logs from other project read them and see if there are any exceptions or errors that you might +encounter during the upgrade process. + +Then when the composer has been done do the `npm outdated` and do the same thing. Gather all the resources, make a plan, +and keep track of all the exceptions and log anything out of the ordinary in the same markdown file. + +Is that somewhat clear? + +> This file tracks all exceptions, errors, gotchas, and unusual things encountered during the upgrade process. +> Intended to be reusable for future upgrades. + +## Starting State + +| Package | Before | Target | +|-----------------------------|----------|---------------------------------| +| PHP | 8.4.17 | 8.4.17 (no change) | +| laravel/framework | 11.48.0 | ^12.0 | +| filament/filament | 3.3.48 | ^5.0 | +| livewire/livewire | 3.7.9 | ^4.0 (required by Filament v5) | +| tailwindcss | 3.4.19 | ^4.0 (required by Filament v5) | +| barryvdh/laravel-debugbar | 3.16.5 | ^4.0 | +| jeffgreco13/filament-breezy | 2.6.4 | ^3.0 (requires Filament ^4\|^5) | +| ariaieboy/filament-currency | 1.13.0 | ^3.0 (requires Filament ^5) | +| resend/resend-laravel | 0.23.0 | ^1.0 | +| symfony/http-client | 7.4.5 | ^8.0 | +| symfony/mailgun-mailer | 7.4.0 | ^8.0 | +| spatie/laravel-medialibrary | 11.17.10 | 11.18.2 (minor) | + +--- + +## Exceptions & Gotchas + +### Laravel 12 + +- [x] **Carbon 3 required** - Already on Carbon 3.11.1. No action needed. +- [x] **HasUuids generates UUID v7** - Fixed: `use HasVersion4Uuids as HasUuids;` in `Attachment` and `JobApplication`. +- [ ] **`image` validation excludes SVGs** - Not encountered. Monitor during testing. +- [x] **Local disk default changed** - Already explicitly configured in `config/filesystems.php`. No action needed. +- [x] **`mergeIfMissing()` dot notation** - Not used in codebase. No action needed. +- [ ] **Container default parameter resolution** - Not encountered. Monitor during testing. +- [ ] **Multi-schema database inspecting** - Not encountered. Monitor during testing. + +### Filament v3 → v5 + +- [x] **Must go v3 → v4 first, then v4 → v5** - Done. Ran `filament-v4` rector, then `filament-v5` rector. +- [x] **Tailwind CSS v4 required** - Done. Manual migration (automated tool failed). See Frontend Build Errors. +- [x] **Livewire v4 required for Filament v5** - Installed automatically with Filament v5. No manual steps. +- [ ] **File visibility default changed** - Non-local disks now default to `private` instead of `public`. Monitor during + testing. +- [ ] **Table filters deferred by default** - Users must click apply. Use `deferFilters(false)` to restore. Monitor + during testing. +- [ ] **Layout components no longer full-width** - Grid, Section, Fieldset need `columnSpanFull()`. Monitor during + testing. +- [x] **`unique()` validation ignores current record by default** - `ignoreRecord: true` is now default. No action + needed (beneficial change). +- [ ] **Pagination `all` option removed** from defaults. Monitor during testing. +- [ ] **Spatie Translatable Plugin deprecated** - Use Lara Zeus fork. Not currently used. +- [ ] **`columnSpan()` targets large devices** (`≥lg`) by default. Monitor during testing. +- [ ] **Enum field states always return enum instances**. Monitor during testing. +- [ ] **URL params renamed** - e.g., `activeRelationManager` → `relation`. Monitor during testing. +- [x] **`make()` method signatures updated** for Field, Entry, Column. Handled by rector scripts. + +### Filament Plugin Compatibility + +- [x] **filament-breezy v3** - Upgraded to v3.1.1. Works with Filament v5. +- [x] **filament-currency v3** - Upgraded to v3.0.0. Works with Filament v5 + Laravel 12. +- [x] **filament/spatie-laravel-media-library-plugin** - Upgraded to v5.0. +- [x] **filament/spatie-laravel-settings-plugin** - Upgraded to v5.0. +- [x] **filament/spatie-laravel-tags-plugin** - Upgraded to v5.0. + +### Symfony 7 → 8 + +- [x] **PHP 8.4 required** - Already satisfied. +- [x] **Return types enforced** - No issues encountered. App boots and tests pass. +- [x] **HttpClient: `setLogger()` removed** - Not used in codebase. No action needed. +- [x] **MailgunMailer** - No breaking changes encountered. + +### Other Packages + +- [x] **barryvdh/laravel-debugbar v4** - Upgraded. Only issue was stale autoload (see Runtime Error #1). +- [x] **resend/resend-laravel v1** - Upgraded to v1.1.0. No API changes encountered. + +--- + +## Errors Encountered During Upgrade + +### Composer Resolution Errors + +1. **codezero packages block Laravel 12** — `codezero/laravel-localized-routes` ^4, `codezero/laravel-localizer` ^3, + and `codezero/laravel-uri-translator` ^2 all hard-require `illuminate/support ^10.0|^11.0`. No stable release + supports L12. **Fix:** Replaced with `opgginc/codezero-laravel-localized-routes` ^5.0 (maintained fork that supports + L12 natively, same `CodeZero\LocalizedRoutes` namespace — drop-in replacement). Also removed + `codezero/laravel-localizer` entirely (`use_localizer` was `false` in config, package was unused). + +### Runtime Errors + +1. **`Barryvdh\Debugbar\ServiceProvider` not found** — After upgrading debugbar v3 → v4, `composer update --no-scripts` + left stale autoload. Fixed by running `composer dump-autoload` which re-ran package discovery. + +2. **`CodeZero\Localizer\LocalizerServiceProvider` not found** — After removing `codezero/laravel-localizer`, stale + `bootstrap/cache/packages.php` still referenced it. **Fix:** Delete `bootstrap/cache/packages.php` and + `bootstrap/cache/services.php`, then `composer dump-autoload`. + +3. **`Filament\Upgrade\UpgradeServiceProvider` not found** — After upgrading `filament/upgrade` from v4 to v5, the v5 + package no longer has a ServiceProvider but the cached packages.php still referenced v4's SP. **Fix:** Same as #2. + +4. **Filament v4: `$navigationGroup` type mismatch** — `protected static ?string $navigationGroup` must now be + `protected static string | \UnitEnum | null $navigationGroup`. Same for `$navigationIcon` → + `string | \BackedEnum | null`. All Filament resource files need updating. The `filament-v4` upgrade rector script + did NOT catch this — must be fixed manually. + +5. **Filament v4: `form()` method signature changed** — `form(Form $form): Form` → `form(Schema $schema): Schema`. + The `filament-v4` rector script DOES handle this, but only if run after `composer update` installs Filament v4. + The rector script requires interactive input (directory prompt — press Enter for default `app/`, or type `modules` + for custom dirs). Use `echo "" | vendor/bin/filament-v4` and `echo "modules" | vendor/bin/filament-v4` for + non-interactive runs. + +### Test Failures + +_(None — all 11 tests passed at every stage)_ + +### Frontend Build Errors + +1. **Tailwind v4: `@tailwindcss/upgrade` can't handle callback-based config** — The automated migration tool failed + with `Cannot destructure property 'negative'` when `tailwind.config.js` used `(theme, { negative }) =>` syntax + (old TW v2/v3 pattern). Also failed with `variants is not a function` from `@formkit/themes/tailwindcss` plugin. + **Fix:** Manual migration instead of automated tool. + +2. **Tailwind v4: `@apply` of custom classes in `@layer base` fails** — Custom utilities like `pl-container` defined + with `@apply` inside `@layer base {}` and then `@apply`'d by other classes (like `.container`) fail with + `Cannot apply unknown utility class`. **Fix:** Convert to `@utility` blocks instead of `@layer base`. + +3. **Tailwind v4: `@import` must precede all other statements** — Warning about `@import "./utility.css"` appearing + after `@theme {}`. **Fix:** Move `@import` to the top, right after `@import "tailwindcss"`. + +### Warnings + +1. **PHPUnit XML config deprecation** — `Your XML configuration validates against a deprecated schema. Migrate your XML + configuration using "--migrate-configuration"!` — Non-blocking, cosmetic warning from PHPUnit 12. + +--- + +## Lessons Learned + +1. **Always delete `bootstrap/cache/packages.php` and `services.php` after package changes** — Stale service provider + references cause `Class not found` errors. Do this after every major composer operation. + +2. **Run Filament upgrade scripts BEFORE `composer update`** for the rector processing, then AGAIN AFTER + `composer update` + for the files to match the new APIs. The rector script only processes directories you specify — remember to run it + separately for `app/` and `modules/` (or any custom dirs). + +3. **Filament v4 rector script doesn't catch property type changes** — `$navigationGroup` and `$navigationIcon` type + changes must be fixed manually. Search for `protected static ?string $navigationGroup` and `$navigationIcon`. + +4. **codezero packages are abandoned** — Replaced with `opgginc/codezero-laravel-localized-routes` (maintained fork, + same namespace). Also removed `codezero/laravel-localizer` (was unused — `use_localizer` was `false`). + +5. **Tailwind v4 migration tool doesn't work with complex configs** — Callback-based theme extensions and third-party + plugins (like FormKit) cause the automated tool to fail. Manual migration is more reliable. + +6. **Tailwind v4: `@layer base` → `@utility` for custom utility classes** — Classes that get `@apply`'d by other + classes must use the new `@utility` directive. Plain CSS rules in `@layer base` still work. + +7. **Tailwind v4: PostCSS config simplified** — Replace `tailwindcss` + `autoprefixer` plugins with just + `@tailwindcss/postcss`. Remove `autoprefixer` package. + +8. **`npm uninstall` can fail with peer dependency conflicts** — Use `--force` flag when removing old TW v3 plugins + that have peer dependencies on TW v3 while TW v4 is already installed. + +## Final State + +| Package | Before | After | +|-------------------------------------------|----------|---------------------| +| laravel/framework | 11.48.0 | 12.50.0 | +| filament/filament | 3.3.48 | 5.2.0 | +| livewire/livewire | 3.7.9 | 4.1.4 | +| tailwindcss | 3.4.19 | 4.1.18 | +| barryvdh/laravel-debugbar | 3.16.5 | 4.0.7 | +| jeffgreco13/filament-breezy | 2.6.4 | 3.1.1 | +| ariaieboy/filament-currency | 1.13.0 | 3.0.0 | +| resend/resend-laravel | 0.23.0 | 1.1.0 | +| symfony/http-client | 7.4.5 | 8.0.5 | +| symfony/mailgun-mailer | 7.4.0 | 8.0.0 | +| spatie/laravel-medialibrary | 11.17.10 | 11.18.2 | +| codezero/laravel-localized-routes | 4.0.1 | _removed_ | +| codezero/laravel-localizer | 3.0.0 | _removed_ | +| opgginc/codezero-laravel-localized-routes | — | 5.1.0 (replacement) | + +--- + +## Session Notes — 2026-02-10 (Discovery / Planning) + +### Exceptions / Out-of-the-Ordinary + +1. **Composer cache path not writable in sandbox** — `composer outdated` warned: + `Cannot create cache directory /Users/vincentverbruggen/Library/Caches/composer/...`. + **Workaround:** Run with `COMPOSER_CACHE_DIR=/tmp/composer-cache`. + +2. **DNS resolution fails in sandbox for Composer repos** — non-escalated runs reported: + - `Could not resolve host: strixi.repo.repman.io` + - `Could not resolve host: repo.packagist.org` + Composer then loaded package info from local cache and warned it **may be out of date**. + +3. **Accurate outdated data requires network-enabled run** — using elevated network access produced a complete and fresh + `composer outdated` result. + +### Verified Current State + +1. **Laravel framework status (as of 2026-02-10):** + - Installed: `laravel/framework v12.50.0` + - Latest stable visible via Composer metadata: `v12.50.0` (released `2026-02-04`) + - `13.0.x-dev` exists, but **no stable `v13` tag is listed yet**. + +2. **Composer actionable updates from fresh run:** + - Direct dependency update available: `laravel/boost 2.0.0 -> 2.1.1` (minor/patch level). + +3. **NPM actionable updates snapshot:** + - Non-breaking/minor updates available for several packages (`@inertiajs/vue3`, `vue`, `axios`, + `laravel-vite-plugin`, + `@vitejs/plugin-vue`, etc.). + - Major updates available for linting stack (`eslint` and `@eslint/js` v10). + +4. **Current baseline test failures (pre-upgrade state):** + - `php artisan test --compact` on 2026-02-10 reports 4 failing tests and 7 passing tests. + - All 4 failures are validation-related (HTTP 422 instead of expected 200) with the same message: + `E-mailadres is geen geldig e-mailadres.` + - Affected tests: + - `Tests\Feature\ContactFormSubmissionTest` (2 cases) + - `Tests\Feature\JobApplicationFormSubmissionTest` (2 cases) + +5. **Transitive major updates are visible but mostly not actionable yet:** + - `composer outdated` reports many `~` major updates for Symfony 7.x/8.x-adjacent and PHPUnit internals. + - Treat these as **future Laravel-major alignment work** rather than immediate upgrades to force directly. + +6. **Filament CSS/asset load troubleshooting (2026-02-10):** + - Symptom: Filament panel styling appeared not to load after upgrade. + - Action taken: `php artisan filament:upgrade` (republished Filament assets and cleared config/route/view caches). + - Result: command completed successfully with `Successfully published assets` and `Successfully upgraded`. + - Reusable rule: prefer `filament:upgrade` first; only consider manual asset directory cleanup if issue persists. + +7. **ESLint + Tailwind v4 compatibility (2026-02-10):** + - Symptom: ESLint crashed with `Error: Could not resolve tailwindcss` from `eslint-plugin-tailwindcss`. + - Context: project uses Tailwind CSS v4 (`tailwindcss@4.1.18`) with CSS-first config, and no active + `tailwind.config.js`. + - Action taken: removed `eslint-plugin-tailwindcss` config usage from `eslint.config.mjs` (import, flat preset, and + plugin-specific settings/rules) to avoid false failures. + - Result: ESLint now executes normally and reports regular code-style/type issues instead of crashing. + - Reference: https://github.com/francoismassart/eslint-plugin-tailwindcss (v4 support is still + partial/work-in-progress). + +8. **NPM dependency update pass (2026-02-10):** + - Pre-check: `npm outdated --json` showed 19 outdated entries. + - Minor/patch in-range updates available for app deps (Inertia, Vue, Vite plugin, FormKit, etc.). + - Major updates still available for `eslint` / `@eslint/js` (v10) and intentionally not applied in this pass. + - Action taken: `npm update`. + - Command result: + `added 9 packages, removed 13 packages, changed 95 packages, audited 426 packages, found 0 vulnerabilities`. + - Post-check: `npm outdated --json` now only shows: + - `@eslint/js` 9.39.2 (latest 10.0.1, major) + - `eslint` 9.39.2 (latest 10.0.0, major) + - `eslint-plugin-tailwindcss` 4.0.0-beta.0 (latest stable line reported as 3.18.2) + - `@rollup/rollup-linux-x64-gnu` (platform binary metadata entry) + - Notable updated packages now in lockfile: + - `@inertiajs/vue3` 2.3.13 + - `vue` 3.5.28 + - `@vue/server-renderer` 3.5.28 + - `vue-i18n` 11.2.8 + - `@formkit/addons` / `@formkit/vue` 1.7.2 + - `@vitejs/plugin-vue` 6.0.4 + - `laravel-vite-plugin` 2.1.0 + - `@vueuse/core` 14.2.1 + - `swiper` 12.1.0 + - `eslint-plugin-unused-imports` 4.4.1 + - `globals` 17.3.0 + - Reusable rule: run npm commands with network access in this environment when sandboxed runs hang or return no + output. + +--- + +## Session: Goos Upgrade (2026-02-10) + +### Starting State (goos) + +| Package | Before | Target | +|-----------------------------|----------|---------------------------------| +| PHP | 8.4 | 8.4 (no change) | +| laravel/framework | 11.47.0 | ^12.0 | +| filament/filament | 3.3.45 | ^5.0 (via v4) | +| barryvdh/laravel-debugbar | 3.x | ^4.0 | +| inertiajs/inertia-laravel | 1.x | ^2.0 | +| jeffgreco13/filament-breezy | 2.x | ^3.0 | +| ariaieboy/filament-currency | 1.8 | ^3.0 | +| amidesfahani/filament-tinyeditor | 3.0 | ^4.0 | +| johncarter/filament-focal-point-picker | 3.x | ^4 | +| ralphjsmit/laravel-filament-components | 2.x | ^3 | +| mollie/laravel-mollie | 3.0 | ^4.0 | +| symfony/http-client | 7.x | ^8 | +| symfony/mailgun-mailer | 7.x | ^8 | +| tailwindcss | 3.3.2 | ^4.0 | +| @inertiajs/vue3 | 1.x | ^2.0 | +| pestphp/pest | 2.4 | ^3.0 | + +**Baseline tests:** 1 failed (ShippingAddressControllerTest — pre-existing), 16 passed (51 assertions) + +### Goos Errors & Gotchas + +1. **codezero packages block L12** — Same as cleanshopping. Replaced `codezero/laravel-localized-routes ^4` with + `opgginc/codezero-laravel-localized-routes ^5.0`. Removed `codezero/laravel-localizer ^3` (unused — no PHP code + references `CodeZero\Localizer`). Removed `codezero/composer-preload-files` from `allow-plugins`. + +2. **`codezero/composer-preload-files` plugin blocked** — After removing from `allow-plugins`, the plugin still existed + in vendor (transitive dependency). Composer refused to run. **Fix:** `composer config --no-plugins allow-plugins.codezero/composer-preload-files false`. + +3. **Localized routes: `/en/` prefix no longer generated** — After switching to `opgginc/codezero-laravel-localized-routes ^5`, + the PageTest fails: redirects for English locale no longer have `/en/` prefix (e.g., `/ds` instead of `/en/ds`). + The `config/localized-routes.php` `omitted_locale` is `nl`, so English should get prefixed. **Status:** Needs investigation — + may be a config difference in the v5 fork. Monitor during manual testing. + +4. **`johncarter/filament-focal-point-picker` incompatible with Filament v5** — Latest v4.1.0 and `dev-main` only support + `filament/filament ^3.0|^4.0`. No v5 support. **Fix:** Removed package, replaced `FocalPointPicker` with `TextInput` + for focal point fields (stores coordinates as string like `"50% 50%"`). Consider forking or finding alternative. + +5. **`filament/spatie-laravel-translatable-plugin` deprecated in v4** — No v5 release exists. **Fix:** Replaced with + `lara-zeus/spatie-translatable ^2.0` (recommended by Filament upgrade tool). Namespace changed: `Filament\SpatieLaravelTranslatablePlugin` + → `LaraZeus\SpatieTranslatable\SpatieLaravelTranslatablePlugin` (handled by rector). + +6. **laravel-vite-plugin v2 requires Vite 7** — `laravel-vite-plugin ^2` has `peer vite@"^7.0.0"`. Had to bump + `vite` from `^6.2.0` to `^7.0.0`. + +7. **eslint-plugin-tailwindcss incompatible with TW v4** — `eslint-plugin-tailwindcss ^3` requires `tailwindcss ^3.4.0`. + **Fix:** Removed from devDependencies. TW v4 ESLint plugin support is still WIP upstream. + +8. **PHPUnit metadata deprecation warnings** — 15 test methods use `@test` doc-comment annotations. PHPUnit 12 requires + PHP attributes instead. Non-blocking but noisy. + +9. **Filament v4+v5 rector ran successfully** — Processed `app/`, `cms/`, `commerce/`, `modules/`, `support/` directories + for both v4 and v5 rectors. 112+ files modified. No manual `$navigationGroup`/`$navigationIcon` type fixes needed + (project uses method overrides instead of static properties). + +10. **Inertia v2 SSR config** — Changed `ssr.noExternal` from `['@inertiajs/server']` to `['@inertiajs/vue3']` in + `vite.config.js`. `@inertiajs/server` no longer exists in Inertia v2. + +### Goos Final State + +| Package | Before | After | +|-------------------------------------------|----------|---------------------| +| laravel/framework | 11.47.0 | 12.50.0 | +| filament/filament | 3.3.45 | 5.2.1 | +| livewire/livewire | 3.x | 4.1.4 | +| barryvdh/laravel-debugbar | 3.x | 4.0.7 | +| inertiajs/inertia-laravel | 1.3.3 | 2.1.0 | +| jeffgreco13/filament-breezy | 2.6.4 | 3.1.1 | +| ariaieboy/filament-currency | 1.13.0 | 3.0.0 | +| amidesfahani/filament-tinyeditor | 3.0.0 | 4.0.5 | +| ralphjsmit/laravel-filament-components | 2.2.0 | 3.1.0 | +| mollie/laravel-mollie | 3.1.0 | 4.0.2 | +| symfony/http-client | 7.x | 8.x | +| symfony/mailgun-mailer | 7.x | 8.x | +| pestphp/pest | 2.x | 3.x | +| codezero/laravel-localized-routes | 4.0.1 | _removed_ | +| codezero/laravel-localizer | 3.0.0 | _removed_ | +| opgginc/codezero-laravel-localized-routes | — | 5.x (replacement) | +| filament/spatie-laravel-translatable-plugin | 3.3.45 | _removed_ | +| lara-zeus/spatie-translatable | — | 2.x (replacement) | +| johncarter/filament-focal-point-picker | 3.1.0 | _removed_ | +| tailwindcss | 3.3.2 | 4.1.18 | +| vite | 6.x | 7.3.1 | +| @inertiajs/vue3 | 1.x | 2.x | +| laravel-vite-plugin | 1.x | 2.x | +| @vitejs/plugin-vue | 5.x | 6.x | +| @vueuse/core | 10.x | 14.x | +| vue-i18n | 9.x | 11.x | +| swiper | 10.x | 12.x | +| @gtm-support/vue-gtm | 2.x | 3.x | + +**Final tests:** 2 failed (1 pre-existing ShippingAddressControllerTest + 1 new PageTest locale prefix), 15 passed (51 assertions) +**Frontend build:** Clean (client + SSR), 0 vulnerabilities + +### Post-Upgrade Fixes (Browser Testing Session) + +11. **PHPUnit 12 drops `@test` annotation support** — Pest v4 uses PHPUnit 12, which no longer recognizes `/** @test */` doc annotations. All test methods using `@test` must be updated to use `#[PHPUnit\Framework\Attributes\Test]` attribute or `test_` method prefix. Without this, tests are silently not discovered. + +12. **Filament v5 `Component::$container` uninitialized error** — Using `getChildComponents()` on Filament form components outside a Livewire context (e.g., during frontend page rendering) throws `Typed property Component::$container must not be accessed before initialization`. Fix: replace `getChildComponents()` with `getDefaultChildComponents()` which returns raw component arrays without requiring a Schema/Livewire container. Affected: `cms/Filament/Blocks/Block.php` methods `getSchema()` and `hasSettings()`. + +13. **Filament v5 `Field::make()` signature change** — `make(string $name)` changed to `make(?string $name = null)`. Any subclass overriding `make()` with `string $name = ''` must update to `?string $name = null`. Affected: `app/Forms/Components/DisplayText.php`. + +14. **Pest v4 requires `protected setUp()`** — PHPUnit 12 uses `protected function setUp(): void`. If `Tests\TestCase` declares `public function setUp()`, Pest v4 fails with `Access level to Pest\Concerns\Testable::setUp() must be public`. Fix: change to `protected function setUp(): void`. + +15. **Pest Browser Testing setup** — Requires `npm install playwright` in project root + `npx playwright install chromium`. The plugin starts its own internal HTTP server (AMP-based) and boots the Laravel kernel directly — no external server needed. Browser test directory: `tests/Browser/`. + +16. **Filament v5 `ViewAction` on ListRecords pages crashes** — `ViewAction::make()` in `getHeaderActions()` on a list page causes `getViewAuthorizationResponse(): Argument #1 ($record) must be of type Model, null given`. In v5, `ViewAction` tries to authorize against a record, but list pages have no record. Fix: replace with `Action::make('name')` for navigation-only header actions. Affected: `cms/Filament/Resources/BlogResource/Pages/ListBlogs.php`. + +**Browser tests:** 4 passed (homepage, terms, contact, products all render correctly) +**Updated test results:** 1 failed (PageTest locale prefix — pre-existing codezero issue), 15 passed (49 assertions) + 4 browser tests passed diff --git a/Work/Projects/Laravel-v12-Migration/UPGRADE-LOG-GOOS.md b/Work/Projects/Laravel-v12-Migration/UPGRADE-LOG-GOOS.md new file mode 100644 index 0000000..8eba6d5 --- /dev/null +++ b/Work/Projects/Laravel-v12-Migration/UPGRADE-LOG-GOOS.md @@ -0,0 +1,220 @@ +# Upgrade Log: Goos — Laravel 11 → 12 + Full Ecosystem + +> Date: 2026-02-10 / 2026-02-11 +> Branch: `laravel-v12` + +--- + +## Version Changes + +### Composer (PHP) + +| Package | Before | After | Notes | +|---------|--------|-------|-------| +| laravel/framework | 11.47.0 | 12.50.0 | | +| filament/filament | 3.3.45 | 5.2.1 | Via v4 rector then v5 rector | +| livewire/livewire | 3.x | 4.1.4 | | +| pestphp/pest | 2.x | 4.3.2 | PHPUnit 12 | +| barryvdh/laravel-debugbar | 3.x | 4.0.7 | | +| inertiajs/inertia-laravel | 1.3.3 | 2.1.0 | | +| jeffgreco13/filament-breezy | 2.6.4 | 3.1.1 | | +| ariaieboy/filament-currency | 1.13.0 | 3.0.0 | | +| amidesfahani/filament-tinyeditor | 3.0.0 | 4.0.5 | | +| ralphjsmit/laravel-filament-components | 2.2.0 | 3.1.0 | | +| mollie/laravel-mollie | 3.1.0 | 4.0.2 | | +| symfony/http-client | 7.x | 8.x | | +| symfony/mailgun-mailer | 7.x | 8.x | | +| laravel/sanctum | 3.x | 4.x | | +| nunomaduro/collision | 7.x | 8.x | | +| codezero/laravel-localized-routes | 4.0.1 | *removed* | Replaced | +| codezero/laravel-localizer | 3.0.0 | *removed* | Unused | +| opgginc/codezero-laravel-localized-routes | — | 5.x | Replacement fork | +| filament/spatie-laravel-translatable-plugin | 3.3.45 | *removed* | Deprecated in Filament v4 | +| lara-zeus/spatie-translatable | — | 2.x | Replacement | +| johncarter/filament-focal-point-picker | 3.1.0 | *removed* | No Filament v5 support | +| pestphp/pest-plugin-browser | — | 4.2 | New — browser testing | + +### NPM (Frontend) + +| Package | Before | After | Notes | +|---------|--------|-------|-------| +| tailwindcss | 3.3.2 | 4.1.18 | Manual migration | +| vite | 6.x | 7.3.1 | Required by laravel-vite-plugin v2 | +| @inertiajs/vue3 | 1.x | 2.x | | +| laravel-vite-plugin | 1.x | 2.x | | +| @vitejs/plugin-vue | 5.x | 6.x | | +| @vueuse/core | 10.x | 14.x | | +| vue-i18n | 9.x | 11.x | | +| swiper | 10.x | 12.x | | +| @gtm-support/vue-gtm | 2.x | 3.x | | +| autoprefixer | 10.x | *removed* | Not needed with TW v4 | +| @tailwindcss/forms | 0.5.x | *removed* | Built into TW v4 | +| @tailwindcss/typography | 0.5.x | *removed* | Built into TW v4 | +| @tailwindcss/aspect-ratio | 0.4.x | *removed* | Built into TW v4 | +| eslint-plugin-tailwindcss | 3.x | *removed* | No TW v4 support | +| @tailwindcss/postcss | — | 0.x | New — TW v4 PostCSS plugin | +| @tailwindcss/vite | — | 4.x | New — TW v4 Vite plugin | +| playwright | — | latest | New — browser testing | + +--- + +## All Issues Encountered + +### 1. codezero packages block Laravel 12 + +**Error:** `codezero/laravel-localized-routes ^4` and `codezero/laravel-localizer ^3` have no Laravel 12 support. + +**Fix:** +- Replaced `codezero/laravel-localized-routes` with `opgginc/codezero-laravel-localized-routes ^5.0` +- Removed `codezero/laravel-localizer` entirely (unused — no PHP code references `CodeZero\Localizer`) +- Removed `codezero/composer-preload-files` from `allow-plugins` in `composer.json` + +### 2. codezero/composer-preload-files plugin blocked Composer + +**Error:** After removing from `allow-plugins`, the plugin still existed in vendor. Composer refused to run any command. + +**Fix:** `composer config --no-plugins allow-plugins.codezero/composer-preload-files false` + +### 3. Localized routes: `/en/` prefix no longer generated + +**Error:** PageTest fails — redirects for English locale no longer have `/en/` prefix (e.g., `/ds` instead of `/en/ds`). + +**Status:** Open. Needs investigation — may be a config difference in the opgginc v5 fork. The `config/localized-routes.php` has `omitted_locale => 'nl'`, so English should get prefixed. + +**File:** `tests/Feature/Cms/Models/PageTest.php` + +### 4. johncarter/filament-focal-point-picker incompatible with Filament v5 + +**Error:** Latest v4.1.0 and `dev-main` only support `filament/filament ^3.0|^4.0`. + +**Fix:** Removed the package. Replaced `FocalPointPicker` with `TextInput` for focal point fields (stores coordinates as string like `"50% 50%"`). + +**Files:** +- `cms/Filament/Form/Fieldset/ImageForBlock.php` +- `cms/Filament/Form/Fieldset/ImageVariantForBlock.php` + +### 5. filament/spatie-laravel-translatable-plugin deprecated + +**Error:** No v5 release. Package deprecated in Filament v4. + +**Fix:** Replaced with `lara-zeus/spatie-translatable ^2.0` (recommended by Filament upgrade rector). Namespace changed from `Filament\SpatieLaravelTranslatablePlugin` → `LaraZeus\SpatieTranslatable\SpatieLaravelTranslatablePlugin` (handled by rector). + +**File:** `app/Providers/Filament/AdminPanelProvider.php` + +### 6. laravel-vite-plugin v2 requires Vite 7 + +**Error:** `npm install` fails — `laravel-vite-plugin ^2` has `peer vite@"^7.0.0"`. + +**Fix:** Updated `vite` from `^6.2.0` to `^7.0.0` in `package.json`. + +### 7. eslint-plugin-tailwindcss incompatible with Tailwind v4 + +**Error:** `npm install` fails — `eslint-plugin-tailwindcss ^3` requires `tailwindcss ^3.4.0`. + +**Fix:** Removed from `devDependencies`. TW v4 ESLint plugin support does not exist yet. + +### 8. Tailwind v3 → v4: manual migration required + +**Error:** The automated `@tailwindcss/upgrade` tool fails with callback-based theme extensions, FormKit plugin, and `@apply` in `@layer base`. + +**Fix:** Manual migration: +- `postcss.config.js` — replaced `tailwindcss + autoprefixer` with `@tailwindcss/postcss` +- `resources/css/app.css` — replaced `@tailwind` directives with `@import "tailwindcss"`, added `@theme {}` block with custom colors/fonts/spacing +- `resources/css/utility.css` — converted all `@layer base` classes using `@apply` to `@utility` blocks with plain CSS (including media queries for responsive values) +- Removed `tailwind.config.js` configuration (moved to CSS-first config) +- Removed plugins: `@tailwindcss/forms`, `@tailwindcss/typography`, `@tailwindcss/aspect-ratio`, `autoprefixer` + +### 9. Inertia v2 SSR config change + +**Error:** `@inertiajs/server` no longer exists in Inertia v2. + +**Fix:** Changed `ssr.noExternal` from `['@inertiajs/server']` to `['@inertiajs/vue3']` in `vite.config.js`. + +### 10. Filament v5: `Component::$container` uninitialized error + +**Error:** `Typed property Filament\Schemas\Components\Component::$container must not be accessed before initialization` — thrown when calling `getChildComponents()` on Filament form components outside a Livewire context (during frontend page rendering via the CMS Block system). + +**Root cause:** Filament v5's `getChildComponents()` creates a `Schema` wrapper that requires `getLivewire()`, which fails outside Filament admin panel context. + +**Fix:** Replace `getChildComponents()` with `getDefaultChildComponents()` which returns raw component arrays without requiring a Schema/Livewire container. + +**File:** `cms/Filament/Blocks/Block.php` — methods `getSchema()` and `hasSettings()` + +### 11. Filament v5: `Field::make()` signature change + +**Error:** `Declaration of DisplayText::make(string $name = ''): static must be compatible with Field::make(?string $name = null): static` + +**Fix:** Changed `make(string $name = '')` to `make(?string $name = null)` and pass `$name ?? ''` to parent. + +**File:** `app/Forms/Components/DisplayText.php` + +### 12. PHPUnit 12 drops `@test` annotation support + +**Error:** Tests using `/** @test */` are silently not discovered — `INFO No tests found.` + +**Fix:** Replaced all `/** @test */` annotations with `#[PHPUnit\Framework\Attributes\Test]` attribute in all 7 test files. Added `use PHPUnit\Framework\Attributes\Test;` import to each. + +**Files:** +- `tests/Feature/Cms/Models/PageTest.php` +- `tests/Feature/Cms/Models/RedirectTest.php` +- `tests/Feature/Models/UserTest.php` +- `tests/Feature/Services/Filament/HelperTest.php` +- `tests/Feature/Commerce/Actions/Order/CreateOrderFromCheckoutTest.php` +- `tests/Feature/Http/Controller/Public/FormControllerTest.php` +- `tests/Feature/Http/Controllers/Api/V0/AddressCheckControllerTest.php` + +### 13. PHPUnit 12 / Pest v4: `setUp()` must be protected + +**Error:** `Access level to Pest\Concerns\Testable::setUp() must be public (as in class Tests\TestCase)` — fatal error on any test run. + +**Fix:** Changed `public function setUp(): void` to `protected function setUp(): void`. + +**File:** `tests/TestCase.php` + +### 14. Filament v5: `ViewAction` on ListRecords pages crashes + +**Error:** `Resource::getViewAuthorizationResponse(): Argument #1 ($record) must be of type Model, null given` — thrown when rendering `ViewAction` header actions on list pages. + +**Root cause:** In v5, `ViewAction` tries to authorize against a record, but list pages have no record (`null`). + +**Fix:** Replace `ViewAction::make()` with `Action::make('name')` for navigation-only header actions that don't operate on a record. + +**File:** `cms/Filament/Resources/BlogResource/Pages/ListBlogs.php` + +### 15. Filament v4/v5 rector scripts + +**Note:** Rector must run for EACH custom namespace directory separately: `app/`, `cms/`, `commerce/`, `modules/`, `support/`. No manual `$navigationGroup`/`$navigationIcon` type fixes needed in this project (uses method overrides). + +**Files:** 112+ files modified by rector across all directories. + +--- + +## Files Modified (manual changes only, excluding rector) + +| File | Change | +|------|--------| +| `composer.json` | Version constraints, package replacements | +| `package.json` | Version constraints, removed TW plugins, cleanup | +| `postcss.config.js` | TW v4 PostCSS plugin | +| `resources/css/app.css` | TW v4 directives + `@theme` block | +| `resources/css/utility.css` | `@layer base` → `@utility` blocks | +| `vite.config.js` | SSR `noExternal` fix | +| `cms/Filament/Blocks/Block.php` | `getChildComponents()` → `getDefaultChildComponents()` | +| `cms/Filament/Form/Fieldset/ImageForBlock.php` | FocalPointPicker → TextInput | +| `cms/Filament/Form/Fieldset/ImageVariantForBlock.php` | FocalPointPicker → TextInput | +| `cms/Filament/Resources/BlogResource/Pages/ListBlogs.php` | ViewAction → Action | +| `app/Forms/Components/DisplayText.php` | `make()` signature fix | +| `tests/TestCase.php` | `setUp()` visibility | +| `tests/Pest.php` | Browser test suite binding | +| `phpunit.xml` | Browser test suite | +| `tests/Browser/PageTest.php` | New — browser smoke tests | +| `tests/Feature/**/*Test.php` (7 files) | `@test` → `#[Test]` attribute | + +--- + +## Final State + +- **Feature/Unit tests:** 15 passed, 1 failed (PageTest locale prefix — codezero fork issue) +- **Browser tests:** 4 passed (homepage, terms, contact, products) +- **Frontend build:** Clean (client + SSR), 0 npm vulnerabilities +- **169 files changed** total (including rector, vendor assets, lock files) diff --git a/Work/Projects/Laravel-v12-Migration/UPGRADE-LOG-deversspecialist.md b/Work/Projects/Laravel-v12-Migration/UPGRADE-LOG-deversspecialist.md new file mode 100644 index 0000000..4eeaaa6 --- /dev/null +++ b/Work/Projects/Laravel-v12-Migration/UPGRADE-LOG-deversspecialist.md @@ -0,0 +1,119 @@ +# Upgrade Log: Laravel 11 → 12 + Full Ecosystem + +## Starting State + +| Package | Before | Target | +|---|---|---| +| laravel/framework | 11.48.0 | ^12.0 | +| filament/filament | 3.3.48 | ^5.0 | +| livewire/livewire | 3.7.10 | ^4.0 | +| tailwindcss | 3.4.19 | ^4.0 | +| pestphp/pest | 3.8.5 | ^4.0 | +| barryvdh/laravel-debugbar | 3.16.5 | ^4.0 | +| jeffgreco13/filament-breezy | 2.6.4 | ^3.0 | +| ariaieboy/filament-currency | 1.13.0 | ^3.0 | +| amidesfahani/filament-tinyeditor | 3.0.0 | ^4.0 | +| mollie/laravel-mollie | 3.1.0 | ^4.0 | + +**Baseline tests:** 14 passed (41 assertions) +**Baseline build:** Success (client + SSR) + +--- + +## Phase 1: Pre-Flight + +- [x] Branch created: `upgrade/laravel-12-full` +- [x] Baseline tests: 14 passed +- [x] Baseline build: success + +## Phase 2: Composer — Laravel 12 + +- [x] Replaced `codezero/laravel-localized-routes` with `opgginc/codezero-laravel-localized-routes:^5.0` (drop-in fork) +- [x] Removed `codezero/laravel-localizer` (single-locale nl project) +- [x] Set `codezero/composer-preload-files` to `false` in allow-plugins (transitive dep still present) +- [x] Updated constraints: laravel/framework ^12, symfony/http-client ^8.0, symfony/mailgun-mailer ^8.0, barryvdh/laravel-debugbar ^4.0, mollie/laravel-mollie ^4.0 +- [x] `composer update -W` — Laravel v12.50.0 installed +- [x] Tests: 14 passed + +## Phase 3: Filament v3 → v4 → v5 + +- [x] Removed `awcodes/filament-table-repeater` (no Filament v4/v5 version exists) +- [x] Replaced TableRepeater with standard `Filament\Forms\Components\Repeater` in ChildrenRelationManager +- [x] Ran `filament-v4` rector on 197 files +- [x] Removed `filament/spatie-laravel-translatable-plugin` (no v4 release), skipped to v5 +- [x] Ran `filament-v5` rector on 197 files +- [x] Installed all Filament v5 packages + `lara-zeus/spatie-translatable:^2.0` +- [x] Fixed ~20 files: `Filament\Pages\Actions\*` → `Filament\Actions\*` +- [x] Fixed `Filament\Forms\Set` → `Filament\Schemas\Components\Utilities\Set` (ProductResource, ChildrenRelationManager) +- [x] Filament v5.2.1, Livewire v4.1.4 installed +- [x] Tests: 14 passed + +## Phase 4: Tailwind v3 → v4 + +- [x] Installed tailwindcss@^4, @tailwindcss/postcss, @tailwindcss/cli +- [x] Removed autoprefixer, @tailwindcss/forms, @tailwindcss/typography, @tailwindcss/aspect-ratio, eslint-plugin-tailwindcss +- [x] Updated postcss.config.js to use @tailwindcss/postcss +- [x] Migrated tailwind.config.js to CSS-first config in app.css (@theme, @source, @variant directives) +- [x] Converted utility.css from @layer to @utility directives +- [x] Deleted tailwind.config.js +- [x] Removed tailwindcss settings from eslint.config.mjs +- [x] Installed vite@^7, @vitejs/plugin-vue@^6, laravel-vite-plugin@^2 +- [x] Build: success, Tests: 14 passed + +## Phase 5: Pest v3 → v4 + +- [x] Upgraded pestphp/pest:^4.0 + pestphp/pest-plugin-laravel:^4.0 +- [x] Pest v4.3.2, PHPUnit 12.5.8 installed +- [x] Tests: 14 passed + +## Phase 6: NPM Updates + +- [x] Removed eslint-plugin-tailwindcss (re-added by quality:update, incompatible with TW v4) +- [x] Fixed eslint.config.mjs (removed tailwindcss settings block re-added by quality:update) +- [x] `npm update` for minor/patch bumps +- [x] Major updates: @vuepic/vue-datepicker ^12.1.0, @vueuse/core ^14.2.1, swiper ^12.1.0, vite-imagetools ^9.0.2, imagetools-core ^9.1.0, vite-plugin-vue-devtools ^8.0.6, vue-flatpickr-component ^12.0.0, globals ^17.3.0 +- [x] Fixed `VueDatePicker` import: default → named export (v12 breaking change) +- [x] ESLint stays at v9 (intentionally skipped) +- [x] Build: success + +## Phase 7: Final Verification + +- [x] Tests: 14 passed (41 assertions) +- [x] Build: success (client + SSR) +- [x] Pint: clean (fixed 2 lang files) +- [x] `composer outdated --direct`: only predis/predis v2→v3 (out of scope) +- [x] `npm outdated`: only eslint v9→v10, @eslint/js v9→v10 (intentionally skipped) +- [x] `php artisan filament:upgrade`: assets published successfully +- [x] `php artisan about`: Laravel 12.50.0 confirmed + +--- + +## Final State + +| Package | Version | +|---|---| +| laravel/framework | 12.50.0 | +| filament/filament | 5.2.1 | +| livewire/livewire | 4.1.4 | +| tailwindcss | 4.x | +| pestphp/pest | 4.3.2 | +| phpunit/phpunit | 12.5.8 | +| vite | 7.3.1 | +| @vitejs/plugin-vue | 6.x | +| laravel-vite-plugin | 2.x | + +--- + +## Exceptions & Issues Log + +1. **codezero/composer-preload-files plugin error**: After removing codezero packages, `composer dump-autoload` failed. Fix: set `allow-plugins.codezero/composer-preload-files` to `false`. +2. **awcodes/filament-table-repeater blocks Filament v4**: No compatible version. Fix: removed package, replaced with standard Repeater. +3. **lara-zeus/spatie-translatable requires Filament v5**: Rector changed imports to LaraZeus namespace during v4 step, but package wasn't installable until v5. Caused transient FatalError. Fix: skip translatable during v4, install with v5. +4. **filament-v5 rector MissingInputException**: Running without input fails. Fix: pipe `echo "app"` to rector. +5. **Vite 7 peer dependency conflicts**: laravel-vite-plugin@^2 requires Vite 7. Fix: install vite@^7 with `--force`. +6. **@import must precede @source in TW v4**: CSS ordering constraint. Fix: move @import before @source directives. +7. **eslint-plugin-tailwindcss re-added by quality:update**: `strixi/laravel-quality` re-publishes eslint.config.mjs on `composer update`. Fix: remove the package and tailwindcss settings again after composer operations. +8. **@vuepic/vue-datepicker v12 default export removed**: Changed to named export. Fix: `import { VueDatePicker }` instead of default import. +9. **Add basic browser smoke tests after upgrade**: After completing the upgrade, set up `pestphp/pest-plugin-browser` + Playwright and create browser tests that seed pages (via `PageSeeder`) and visit key public routes (`/`, `/over-ons`, `/contact`). Use `assertNoSmoke()` to catch JS errors and console logs. This catches runtime issues (broken Inertia renders, missing assets, JS import errors) that unit/feature tests won't find. +10. **@vuepic/vue-datepicker v12 locale + format props changed**: The `locale` prop now requires a date-fns `Locale` object instead of a string. The `format` prop was renamed to `formats` with sub-properties (e.g. `formats.input`). Fix: `import {nl} from "date-fns/locale"`, change `:locale="'nl'"` to `:locale="nl"`, change `format="dd-MM-yyyy"` to `:formats="{ input: 'dd-MM-yyyy' }"`. +11. **Filament v5 evaluates column labels during initialization**: `$livewire->tableFilters` is null before filters are populated, causing "Trying to access array offset on null" errors. Fix: use null-safe access with `?? null` or `?? 'default'` defaults when accessing filter values in column labels/formatters.