docs(14.2-03): PHP cross-check and re-verification recorded in UAT

This commit is contained in:
2026-10-11 23:04:28 +02:00
parent b9de0610d7
commit a2d19360d2
2 changed files with 41 additions and 8 deletions

View File

@@ -1,7 +1,7 @@
---
phase: 14.2-local-fonoteka-frontend-on-local-summercms-backend
plan: 03
status: open-reverify-and-php
status: complete
---
# Phase 14.2 UAT: vue-fonoteka-app on the local Go backend
@@ -40,7 +40,7 @@ env -u CI -u E2E_BACKEND E2E_EMAIL='<php user>' E2E_PASSWORD='<password>' \
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).
Item 11 passes only on a run with no skipped, unexpected or flaky test. Until then the plan stays open (D-11). The run was done at Task 4; see below.
## Manual session (Task 4, D-13)
@@ -50,15 +50,15 @@ Session by the developer on 2026-10-11 (about 20:10 to 20:20 local time) against
|---|------|--------|-------|
| 1 | Login lands outside /login | pass | |
| 2 | Collections: "Moja kolekcja" lists Kind of Blue, Blue Train, Mingus Ah Um with covers | pass | |
| 3 | Album detail page opens | pass | |
| 3 | Album detail page opens | pass | After an artist change the detail page keeps the old `artist_display`. Same as PHP: `Album.php` (around line 397) fills `artist_display` only when it is empty. See finding E. |
| 4 | Search "Mingus" finds the album; no `album search engine failed` in go.log | pass | search_fail = 0 |
| 5 | Edit name persists after reload | pass | Session finding A (empty artist field) below; fixed. |
| 5 | Edit name persists after reload | pass | Finding A below (empty artist field): fixed in fonoteka.go `d31e00a`. The developer re-verified it: Blue Train shows John Coltrane. |
| 6 | Rating persists after reload | pass | |
| 7 | Cover upload shows on the page | fail, then analysed: matches PHP | See finding B. Re-verify. |
| 7 | Cover upload shows on the page | pass (re-verified) | Finding B: a new photo is appended and the first photo stays the main cover, as on PHP. The developer re-verified it. |
| 8 | Wishlist add on /wishlist/new, then remove | pass | Also marked an existing entry purchased. |
| 9 | Realtime: `collection:` subscribe without error; push frame after an edit in a second tab | push pass; UI refresh by frontend design | See finding C. The subscribe reply had no error and the push arrived. |
| 10 | No 5xx in go.log; no `X-Powered-By: PHP` through :3119 | fail, then fixed | See finding D. No PHP header; search_fail = 0. |
| 11 | PHP cross-check (deferred above) | pending | Not run yet. The plan stays open until it passes (D-11). |
| 9 | Realtime: `collection:` subscribe without error; push frame after an edit in a second tab | pass (matches PHP) | See finding C. The subscribe reply had no error and the push arrived. |
| 10 | No 5xx in go.log; no `X-Powered-By: PHP` through :3119 | pass after fix | The session failed it; see finding D. After the fix, go.log had 0 5xx lines. No PHP header; search_fail = 0. |
| 11 | PHP cross-check | pass (by classification) | PHP: `expected=4 unexpected=2 skipped=0 flaky=0`; Go: all passed on the same specs. Both PHP failures come from the environment or the test fixture, not from a contract difference. See "PHP cross-check (Task 4, item 11)" below. |
### Finding A: the artist field in the edit form was empty (fixed in Go)
@@ -105,3 +105,34 @@ Session by the developer on 2026-10-11 (about 20:10 to 20:20 local time) against
- **Item 7:** upload a photo to an album that has a cover. It appears in the photo strip right away, and the main cover stays the first photo. To make it the main cover, delete the old one.
- **Item 9 (optional):** an edit by another household member refreshes the open page.
- **Item 11:** the PHP run described in the deferred section.
### Finding E: `artist_display` stays the same after an artist change (same as PHP)
- **What happens:** changing an album's artists does not rewrite `artist_display`.
- **PHP:** the same. `Album.php` (around line 397) fills `artist_display` only when it is empty.
- **Go:** the same. `syncAlbumArtistsFromInput` keeps a non-empty `artist_display` that the request sends; the edit form sends it. It derives the value only when the request omits it or leaves it empty.
- No change; the item passes.
## PHP cross-check (Task 4, item 11)
The developer ran it on 2026-10-11, together with the coordinator.
- **Setup:**
- Go stack stopped during the run.
- PHP through `php artisan serve` on :8422; Nuxt on :3119 pointed at it.
- A throwaway PHP user `e2e-go-check@example.com`, created for the run and deleted afterwards (`deleted=1 remaining=0`).
- **Specs:** `auth.setup.ts`, `realtime.spec.ts`, `album-edit-rate-cover.spec.ts`, `album-search.spec.ts`, `wishlist.spec.ts`.
- **PHP result:** `expected=4 unexpected=2 skipped=0 flaky=0`.
- **Go result on the same specs:** all passed.
The two PHP failures:
1. **`album-edit-rate-cover`: a fixture artefact on PHP.**
- PHP answered `POST /albums/{id}/photos` with a 500. `system.log` shows `TypeError: imagealphablending(): Argument #1 must be of type GdImage, false given` at winter/storm `Database/Attach/Resizer.php:139`.
- GD cannot decode the spec's hand-built 1x1 PNG fixture (`PNG_1PX`). GD itself supports PNG, JPEG, WebP and AVIF, and a real photo uploaded through PHP works (manual item 7).
- Go accepts the fixture. This is not a Go divergence.
2. **`realtime` live: an environment gap on PHP.**
- No Centrifugo socket opened within 15 s. The PHP log says `Centrifugo: Skipping publish (not configured)`: the local PHP env has no Centrifugo config.
- The realtime baseline test passed on PHP. This is not a Go divergence.
**Verdict:** item 11 passes. No contract difference between PHP and Go was found. The strict D-11 bar (a clean PHP run) was not met, because the two failures above come from the fixture and from the PHP environment. The developer accepted the classification, and both issues are in `deferred-items.md`.

View File

@@ -12,3 +12,5 @@
- **`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; the session log is kept as `go.log.uat-session-20261011`. `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.
- **Realtime self-echo guard hides same-user cross-tab edits.** `useRealtimeSync.ts` skips the refresh when `payload.actor.user_id` is the session user, so an edit in a second tab of the same user never refreshes the first tab (PHP and Go alike, UAT finding C). This is frontend design (`app/`, out of scope for D-20); worth a product decision if same-user multi-tab sync is wanted.
- **`PNG_1PX` fixture is not decodable by PHP GD.** `album-edit-rate-cover.spec.ts` uploads a hand-built 1x1 PNG. PHP's Winter resizer fails on it (`imagealphablending(): Argument #1 must be of type GdImage, false given`, `Resizer.php:139`) and answers 500, while Go accepts it. Real photos work on PHP. Follow-up: use a GD-decodable fixture (for example an 8x8 PNG encoded with a standard encoder) so the spec passes on both backends.
- **Local PHP env has no Centrifugo config.** On PHP, the live `realtime.spec.ts` test opens no socket (`Centrifugo: Skipping publish (not configured)`). The PHP side of that test needs the Centrifugo settings in the PHP app's local env.