diff --git a/.planning/phases/14.2-local-fonoteka-frontend-on-local-summercms-backend/14.2-UAT.md b/.planning/phases/14.2-local-fonoteka-frontend-on-local-summercms-backend/14.2-UAT.md new file mode 100644 index 0000000..4f3b71a --- /dev/null +++ b/.planning/phases/14.2-local-fonoteka-frontend-on-local-summercms-backend/14.2-UAT.md @@ -0,0 +1,60 @@ +--- +phase: 14.2-local-fonoteka-frontend-on-local-summercms-backend +plan: 03 +status: pending-manual-session +--- + +# Phase 14.2 UAT: vue-fonoteka-app on the local Go backend + +This file records the D-13 manual session (plan 03, Task 4) and the D-11 PHP cross-check of the plan 03 specs. + +## Automated evidence (plan 03, Tasks 1 and 3) + +- Go gate subset (D-15) through `fonoteka.go/scripts/dev-stack.sh e2e`. Specs: `auth.setup.ts`, `login.spec.ts`, `smoke.spec.ts`, `fonoteka-item.spec.ts`, `public-share.spec.ts`, `realtime.spec.ts`, `i18n.spec.ts`, `album-edit-rate-cover.spec.ts`, `album-search.spec.ts`, `wishlist.spec.ts`. Result: `expected=17 unexpected=0 skipped=0 flaky=0`, `e2e-verdict: passed`. +- The realtime live test passed against the shared Centrifugo after the D-18/D-23 operator step: a connect reply, an error-free `collection:` subscribe and a push on that channel after an API album create. +- Commits tested: vue-fonoteka-app `c1f323a`; fonoteka.go `7675d64`. + +## PHP cross-check (Task 3): deferred + +The plan 03 specs could not be checked against PHP automatically on 2026-10-11. + +- **What PHP did:** PHP started. `php artisan serve --host=127.0.0.1 --port=8422` in `/media/nvme/dev/golem15/fonoteka` answered the probe `GET http://127.0.0.1:8422/_fonoteka/api/v1/albums` with `HTTP/1.1 401 Unauthorized` and `X-Powered-By: PHP/8.5.10`, so the verify took branch A. +- **Why the run did not count:** no PHP E2E credentials are available to the executor. `E2E_EMAIL` and `E2E_PASSWORD` were still unset after Playwright loaded `tests/e2e/.env.local` and `tests/e2e/.env`. `auth.setup.ts` therefore wrote an empty storage state, and the five specs skipped. + - Report: `expected=1 unexpected=0 skipped=5 flaky=0`. + - `e2e-verdict` refused it. It is **not** a PHP pass. +- **Why the executor did not seed:** the Go seed user `demo@example.com` / `changeme` does not exist on PHP (`POST /_user/api/v1/login` answered 401). The executor did not create a user in the developer's PHP database. Seeding with `seedE2EFixtures()` in PHP mode runs `firstOrNew` on the e-mail, so it can reset the password of an existing user. + +**Manual PHP check (Task 4, item 11).** Run it with the credentials of a PHP user whose collection may receive temporary `E2E …` albums. Every spec deletes what it creates. + +```sh +# Go stack stopped first: bash ../fonoteka.go/scripts/dev-stack.sh down +cd /media/nvme/dev/golem15/fonoteka && php artisan serve --host=127.0.0.1 --port=8422 & +cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go +R=/tmp/php-e2e-14.2.json; rm -f "$R" +env -u CI -u E2E_BACKEND E2E_EMAIL='' E2E_PASSWORD='' \ + E2E_FRONTEND_URL=http://localhost:3119 E2E_BACKEND_URL=http://localhost:8422 E2E_CENTRIFUGO=1 \ + PLAYWRIGHT_JSON_OUTPUT_NAME="$R" pnpm --dir /media/nvme/dev/golem15/fonoteka/vue-fonoteka-app exec playwright test \ + auth.setup.ts realtime.spec.ts album-edit-rate-cover.spec.ts album-search.spec.ts wishlist.spec.ts \ + --project=chromium --reporter=json > /dev/null +bash ../fonoteka.go/scripts/dev-stack.sh e2e-verdict "$R" # must print e2e-verdict: passed +``` + +Item 11 passes only on a run with no skipped, unexpected or flaky test. Until then the plan stays open (D-11). + +## Manual session (Task 4, D-13) + +Pending: the developer's session against the Go stack. + +| # | Item | Result | Notes | +|---|------|--------|-------| +| 1 | Login lands outside /login | pending | | +| 2 | Collections: "Moja kolekcja" lists Kind of Blue, Blue Train, Mingus Ah Um with covers | pending | | +| 3 | Album detail page opens | pending | | +| 4 | Search "Mingus" finds the album; no `album search engine failed` in go.log | pending | | +| 5 | Edit name persists after reload | pending | | +| 6 | Rating persists after reload | pending | | +| 7 | Cover upload shows on the page | pending | | +| 8 | Wishlist add on /wishlist/new, then remove | pending | | +| 9 | Realtime: `collection:` subscribe without error; push frame after an edit in a second tab | pending | | +| 10 | No 5xx in go.log; no `X-Powered-By: PHP` through :3119 | pending | | +| 11 | PHP cross-check (deferred above) | pending | | diff --git a/.planning/phases/14.2-local-fonoteka-frontend-on-local-summercms-backend/deferred-items.md b/.planning/phases/14.2-local-fonoteka-frontend-on-local-summercms-backend/deferred-items.md index 42bc55f..eae1a27 100644 --- a/.planning/phases/14.2-local-fonoteka-frontend-on-local-summercms-backend/deferred-items.md +++ b/.planning/phases/14.2-local-fonoteka-frontend-on-local-summercms-backend/deferred-items.md @@ -4,3 +4,10 @@ - **File bucket fails across devices (affects Phase 20 cutover).** With the real `config/storage.yaml` (`file://./storage/app/uploads/public`), gocloud `fileblob` writes each upload to a temporary file in `os.TempDir()` and renames it into the bucket. When `/tmp` is a tmpfs (this machine) the rename fails with `invalid cross-device link`, so `fonoteka:dev-seed` (and any cover upload) fails. `dev-stack.sh` works around it by running the Go processes with `TMPDIR=tmp/dev-stack/go-tmp`. A deployment fix belongs to the framework or the app config (fileblob `no_tmp_dir` URL option, or a TMPDIR on the storage device) and should be decided before cutover. TestDevStackSmoke did not catch it because its bucket lives in the test's temp directory. - **GORM "record not found" log noise in `fonoteka:dev-seed`.** `classes/active_collection.go:243` logs the first, expected lookup miss through GORM's default logger in colour on stderr. Cosmetic; out of scope. + +## From plan 14.2-03 + +- **vue-fonoteka-app contract test fails on HEAD before this plan.** `tests/contracts/missing-catalog.test.mjs` ("Album DTO carries label, catalog_number and country without any") matches `\bany\b` against the Album type and trips on the comment "the cheapest current listing in any condition" added by vue-fonoteka-app `984031f` (feat(e5o)). `pnpm test:contracts`: 278 pass, 1 fail. It is an `app/` type comment, which this phase must not change (D-20). +- **lagoon.Validate treats a pointer to "" as a value.** `isEmptyValue` returns false for a non-nil `*string` holding "", so a `nullable|in:` model rule fails where Laravel skips every non-implicit rule for an empty string. fonoteka works around it in `albumRuleValues` (fonoteka.go `7675d64`). A framework fix (dereference pointers, or apply Laravel's empty-string skip) would cover other models; it changes `required` semantics for `*string` too, so it needs its own change. +- **`tmp/dev-stack/go.log` is appended across `up` runs.** A `grep -c 'status=5..'` over the whole file counts requests from earlier runs. The four 500s from before the empty-format fix were in it until the log was rotated before the Task 4 session. `up` could truncate or rotate the log. +- **Orphan artist rows in the Go dev database.** The specs delete the albums they create, but the artists created with them (`E2E Artist`) stay in `fonoteka_go_dev`. Whether PHP removes orphan artists on album delete was not checked.