PR #7335 — the profile-photo round trip

Upload → card + rail → another page → popover → Remove, driven through the real file input against the branch's own dev server, with the DOM checks each capture had to pass. Companion to pr-7335-account-settings-photo. PR: PropFlow-Technologies/propflowai#7335.

Served URL under test: /api/users/5330114e-38f4-4fd4-9a23-41b1546d7d60/avatar?v=av_c3de3b5c-be7e-43e0-a9b6-df21be2aedbc · 5 steps · 18 checks · 0 failures

Before the upload

The smoke account has no photo: the Profile card and the rail both draw initials, the Photo row offers Upload photo only. This is also exactly what every existing account sees the day this ships — nothing changes until someone chooses a picture.

Before the upload
1-before-initials.png — branch dev server, 1600×1000
DOM checks this capture had to pass (4/4)
  • title is Account Settings
  • Photo row present
  • no Remove before an upload
  • rail shows initials

Upload — the card and the rail change together, no reload

A 900×600 two-tone PNG went through the real <input type=file>. The route normalised it to a 256×256 WebP (checked by fetching the served URL and reading its metadata), pointed the User row at it, and answered with the per-upload URL. The card re-rendered from that answer; the rail re-read /api/auth/me on the propflow:me-updated event and drew the same URL. Change photo and Remove replace Upload photo.

Upload — the card and the rail change together, no reload
2-after-upload.png — branch dev server, 1600×1000
DOM checks this capture had to pass (6/6)
  • toast says Photo updated
  • card draws an image from /api/users/…/avatar?v=
  • rail draws the SAME image without a reload
  • Change photo + Remove now offered
  • served object is a 256×256 WebP
  • served with a day of private caching

Another page — the photo is on the row, not in page state

Navigating to Admin Settings, the rail's first read of /api/auth/me already carries the photo: it persisted on User.avatarKey, not in the account page's memory.

Another page — the photo is on the row, not in page state
3-rail-on-admin-settings.png — branch dev server, 1600×1000
DOM checks this capture had to pass (2/2)
  • Admin Settings page
  • rail shows the photo here too

The ⋯ popover trigger is the same component

Open, the popover shows the account row (the way to Account Settings since #7324); the trigger behind it keeps drawing the photo — the rail's two tiers and the account page share one UserAvatar.

The ⋯ popover trigger is the same component
4-popover-open.png — branch dev server, 1600×1000
DOM checks this capture had to pass (2/2)
  • popover open with the account row
  • trigger still draws the photo

Remove — back to initials, and the old URL is gone

The pointer is cleared, the object deleted; the rail falls back in the same tab and the previous photo URL now answers 404 (briefly cached, so a thread with many of this person's messages costs one request). The smoke account is left exactly as it was found.

Remove — back to initials, and the old URL is gone
5-after-remove.png — branch dev server, 1600×1000
DOM checks this capture had to pass (4/4)
  • toast says Photo removed
  • card back to Upload photo, no Remove
  • rail back to initials without a reload
  • old photo URL is gone (404)
PropFlow Docs